PDA

View Full Version : [SOLVED]Can't create a 3.X or higher context



Wilds
09-26-2011, 05:29 AM
Hello openGL users!
I have been trying for a week now to create a good working Win32 OpenGL 3.3 context.

I have tried to it the same way as in the following tutorial
http://www.swiftless.com/tutorials/opengl4/1-opengl-window.html

it works but it does not use the wglChoosePixelFormatArb(); so you cant use MSAA and newer stuff.

I have the newest OpenGL superbible 5 book and Beginning OpenGL Game Programming, Second Edition.

System:
I5 2500k CPU
2x 560 GTX TI SC
OpenGL 4.1 compatible
newest drivers

The problems I am having are:
1. when sizing the window it show the windows DC background color around the openGL viewport.
2. the window does not resize the way I want the mouse keeps sticking to the border.

http://imageshack.us/photo/my-images/695/renderingerror00.jpg/
http://imageshack.us/photo/my-images/90/renderingerror01.jpg/

Libraries used:
GLEW 1.7.0
Win32

Source:
program.cpp

/*
* Author: Mark van der Wal
* Date: 28-08-2011
* Descr: starting point of the application
*/

// libraries
#include "CGameForm.h"
#include <string>

// global definitions
const std::string gAppName = "OpenGLWin32Framework v0.1";
const unsigned int gWindowWidth = 1024;
const unsigned int gWindowHeight = 768;

// @STARTING_POINT
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd)
{
// create instance of a window
CGameForm game(hInstance, gWindowWidth, gWindowHeight, gAppName.c_str());

// try to create the main window
if( !game.CreateForm())
{
MessageBox(0, "Could not create Window!", "Error", MB_OK);
return 0;
}

// run the application
return game.RunApplication();
}

CGameForm.h

/*
* Author: Mark van der Wal
* Date: 28-08-2011
* Descr: Class for handling win 32 system operations and initializing OpenGL rendering context
*/
#ifndef _CGAMEFORM_H_
#define _CGAMEFORM_H_

#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN

#include <GL/glew.h>
#include <GL/wglew.h>

#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "opengl32.lib")

// Abstract base Window class
class CGameForm
{
public: // methods
// default constructor
inline CGameForm(const HINSTANCE&amp; instance, USHORT width, USHORT height, LPCSTR caption)
: mHInstance(instance), mWindowName(caption)
{
memset(&amp;mWindowDim, 0, sizeof(RECT));
mWindowDim.bottom = height;
mWindowDim.left = width;
mWindowDim.right = 0;
mWindowDim.top = 0;
}

// create the main app window
bool CreateForm();

// handle the events
int RunApplication();

private: // methods
// Message handlers
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT ProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

// tries to create the OpenGL rendering context
bool CreateRenderingContext(HWND hwnd);

private: // data members
HINSTANCE mHInstance; // handle to the instance the window belongs to
HWND mForm; // handle to the created window
HDC mFormDC; // device context
HGLRC mGLRC; // rendering context

// window data
LPCSTR mWindowName; // name of the window
RECT mWindowDim;
};

#endif // _CGameForm_H_

CGameForm.cpp

/*
* Author: Mark van der Wal
* Date: 28-08-2011
* Descr: Win32 abstract class, handles initializing a window on windows
*/
#include "CGameForm.h"
#include <string>

bool CGameForm::CreateForm()
{
// create the win32 class
// if we fail to create the Win32 class we return false
WNDCLASS pClass;
memset(&amp;pClass, 0, sizeof(WNDCLASS));

// fill in the Win32 class structure
pClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
pClass.lpfnWndProc = CGameForm::WndProc;
pClass.cbClsExtra = NULL;
pClass.cbWndExtra = NULL;
pClass.hInstance = mHInstance;
pClass.hIcon = ::LoadIcon(mHInstance, IDI_APPLICATION);
pClass.hCursor = ::LoadCursor(0, IDC_ARROW);
pClass.hbrBackground = NULL;
pClass.lpszMenuName = NULL;
pClass.lpszClassName = mWindowName;

// try to register
if( ::RegisterClass( &amp;pClass ) == 0 )
return false;

// create DUMMY window
HWND mFormTemp = ::CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
mWindowName, // class name
mWindowName, // window name
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
mWindowDim.right, mWindowDim.top,
mWindowDim.left, mWindowDim.bottom,
NULL,
NULL,
mHInstance,
NULL);

// create the rendering context
if( !CreateRenderingContext(mFormTemp) )
return false;

// set OpenGL state
glClearColor(0.2f, 0.7f, 1.0f, 1.0f);

// show & update the window
ShowWindow(mForm, SW_SHOW);
UpdateWindow(mForm);

return true;
}

// tries to create the OpenGL rendering context
bool CGameForm::CreateRenderingContext(HWND hwnd)
{
// for the 2.1 rendering context
PIXELFORMATDESCRIPTOR pfd;
memset(&amp;pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;

// get the device context for the 2.1 rendering context
HDC mFormDCTemp = GetDC(hwnd);

// choose most appropiate pixelformat for 2.1 rendering context
int pxFormat = ChoosePixelFormat(mFormDCTemp, &amp;pfd);
if(pxFormat == 0)
return false;

// set the pixelformat to our window for 2.1 rendering context
bool result = SetPixelFormat(mFormDCTemp, pxFormat, &amp;pfd);
if(!result)
return false;

// Create 2.1 rendering context and make it current
HGLRC tempGLRC = wglCreateContext(mFormDCTemp);

// error check
if( tempGLRC == 0)
return false;

// make the 2.1 Rendering context current
wglMakeCurrent(mFormDCTemp, tempGLRC);

// init GLEW
GLenum err = glewInit();
if(err != GLEW_OK)
return false;

// If the OpenGL 3.x context creation extension is available
if (wglewIsSupported("WGL_ARB_pixel_format") == 1)
{
// specify the attributes for a 3.x+ rendering context
unsigned int nPixCount = 0;
int pixelFormats = 0; // nr of pixel formats

const int pixAttribs[] = {
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
0};

mForm = ::CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
mWindowName, // class name
mWindowName, // window name
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
mWindowDim.right, mWindowDim.top,
mWindowDim.left, mWindowDim.bottom,
NULL,
NULL,
mHInstance,
this);

// get the new 3.X window DC
mFormDC = GetDC(mForm);

// get a pixelformat for our 3.X or higher rendering context
wglChoosePixelFormatARB(mFormDC, &amp;pixAttribs[0], NULL, 1, &amp;pixelFormats, &amp;nPixCount);

// check if we could load a valid pixelformat
if(pixelFormats != -1)
{
// set the pixel format for our 3.X or higher context
SetPixelFormat(mFormDC, pixelFormats, &amp;pfd);

// attribute list for the renderin context
int attribs33[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};

// create the openGL rendering context
// check if it succeeded
if (wglewIsSupported("WGL_ARB_create_context") == 1) // If the OpenGL 3.x context creation extension is available
{
mGLRC = wglCreateContextAttribsARB(mFormDC, NULL, attribs33); // Create and OpenGL 3.x context based on the given attributes

// release all and start over for real context
wglMakeCurrent(NULL, NULL); //remove the 2.1 rendering context from being active
wglDeleteContext(tempGLRC); // Delete the temporary OpenGL 2.1 context
ReleaseDC(hwnd, mFormDCTemp);
DestroyWindow(hwnd);

// Make our OpenGL 3.x context current
wglMakeCurrent(mFormDC, mGLRC);
}
}
else
return false;
}
else
return false;

return true;
}

// the finite loop for everything handled in real time
int CGameForm::RunApplication()
{
// we only use this structure in here
MSG mMsg;

// zero out the message structure
ZeroMemory(&amp;mMsg, sizeof(MSG));

// if the message recieved is not WM_QUIT we do stuff
while(mMsg.message != WM_QUIT)
{
// if there is a message in the queue handle it and remove it from the queue
if(PeekMessage(&amp;mMsg, 0, 0, 0, PM_REMOVE))
{
// get it over to the message handler of this window
TranslateMessage(&amp;mMsg);
DispatchMessage(&amp;mMsg);
}

// clear the window with the current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

SwapBuffers(mFormDC);
}

// return the return code if the message handler terminates
return (int)mMsg.wParam;
}

// the static windproc callback function
LRESULT CALLBACK CGameForm::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// set the this pointer of the calling class in the user defined space
if( msg == WM_CREATE)
SetWindowLong(hwnd, GWL_USERDATA, (LONG)((CREATESTRUCT FAR*)lParam)->lpCreateParams);

// get the instance of this class
CGameForm* destination = (CGameForm*)GetWindowLong(hwnd, GWL_USERDATA);

// if it is not null we pass in the message to the local message handler
if(destination)
destination->ProcHandler(hwnd, msg, wParam, lParam);

// if non of the above is handled we let windows handle the message
return DefWindowProc(hwnd, msg, wParam, lParam);
}

// the message handler
LRESULT CGameForm::ProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
mWindowDim.right = LOWORD(lParam);
mWindowDim.bottom = HIWORD(lParam);

// change the openGL viewport dimensions
glViewport(0, 0, mWindowDim.right, mWindowDim.bottom);
break;
case WM_DESTROY:
// check if we can delete the RC
if(mGLRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(mGLRC);
mGLRC = NULL;
}

if(mForm != NULL)
{
// check if we can delete the DC
if(mFormDC)
{
// release the DC
ReleaseDC(mForm, mFormDC);
}

// destroy the window
DestroyWindow(mForm);
}

// terminate the application
PostQuitMessage(0);
break;
}

return DefWindowProc(hwnd, msg, wParam, lParam);
}

Wilds
09-26-2011, 06:46 AM
I seemed to have found the problem!
My problem is that Used a class to handle Win32 window creation, in my static prochandler I manage to call the DefWindowProc() twice