glEnable(GL_DEPTH_TEST) 开启深度缓存
glDisable(GL_DEPTH_TEST) 关闭深度缓存
使用深度缓存前的初始化,不重置投影和模型观察矩阵会导致一些显示错误
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity(); // 重置投影矩阵
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵
代码:
#include <Windows.h>
#include <iostream>
#include <gl\GL.h>
#include <gl\GLU.h>
#pragma comment(lib,"opengl32.lib")//opengl相关库
#pragma comment(lib,"glu32.lib")
/全局句柄
HGLRC hRC;
HDC hDC;
HWND hWnd;
/全局句柄
//全局变量
bool flag_depth = true;//是否深度测试
float rx = 0,ry=0;//旋转变量
GLfloat vec[][3] = {//立方体顶点坐标
{ -1, 1, -1 }, { 1, 1, -1 }, { 1, 1, 1 }, { -1, 1, -1 }, { 1, 1, 1 }, { -1, 1, 1 },//前
{ -1, -1, -1 }, { 1, -1, -1 }, { 1, -1, 1 }, { -1, -1, -1 }, { 1, -1, 1 }, { -1, -1, 1 },//后
{ -1, 1, 1 }, { -1, 1, -1 }, { -1, -1, -1 }, { -1, 1, 1 }, { -1, -1, -1 }, { -1, -1, 1 },//左
{ 1, 1, 1 }, { 1, 1, -1 }, { 1, -1, -1 }, { 1, 1, 1 }, { 1, -1, -1 }, { 1, -1, 1 },//右
{ -1, -1, 1 }, { -1, 1, 1 }, { 1, 1, 1 }, { -1, -1, 1 }, { 1, 1, 1 }, { 1, -1, 1 },//上
{ -1, -1, -1 }, { -1, 1, -1 }, { 1, 1, -1 }, { -1, -1, -1 }, { 1, 1, -1 }, { 1, -1, -1 },//下
};
GLfloat col[][3] = {//各顶点颜色坐标
{ 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 0.1, 0.2, 0.3 }, { 0.1, 0.2, 0.3 }, { 0.1, 0.2, 0.3 },//前
{ 0.4, 0.4, 0.0 }, { 0.4, 0.4, 0.0 }, { 0.4, 0.4, 0.0 }, { 0.8, 0.4, 0.0 }, { 0.8, 0.4, 0.0 }, { 0.8, 0.4, 0.0 },//后
{ 0.8, 0.4, 0.8 }, { 0.8, 0.4, 0.8 }, { 0.8, 0.4, 0.8 }, { 0.0, 0.4, 0.8 }, { 0.0, 0.4, 0.8 }, { 0.0, 0.4, 0.8 },//左
{ 0.3, 0.3, 0.3 }, { 0.3, 0.3, 0.3 }, { 0.3, 0.3, 0.3 }, { 0.4, 0.4, 0.4 }, { 0.4, 0.4, 0.4 }, { 0.4, 0.4, 0.4 },//右
{ 0.4, 0.0, 0.4 }, { 0.4, 0.0, 0.4 }, { 0.4, 0.0, 0.4 }, { 0.4, 0.0, 0.0 }, { 0.4, 0.0, 0.0 }, { 0.4, 0.0, 0.0 },//上
{ 0.0, 0.4, 0.0 }, { 0.0, 0.4, 0.0 }, { 0.0, 0.4, 0.0 }, { 0.0, 0.0, 0.4 }, { 0.0, 0.0, 0.4 }, { 0.0, 0.0, 0.4 },//下
};
void InitGL()//初始化opengl参数
{
glClearColor(0.5, 0.5, 0.5, 1);//设置颜色缓存颜色
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glTranslated(0, 0, -1);
glVertexPointer(3, GL_FLOAT, 0, vec);
glColorPointer(3, GL_FLOAT, 0, col);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity(); // 重置投影矩阵
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
glLoadIdentity(); // 重置模型观察矩阵
glScalef(0.5,0.5,0.5); //缩放0.5倍
}
void DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 每次刷新屏幕颜色缓存
if (flag_depth) glEnable(GL_DEPTH_TEST);
else glDisable(GL_DEPTH_TEST);
glRotated(rx, 1, 0, 0);
glRotated(ry, 0, 1, 0);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)// 消息处理回调函数
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // 按键按下 由wParam决定
{
switch (wParam)
{
case 'D':
flag_depth = !flag_depth;
break;
case VK_UP:
rx += 0.001;
break;
case VK_DOWN:
rx -= 0.001;
break;
case VK_LEFT:
ry += 0.001;
break;
case VK_RIGHT:
ry -= 0.001;
break;
}
return 0; // Jump Back
}
case WM_KEYUP: // 按键松开
{
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));//改变GL窗口大小
return 0; // Jump Back
}
case WM_PAINT:
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hwnd, uMsg, wParam, lParam);//默认消息回调处理函数
}
void KillGLWindow()
{
if (hRC) // 删除着色描述表
{
if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL; // Set RC To NULL
}
if (hDC && !ReleaseDC(hWnd, hDC)) // 释放DC
{
MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hDC = NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL, "Could Not Release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hWnd = NULL; // Set hWnd To NULL
}
}
int WINAPI WinMain(HINSTANCE h,HINSTANCE,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wc;
wc.hInstance = h;
wc.hbrBackground = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC)WndProc;
RegisterClass(&wc);
hWnd = CreateWindow("OpenGL", "test", WS_OVERLAPPEDWINDOW | WS_SYSMENU | WS_BORDER | WS_MAXIMIZEBOX, 0, 0, 300, 300, NULL, NULL, h, NULL);
//opengl设定
hDC = GetDC(hWnd);
static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
24, // Select Our 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
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
int PixelFormat;
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // 按照给定像素格式规范匹配与设备上下文合适的像素格式
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 设置像素格式
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, "不能设置像素格式", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!(hRC = wglCreateContext(hDC))) // 设置合适设备的OpenGL渲染上下文
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, "不能创建OpenGL渲染描述表", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!wglMakeCurrent(hDC, hRC)) // 尝试激活着色描述表
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, "不能激活当前的OpenGL渲然描述表", "错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
//opengl着色表设定结束
ShowWindow(hWnd, SW_SHOW);
InitGL();//opengl相关初始化
//消息处理
bool done = false;
MSG msg;
while (!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // 如果有消息就处理消息
{
if (msg.message == WM_QUIT) // Have We Received A Quit Message?
{
done = TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // 没消息就处理界面
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
}
}
return TRUE;
}