OpenGL啥都不显示?
Posted
技术标签:
【中文标题】OpenGL啥都不显示?【英文标题】:OpenGL not displaying anything?OpenGL什么都不显示? 【发布时间】:2012-04-21 04:40:16 【问题描述】:我的问题是我的程序没有在屏幕上显示任何内容。
这是“main.cpp”代码:
#include "paStdAfx.h"
#include "OpenGL.h"
HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hwnd = NULL;
HINSTANCE hInstance = GetModuleHandle(NULL);
const wchar_t* szClassName = _T("*project name :3*");
static std::wstring Titles[] =
_T("*project name :3* - 100% free!"),
_T("*project name :3* - 100% OpenGL!"),
_T("*project name :3* - Not cross platform!"),
_T("*project name :3* - Rawr"),
_T("*project name :3* - Entirely C++!"),
_T("*project name :3* - Woo, /r/gamedev!"),
_T("*project name :3* - Platypi, platypi everywhere."),
_T("*project name :3* - Nom nom nom"),
_T("*project name :3* - Thanks, StackExchange!"),
_T("*project name :3* - DRM Free!"),
_T("*project name :3* - <3"),
_T("*project name :3* - Minecraft is also fun!")
;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CreateOpenGLWindow(const wchar_t*, int, int, int);
OpenGL ogl;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
srand(time(NULL));
const std::wstring wtt = Titles[rand() % 11];
const wchar_t* WindowTitle = wtt.c_str();
BOOL done = FALSE;
MSG msg;
if(!CreateOpenGLWindow(WindowTitle, 800, 600, 32)) MessageBox(NULL, _T("Could not create window :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE);
while(!done)
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
if(msg.message == WM_QUIT)
done = TRUE;
else
TranslateMessage(&msg);
DispatchMessage(&msg);
else
ogl.RenderGLScene();
SwapBuffers(hDC);
ogl.KillOpenGL(hwnd, hDC, hRC);
return 0;
BOOL CreateOpenGLWindow(const wchar_t* title, int width, int height, int bits)
WNDCLASSEX wcx = 0;
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = CS_OWNDC;
wcx.lpfnWndProc = WndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = 0;
wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PROGRAMICON));
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wcx.lpszClassName = szClassName;
wcx.lpszMenuName = NULL;
wcx.hIconSm = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_PROGRAMICON), IMAGE_ICON, 16, 16, 0);
if(!RegisterClassEx(&wcx)) MessageBox(NULL, _T("Failed to register window!"), _T("Error! :("), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE);
if(!(hwnd = CreateWindowEx(dwExStyle, szClassName, title, dwStyle, 200, 69, width, height, NULL, NULL, hInstance, NULL))) MessageBox(NULL, _T("Failed to create the window!"), _T("Error! :("), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE);
ogl.CreateOpenGLContext(hwnd, &hDC, &hRC);
ogl.PrepareOpenGLScene();
ogl.ResizeGLScene(width, height);
ShowWindow(hwnd, SW_SHOW);
SetForegroundWindow(hwnd);
SetFocus(hwnd);
return TRUE;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch(msg)
case WM_CREATE:
ogl.ProgramIcon(hwnd);
break;
case WM_KEYDOWN:
switch(wParam)
case VK_ESCAPE:
PostQuitMessage(0);
break;
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
return 0;
return DefWindowProc(hwnd, msg, wParam, lParam);
这是“OpenGL.cpp”代码:
#include "paStdAfx.h"
#include "OpenGL.h"
GLvoid OpenGL::CreateOpenGLContext(HWND hwnd, HDC* hDC, HGLRC* hRC)
PIXELFORMATDESCRIPTOR pfd;
HGLRC tempContext;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
*hDC = GetDC(hwnd);
int PixelFormat = ChoosePixelFormat(*hDC, &pfd);
if(PixelFormat == 0) MessageBox(NULL, _T("Could not choose pixel format :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(EXIT_FAILURE);
if(!SetPixelFormat(*hDC, PixelFormat, &pfd)) MessageBox(NULL, _T("Could not set pixel format :("), _T("Error!"), MB_OK | MB_ICONERROR); exit(3);
tempContext = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, tempContext);
GLenum err = glewInit();
if(GLEW_OK != err) MessageBox(NULL, _T("Failed to initialize GLEW! :("), _T("Warning!"), MB_OK | MB_ICONINFORMATION);
int attribs[] =
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_FLAGS_ARB,
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
0
;
if(!glewIsSupported("GL_VERSION_3_1")) MessageBox(NULL, _T("OpenGL 3.1 not supported :("), _T("Warning!"), MB_OK | MB_ICONERROR);
if(wglewIsSupported("WGL_ARB_create_context") == 1)
*hRC = wglCreateContextAttribsARB(*hDC, 0, attribs);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
wglMakeCurrent(*hDC, *hRC);
else *hRC = tempContext;
const char* GLVersionString = (char*) glGetString(GL_VERSION);
int OpenGLVersion[2];
glGetIntegerv(GL_MAJOR_VERSION, &OpenGLVersion[0]);
glGetIntegerv(GL_MINOR_VERSION, &OpenGLVersion[1]);
GLvoid OpenGL::PrepareOpenGLScene(GLvoid)
glClearColor(0.0f, 0.6f, 1.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
GLvoid OpenGL::RenderGLScene(GLvoid)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
/* Begin OpenGL Rendering */
/* End OpenGL Rendering */
GLvoid OpenGL::ResizeGLScene(int w, int h)
float ratio = 1.0 * w / h;
if(h == 0)
h = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, ratio, 0.1f, 1000.0f);
glViewport(0, 0, w, h);
GLvoid OpenGL::ProgramIcon(HWND hwnd)
HICON hIcon, hIconSm;
hIcon = (HICON) LoadImage(NULL, _T("data/icon.ico"), IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
if(hIcon)
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
else
MessageBox(NULL, _T("Could not load the big icon! :("), _T("Error!"), MB_OK | MB_ICONERROR);
//---------------------------------------------------------------------------------------------//
hIconSm = (HICON) LoadImage(NULL, _T("data/icon.ico"), IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
if(hIconSm)
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
else
MessageBox(NULL, _T("Could not load the small icon! :("), _T("Error!"), MB_OK | MB_ICONERROR);
GLvoid OpenGL::KillOpenGL(HWND hwnd, HDC hDC, HGLRC hRC)
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
所有渲染代码都将进入 OpenGL.cpp 内的“RenderGLScene”函数,但是当我放置代码以在屏幕上渲染三角形或正方形等基本内容时,什么也没有出现。我也尝试过修改“gluLookAt()”函数和“gluPerspective()”函数,因为我认为这些可能是我问题的根源。我已经尝试过 VBO 和使用 glBegin()/glEnd() 的旧方法。
【问题讨论】:
我认为您的 gluPerspective 调用没有问题。我在任何地方都看不到 gluLookAt,也没有任何实际的对象渲染。请添加您的实际渲染代码,不要让我们猜测您在做什么。另外,在开发过程中,始终将 glGetError 放在你的绘图循环中至少一个地方,它会告诉你是否有问题。 【参考方案1】:您创建了一个双缓冲上下文,但我没有看到您在完成渲染后执行缓冲区交换 (wglSwapBuffers
)。如果没有缓冲区交换,您将什么都看不到。
【讨论】:
在 main.cpp SwapBuffers 在我的渲染函数之后被调用。我认为这是对的,但是,嘿,我可能错了。【参考方案2】:您的渲染代码是什么样的。请记住,相机始终位于原点,这意味着您需要在负 z 坐标处绘制东西。
【讨论】:
【参考方案3】:如果您创建了核心上下文,则所有绘图都必须使用 VAO 完成。检查 glError() 返回代码以查看 glDraw*() 报告的内容。
【讨论】:
嗯,glError
实在是太烦人了。请改用调试上下文。 (如果可以的话,那就是)
它使用了很多其他非核心功能。矩阵堆栈,无着色器渲染等。它请求 32 位深度缓冲区,大多数硬件不支持。
我很清楚这一点;我确实通读了代码。 glError 代码可能并不酷,但它们会告诉您是否有任何调用引发错误状态。如果发生任何可疑情况,一个 glError 调用就足以赶上。然后,当然,对确切的位置进行二进制搜索是一项艰巨的工作。但在我看来,他只是想获得一个上下文,在 wgl 中使用新的扩展上下文创建,所以看起来是否有任何错误的第一步是合乎逻辑的,如果有,在哪里。在检查错误状态之前,我看不到任何附加值推测。以上是关于OpenGL啥都不显示?的主要内容,如果未能解决你的问题,请参考以下文章