Hi,
I was wondering if anyone could answer a few questions I have about properly setting up an OpenGL 4.1 context on Windows. I scrapped together two quick code samples on my computer one using GLFW/GLEW and another creating my own window and using GLEW.
I ran both code samples through gDEBugger and I'm a little confused by the results. Based on the way I set up my window in both of the samples below I expected to only see a "Front Buffer" and "Back Buffer" when I viewed the context in gDEBugger. Instead I am seeing a depth, back, front, and four auxiliary buffers. Do I have any control over the creation of those buffers?
The other question I have is if I'm properly setting up my OpenGL context for Windows. The one issue I seem to be having is that if I specify WGL_CONTEXT_DEBUG_BIT_ARB in the sample where I create my own window it doesn't properly create a context.
Posted this over at the OpenGL forums as well.
Thanks for any help.
GLFW/GLEW:
#define GLEW_STATIC
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GLM/glm.hpp>
#include "Debugging/glDebugging.h"
int main( int argc, char* argv[] )
{
if( !glfwInit() )
return EXIT_FAILURE;
// define glfw window hints
#if defined( _DEBUG )
glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE );
#endif
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );
glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, 1 );
glfwWindowHint( GLFW_DEPTH_BITS, 0 );
glfwWindowHint( GLFW_STENCIL_BITS, 0 );
glfwWindowHint( GLFW_ACCUM_RED_BITS, 0 );
glfwWindowHint( GLFW_ACCUM_GREEN_BITS, 0 );
glfwWindowHint( GLFW_ACCUM_BLUE_BITS, 0 );
glfwWindowHint( GLFW_ACCUM_ALPHA_BITS, 0 );
glfwWindowHint( GLFW_AUX_BUFFERS, 0 );
// open a window with GLFW
GLFWwindow* pWindow = glfwCreateWindow( 640, 360, "LearnGL", nullptr, nullptr );
if( pWindow == nullptr )
{
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent( pWindow );
// initialize GLEW
glewExperimental = GL_TRUE;
if( glewInit() != GLEW_OK )
{
glfwTerminate();
return EXIT_FAILURE;
}
if( !GLEW_VERSION_4_1 )
{
glfwTerminate();
return EXIT_FAILURE;
}
#if defined( _DEBUG )
GL::InitializeDebugging();
#endif
GLuint frameBuffer;
GLuint colorBufferTexture;
glGenTextures( 1, &colorBufferTexture );
// Set up texture
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, colorBufferTexture );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 );
glTexImage2D( GL_TEXTURE_2D, GLint( 0 ), GL_RGBA8, GLsizei( 640 ), GLsizei( 360 ), 0,
GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
glBindTexture( GL_TEXTURE_2D, 0 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
// Set up frame buffer
glGenFramebuffers( 1, &frameBuffer );
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
glFramebufferTexture( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorBufferTexture, 0 );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
while( !glfwWindowShouldClose( pWindow ) )
{
// Viewport setup
int width = 0;
int height = 0;
glfwGetWindowSize( pWindow, &width, &height );
glViewport( 0, 0, width, height );
// Clear render targets
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer );
glClearBufferfv( GL_COLOR, 0, &glm::vec4( 1.0f, 0.0f, 5.0f, 1.0f )[0] );
glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glClearBufferfv( GL_COLOR, 0, &glm::vec4( 0.1f, 0.1f, 0.1f, 1.0f )[0] );
glClearBufferfi( GL_DEPTH_STENCIL, 0, 1.0f, 0 );
glfwSwapBuffers( pWindow );
glfwPollEvents();
}
return EXIT_SUCCESS;
}
Win32/GLEW
[font='Helvetica Neue', Arial, Verdana, sans-serif]#define GLEW_STATIC[/font]
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <GL/glew.h>
#include <GL/wglew.h>
#include <GLM/glm.hpp>
#include "Debugging/glDebugging.h"
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
struct RunInfo
{
bool bRunning;
};
int main( int argc, char* argv[] )
{
STARTUPINFO startInfo;
HINSTANCE hInstance = ( HINSTANCE )GetModuleHandle( NULL );
GetStartupInfo( &startInfo );
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_APPLICATION ) );
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"NoGLFW";
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_APPLICATION ) );
if( !RegisterClassEx( &wcex ) )
return -1;
RECT rc = { 0, 0, 640, 360 };
AdjustWindowRectEx( &rc, WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE );
HWND hWnd = CreateWindowEx(
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
L"NoGLFW",
L"NoGLFW",
WS_OVERLAPPEDWINDOW,
0,
0,
rc.right - rc.left,
rc.bottom - rc.top,
NULL,
NULL,
hInstance,
NULL );
if( !hWnd )
return -1;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof( PIXELFORMATDESCRIPTOR ), // Struct size
1, // Version
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Support OpenGL/Double Buffering
PFD_TYPE_RGBA, // Request RGBA format
32, // Output color depth
0, 0, 0, 0, 0, 0, // Color bits, ignored
0, // No alpha buffer
0, // Shift bit, ignored
0, // No accumulation buffer
0, 0, 0, 0, // Accumulation bits, ignored
0, // No z-buffer
0, // No stencil buffer
0, // No auxillary buffer
PFD_MAIN_PLANE, // Main drawing layer
0, // Reserved
0, 0, 0 // Layer masks, ignored
};
HDC hDc = GetDC( hWnd );
if( !hDc )
return -1;
unsigned int pixelFormat = ChoosePixelFormat( hDc, &pfd );
if( !pixelFormat )
return -1;
if( !SetPixelFormat( hDc, pixelFormat, &pfd ) )
return -1;
HGLRC tempContext = wglCreateContext( hDc );
wglMakeCurrent( hDc, tempContext );
glewExperimental = GL_TRUE;
GLenum err = glewInit();
int attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB, 0,
0
};
HGLRC hRc = tempContext;
if( wglewIsSupported( "WGL_ARB_create_context" ) == 1 )
{
hRc = wglCreateContextAttribsARB( hDc, 0, attribs );
wglMakeCurrent( NULL, NULL );
wglDeleteContext( tempContext );
wglMakeCurrent( hDc, hRc );
}
//Checking GL version
const GLubyte* GLVersionString = glGetString( GL_VERSION );
//Or better yet, use the GL3 way to get the version number
int OpenGLVersion[2];
glGetIntegerv( GL_MAJOR_VERSION, &OpenGLVersion[0] );
glGetIntegerv( GL_MINOR_VERSION, &OpenGLVersion[1] );
RunInfo runInfo;
runInfo.bRunning = true;
SetWindowLongPtr( hWnd, GWLP_USERDATA, ( LONG_PTR )&runInfo );
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
MSG msg = { 0 };
while( runInfo.bRunning )
{
if( PeekMessage( &msg, hWnd, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
glViewport( 0, 0, 640, 360 );
glClearBufferfv( GL_COLOR, 0, &glm::vec4( 0.1f, 0.1f, 0.1f, 1.0f )[0] );
SwapBuffers( hDc );
}
return 0;
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
RunInfo* pRunInfo = ( RunInfo* )GetWindowLongPtr( hWnd, GWLP_USERDATA );
switch( message )
{
case WM_DESTROY:
{
pRunInfo->bRunning = false;
PostQuitMessage( 0 );
}
break;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}