What is the best way to set up a window in win32 that has OpenGl(and glsl if the needs extra code to work) integrated into it?
I have done some research and found numerous ways of accomplishing this task i was wondering what the best way is or what way you like the most if the best way doesn't have an answer.
I have looked at nehe`s design and also the one supplied by the OpenGl super bible which both have completely different ways of accomplishing it (also the super bibles one gives me errors :().
any help would be appreciated including tutorials etc.
thanks
All your "different ways" aren't so different. You have to:
RegisterClass(Ex)
and CreateWindow(Ex)
)GetDC
)DescribePixelFormat
, then ChoosePixelFormat
)wglCreateContext
)glGetString(GL_EXTENSIONS)
then wglGetProcAddress
)wglCreateContextAttribs
)wglMakeCurrent
)An excerpt of code showing these steps in action (not suitable for copy+paste, a bunch of RAII wrappers are used):
bool Context::attach( HWND hwnd )
{
PIXELFORMATDESCRIPTOR pfd = { sizeof(pfd), 1 };
if (!m_dc) {
scoped_window_hdc(hwnd).swap(m_dc);
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cAlphaBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
auto format_index = ::ChoosePixelFormat(m_dc.get(), &pfd);
if (!format_index)
return false;
if (!::SetPixelFormat(m_dc.get(), format_index, &pfd))
return false;
}
auto active_format_index = ::GetPixelFormat(m_dc.get());
if (!active_format_index)
return false;
if (!::DescribePixelFormat(m_dc.get(), active_format_index, sizeof pfd, &pfd))
return false;
if ((pfd.dwFlags & PFD_SUPPORT_OPENGL) != PFD_SUPPORT_OPENGL)
return false;
m_render_thread = ::CreateThread(NULL, 0, &RenderThreadProc, this, 0, NULL);
return m_render_thread != NULL;
}
DWORD WINAPI Context::RenderThreadProc( LPVOID param )
{
Context* const ctx = static_cast<Context*>(param);
HDC dc = ctx->m_dc.get();
SIZE canvas_size;
ctx->m_dc.check_resize(&canvas_size);
scoped_hglrc glrc(wglCreateContext(dc));
if (!glrc)
return EXIT_FAILURE;
if (!glrc.make_current(dc))
return EXIT_FAILURE;
if (ctx->m_major_version > 2 && GLEE_WGL_ARB_create_context) {
int const create_attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, ctx->m_major_version,
WGL_CONTEXT_MINOR_VERSION_ARB, ctx->m_minor_version,
0
};
scoped_hglrc advrc(wglCreateContextAttribsARB(dc, 0, create_attribs));
if (advrc) {
if (!advrc.make_current(dc))
return EXIT_FAILURE;
advrc.swap(glrc);
}
}
{
const char* ver = reinterpret_cast<const char*>(glGetString(GL_VERSION));
if (ver) {
OutputDebugStringA("GL_VERSION = \"");
OutputDebugStringA(ver);
OutputDebugStringA("\"\n");
}
}
glDisable(GL_DITHER);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.f, 0.f, 0.f, 1.f);
if (GLEE_WGL_EXT_swap_control)
wglSwapIntervalEXT(1);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
while (!::InterlockedExchange(&ctx->m_stop_render, 0)) {
ctx->process_queued_tasks();
if (ctx->m_dc.check_resize(&canvas_size)) {
glViewport(0, 0, canvas_size.cx, canvas_size.cy);
ctx->process_on_resize();
}
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
ctx->process_on_render();
BOOL swapped = ::SwapBuffers(dc);
if (!swapped)
std::cout << "::SwapBuffers failure, GetLastError() returns " << std::hex << ::GetLastError() << std::endl;
}
ctx->m_program_db.clear();
return EXIT_SUCCESS;
}
It also doesn't cover window creation, it enables OpenGL on an existing window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With