win32+opengl编程框架

需要附加opengl32.lib glaux.lib  glu32.lib三个文件

 

 

/**************************************************

*********a framework for programming with OpenGL+Win32

*****************which is written by myself**********/

//2010.9.25 by lint

 

#include "windows.h"

#include "stdio.h"

#include "stdlib.h"

#include "gl/gl.h"

#include "gl/glu.h"

#include "tchar.h"    //为了兼容unicode模式,使用L和_T需要这个头文件

 

 

//declaration

int createGLWindow( wchar_t *title, int left_top_x, int left_top_y, int width, int height, int bits /*颜色的位数*/ ); //创建窗口

void initOpenGL();    //初始化opengl

void drawGLScene();   //用opengl进行画图

void idle();          //将除消息处理和opengl画图外要经常进行的操作放在这里

void deleteGLWindow(); //删除窗口

void resizeGLWindow();  

void initVars();     //对整个系统的初始化操作(不含对 opengl的初始化)

 

LRESULT CALLBACK BallWndProc(

HWND hwnd,      // handle to window

UINT uMsg,      // message identifier

WPARAM wParam,  // first message parameter

LPARAM lParam   // second message parameter

);

 

 

//global variable

int done = false;

HWND hwnd;

HDC hDC;

HINSTANCE hInst;

HGLRC hrc;

 

//main programm

int WINAPI WinMain(

  HINSTANCE hInstance,      // handle to current instance

  HINSTANCE hPrevInstance,  // handle to previous instance

  LPSTR lpCmdLine,          // command line

  int nCmdShow              // show state

  )

{

hInst = hInstance;

initVars();

 

//create window

if( !createGLWindow(_T("ball_collision"),0, 0, 500, 500, 16 ))

{

return 0;

}

 

//init opengl

initOpenGL();

 

//process messages

MSG msg;

while(!done)

{

//这里不要用PeekMeesage(&msg,hwnd, null,null, pm_remove)。否则当postquitmessasge时,会直接调用wm_destroy消息后,窗口

//被注销,这里就得不到wm_quit消息了

//http://blog.csdn.net/dadalan/archive/2010/07/07/5719056.aspx

if( PeekMessage(&msg, NULL, NULL, NULL, 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

{

idle();

drawGLScene();

SwapBuffers(hDC);

}

}

 

//some actions before the programm end

deleteGLWindow();

}

 

 

void drawGLScene()

{

//设置清屏颜色为黑色

glClearColor(0.0f,0.0f,0.0f,0.0f);

//清除颜色缓冲区和深度缓冲区

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

//矩阵堆栈函数,和glPopMatrix()相对应

glPushMatrix();

 

//设置点的大小

glPointSize(10.0);

//说明几何图元为“点”,和glEnd()相对应

glBegin(GL_POINTS);

//绘制红色的点

glColor3f(1.0,0.0,0.0);

glVertex3f(-0.7,-0.7,0.0);

//绘制绿色的点

glColor3f(0.0,1.0,0.0);

glVertex3f(0.7,-0.7,0.0);

//绘制白色的点

glColor3f(1.0,1.0,1.0);

glVertex3f(0.0,0.0,0.0);

//绘制兰色的点

glColor3f(0.0,0.0,1.0);

glVertex3f(0.7,0.7,0.0);

//绘制黄色的点

glColor3f(1.0,1.0,0.0);

glVertex3f(-0.7,0.7,0.0);

glEnd();

 

glPopMatrix();

glFinish();

}

 

void idle()

{

}

 

void initOpenGL()

{

 

}

 

void deleteGLWindow()

{

//释放hrc

if(hrc)

{

//将hrc与hdc脱钩

if(!wglMakeCurrent(NULL,NULL))

{

MessageBox(NULL, L"failed to release hrc from hdc", L"error", MB_OK);

}

 

if(!wglDeleteContext(hrc))

{

MessageBox(NULL,L"failed to delete hrc", L"error", MB_OK);

}

hrc = NULL;

}

 

//释放hdc

if(hDC && !ReleaseDC(hwnd, hDC ))

{

MessageBox(NULL, L"failed to released dc ", L"error", MB_OK );

hDC = NULL;

}

 

//删除窗口

if(hwnd && !DestroyWindow(hwnd))

{

MessageBox(NULL, L"failed to destroy window", L"error", MB_OK);

hwnd = NULL;

}

 

//反注册类

if( !UnregisterClass(L"ball", hInst))

{

MessageBox(NULL, L"failed to unregister class", L"error", MB_OK);

hInst = NULL;

}

}

 

void resizeGLWindow(int cx, int cy )

{

int w=cx;

int h=cy;

GLfloat nRange=1.0f;

//避免除数为0

if(h==0)

h=1;

 

//设置视口与窗口匹配

glViewport(0,0,w,h);

 

//重新设置坐标系统

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

 

//建立正交变换下的剪切体

if(w<h)

glOrtho(-nRange,nRange,-nRange*h/w,nRange*h/w,-nRange,nRange);

else

glOrtho(-nRange*w/h,nRange*w/h,-nRange,nRange,-nRange,nRange);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

 

 

}

 

int createGLWindow( wchar_t *title, int x, int y, int width, int height, int bits )

{

//define window class

WNDCLASS wc;

wc.cbClsExtra=0;

wc.cbWndExtra=0;

wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

wc.hCursor=LoadCursor(hInst,IDC_ARROW);

wc.hIcon=LoadIcon(hInst, IDI_WINLOGO);

wc.hInstance=hInst;

wc.lpfnWndProc=(WNDPROC)BallWndProc;

wc.lpszClassName=_T("ball");

wc.lpszMenuName=NULL;

wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

 

//register class

if( !RegisterClass(&wc))

{

MessageBox( NULL, _T("failed to register class!"), _T("error"), MB_OK);

return 0;

}

 

//创建窗口

if( !(hwnd=CreateWindow(_T("ball"),title, WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, hInst, NULL)))

{

MessageBox(NULL, _T("failed to create window"), _T("error"), MB_OK);

return 0;

}

 

//link opengl with win32

if( !(hDC = GetDC(hwnd)))

{

MessageBox(hwnd, _T("cannot get a hdc"), _T("error"), MB_OK);

return false;

}

 

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

bits, // 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

};

GLuint pixelFormat;

 

if( !(pixelFormat = ChoosePixelFormat(hDC, &pfd)))

{

deleteGLWindow();

MessageBox(NULL, _T("failed to choose a valid pixel format"), _T("error"), MB_OK );

return 0;

}

 

if(!SetPixelFormat(hDC, pixelFormat, &pfd))

{

deleteGLWindow();

MessageBox(NULL, _T("failed to set pixel format"), _T("error"), MB_OK );

return 0;

}

 

if(!(hrc = wglCreateContext(hDC)))

{

deleteGLWindow();

MessageBox( NULL, _T("failed to create context!"), _T("error"), MB_OK );

return 0;

}

 

if( !wglMakeCurrent(hDC, hrc))

{

deleteGLWindow();

MessageBox( NULL, _T("failed to make current!"), _T("error"), MB_OK );

return 0;

}

 

//show window

ShowWindow(hwnd, SW_SHOW );

SetForegroundWindow(hwnd); // Slightly Higher Priority, 没有也可以

SetFocus(hwnd);

 

//resize

resizeGLWindow(width, height);

 

//这里一定要return true

return 1;

 

}

 

LRESULT CALLBACK BallWndProc(

HWND hwnd,      // handle to window

UINT uMsg,      // message identifier

WPARAM wParam,  // first message parameter

LPARAM lParam   // second message parameter

)

{

switch(uMsg)

{

case WM_CLOSE: // Did We Receive A Close Message?

{

PostQuitMessage(0); // Send A Quit Message

return 0; // Jump Back

}

 

case WM_SIZE:

resizeGLWindow(LOWORD(lParam),HIWORD(lParam));

return 0;

default:

;

}

return DefWindowProc(hwnd, uMsg,wParam, lParam );

}

 

void initVars()

{

 

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值