我正在尝试启动一个将在Windows 10和我们的OpenGL上运行的应用程序。我能够在屏幕上显示一个窗口,但在初始化OpenGL后,我无法在窗口中显示颜色。我试图不使用像GLFW这样的第三方库。
我目前的代码如下:
#include <Windows.h>
#include <gl/gl.h>
#include <cassert>
#define local_persist static
#define local_func static
#define global_variable static
namespace Win64
{
local_func void
ProcessPendingMessages()
{
MSG Message;
while(GetMessageA(&Message, 0, 0, 0))
{
switch(Message.message)
{
case WM_QUIT:
{
} break;
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
{
uint32 VKCode = (uint32)Message.wParam;
if(VKCode == 'W')
{
}
else if(VKCode == 'A')
{
}
else if(VKCode == 'S')
{
}
else if(VKCode == 'D')
{
}
else if(VKCode == 'Q')
{
}
else if(VKCode == 'E')
{
}
else if(VKCode == VK_UP)
{
}
else if(VKCode == VK_LEFT)
{
}
else if(VKCode == VK_DOWN)
{
}
else if(VKCode == VK_RIGHT)
{
}
else if(VKCode == VK_ESCAPE)
{
}
else if(VKCode == VK_SPACE)
{
}
}
default:
{
TranslateMessage(&Message);
DispatchMessageA(&Message);
} break;
}
}
};
LRESULT CALLBACK
ProgramWindowCallback(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
LRESULT Result{0};
switch(Message)
{
case WM_SIZE:
{
OutputDebugStringA("WM_SIZE\n");
}break;
case WM_DESTROY:
{
OutputDebugStringA("WM_DESTROY\n");
}break;
case WM_CLOSE:
{
OutputDebugStringA("WM_CLOSE\n");
}break;
case WM_ACTIVATEAPP:
{
OutputDebugStringA("WM_ACTIVATEAPP\n");
}break;
case WM_PAINT:
{
PAINTSTRUCT Paint;
RECT ClientRect;
GetClientRect(WindowHandle, &ClientRect);
HDC DeviceContext = BeginPaint(WindowHandle, &Paint);
LONG Width = ClientRect.right - ClientRect.left;
LONG Height = ClientRect.bottom - ClientRect.top;
glViewport(0, 0, Width, Height);
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
SwapBuffers(DeviceContext);
EndPaint(WindowHandle, &Paint);
}break;
default:
{
Result = DefWindowProc(WindowHandle, Message, wParam, lParam);
}break;
}
return Result;
};
}
int CALLBACK WinMain(HINSTANCE CurrentProgramInstance, HINSTANCE PrevInstance, LPSTR CommandLine, int ShowCode)
{
WNDCLASS WindowProperties{};
//TODO: Check if OWNDC/HREDRAW/VEDRAW matter
WindowProperties.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
WindowProperties.lpfnWndProc = Win64::ProgramWindowCallback;
WindowProperties.hInstance = CurrentProgramInstance;
WindowProperties.lpszClassName = "MemoWindowClass";
if(RegisterClass(&WindowProperties))
{
HWND Window = CreateWindowEx(0, WindowProperties.lpszClassName, "Memo", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, CurrentProgramInstance, 0);
if(Window)
{
HDC WindowDeviceContext = GetDC(Window);
{ //Init OpenGL
HGLRC OpenGLRenderingContext = wglCreateContext(WindowDeviceContext);
PIXELFORMATDESCRIPTOR DesiredPixelFormat{};
DesiredPixelFormat.nSize = sizeof(DesiredPixelFormat);
DesiredPixelFormat.nVersion = 1;
DesiredPixelFormat.iPixelType = PFD_TYPE_RGBA;
DesiredPixelFormat.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
DesiredPixelFormat.cColorBits = 32;
DesiredPixelFormat.cAlphaBits = 8;
DesiredPixelFormat.iLayerType = PFD_MAIN_PLANE;
int SuggestedPixelFormatIndex = ChoosePixelFormat(WindowDeviceContext, &DesiredPixelFormat);
PIXELFORMATDESCRIPTOR SuggestedPixelFormat{};
DescribePixelFormat(WindowDeviceContext, SuggestedPixelFormatIndex, sizeof(SuggestedPixelFormat), &SuggestedPixelFormat);
if (SetPixelFormat(WindowDeviceContext, SuggestedPixelFormatIndex, &SuggestedPixelFormat))
{
if (wglMakeCurrent(WindowDeviceContext, OpenGLRenderingContext))
{
//Success!
}
else
{
//Log error
assert(1 == 0);
}
}
else
{
//Log error
assert(1 == 0);
}
}
Win64::ProcessPendingMessages();
}
}
return 0;
}
我期待glClear()清除我在glClearColor()中设置的颜色。然而,这并没有发生。我做错了什么?
答案 0 :(得分:1)
在wglCreateContext()
之前移动调用wglMakeCurrent
的行,并在设置像素格式(SetPixelFormat()
调用)之后移动。
if (SetPixelFormat(WindowDeviceContext, SuggestedPixelFormatIndex, &SuggestedPixelFormat))
{
HGLRC OpenGLRenderingContext = wglCreateContext(WindowDeviceContext);
if (wglMakeCurrent(WindowDeviceContext, OpenGLRenderingContext))
//...
答案 1 :(得分:0)
我不知道这是不是问题,但是在许多OpenGL样本中有一个可怕的反模式,它使用CS_OWNDC创建一个窗口类,然后假设在程序启动时调用wglMakeCurrent一次是安全的,并且再也不会
从窗口类中省略CS_OWNDC样式是远远的,更安全,只需使用wglMakeCurrent将所有入口点包装到OpenGl调用中进行设置和清理。
模式是,你想用OpenGL做一些事情,所以你适当地调用GetDC / BeginPaint得到一个窗口DC,然后你调用wglMakeCurrent传递dc和gl rc句柄,做你的OpenGL调用,然后就在你之前调用ReleaseDC / EndPaint,再次调用wglMakeCurrent传递NULL,NULL。
遵循这个基本建议,您可以在一个线程上安全地创建多个open gl窗口实例,并且您不必担心某些第三方代码可能会创建并临时创建其自己的GL上下文。