看流星社区

 找回密码
 注册账号
查看: 2099|回复: 0

VC OpenGL框架

[复制链接]

该用户从未签到

发表于 2013-3-17 08:56:02 | 显示全部楼层 |阅读模式
//窗口及OpenGL所使用的库的头文件
#include <windows.h>        //视窗头文件
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glaux.h>

//定义程序中计划使用的所有变量
HWND   hWnd=NULL;            //得到窗口的句柄
HDC    hDC=NULL;             //私有的GDI设备环境
HGLRC hRC=NULL;             //定义渲染环境
HINSTANCE hInstance;        //建立一个程序的例子Instance(事件)

//设置窗口大小,斜率及全屏标志变量
RECT   rect;
int   sw = 640;
int   sh = 480;
bool   fullscreen   = 1;
GLfloat aspect;

//定义程序链接时所需要调用的OpenGL程序库
#pragma comment( lib, "opengl32.lib" )    // 链接时使用OpenGL32.lib
#pragma comment( lib, "glu32.lib" )     // 链接时使用GLu32.lib
#pragma comment( lib, "glaux.lib" )     // 链接时使用GLaux.lib

//OpenGL初始化开始
void SceneInit(int w,int h)
{
glShadeModel(GL_SMOOTH);        //允许平滑着色
glClearColor( 1.0, 1.0, 1.0, 0.5 );                  //设置屏幕清屏的颜色
glClearDepth(1.0f);          //设置深度缓冲区
glEnable(GL_DEPTH_TEST);                             //允许深度测试
glDepthFunc(GL_LEQUAL);         //深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //透视校正,会使透视效果显得更好一些
}

//窗口尺寸改变时OpenGL场景的尺寸
void SceneResizeViewport(GLsizei w, GLsizei h)
{
if(h==0)
{
   h=1;
}
aspect = (GLfloat)w/(GLfloat)h;
     //设置透视场景,透视的作用是景物距离越远其尺寸越小
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);       //选择投影矩阵
glLoadIdentity();

gluPerspective( 45.0f, aspect, 0.1f, 100.0f ); //基于窗口的高和宽并以45度视角进行计算。0.1f和
                                                 //100f是绘制在屏幕上相对于屏幕距离的开始点和
                                                 //结束点
glMatrixMode(GL_MODELVIEW);                     //确定任何新的变换都会影响模型视点矩阵ModelView
glLoadIdentity();                                //把被选择的矩阵还原到初始状态
}

void SceneShow(GLvoid)          //这里进行所有的绘图工作
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清屏和清除深度缓冲区
glLoadIdentity();                  //重置当前Modelview矩阵
    //此处添加绘图命令
}     

//激活创建OpenGL窗口
void EnableOpenGL()
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;

hDC = GetDC( hWnd );

ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags =    PFD_DRAW_TO_WINDOW |
   PFD_SUPPORT_OPENGL |
   PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 16;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;

iFormat = ChoosePixelFormat( hDC, &pfd );

SetPixelFormat( hDC, iFormat, &pfd );

hRC = wglCreateContext( hDC );
wglMakeCurrent( hDC, hRC );
}

// 取消 OpenGL ,在程序结束前调用,释放渲染环境,设备环境以及最终窗口句柄。
void DisableOpenGL()
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
}

//改变屏幕的分辨率
bool ChangeResolution(int w, int h, int bitdepth)
{
DEVMODE devMode;
int    modeSwitch;
int    closeMode = 0;

EnumDisplaySettings(NULL, closeMode, &devMode);

devMode.dmBitsPerPel = bitdepth;
devMode.dmPelsWidth   = w;
devMode.dmPelsHeight = h;
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

modeSwitch = ChangeDisplaySettings(&devMode, CDS_FULLSCREEN);

if(modeSwitch == DISP_CHANGE_SUCCESSFUL)
{
   return true;
}
else
{
   ChangeDisplaySettings(NULL, 0);
   return false;
}
}

//处理窗口信息
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )                             //将message设置为所有事件声明比较的
                                                //值,message将得到要处理的消息的名字
{
case WM_CREATE:                                    //监视窗口激活的信息
   GetWindowRect(hWnd, &rect);
   sw = rect.right - rect.left;
   sh = rect.bottom - rect.top;
   SceneResizeViewport(sw, sh);
   return 0;

case WM_SIZE:                                      //改变OpenGL窗口的尺寸。

   if(!fullscreen)
   {
    GetWindowRect(hWnd, &rect);
    sw = rect.right - rect.left;
    sh = rect.bottom - rect.top;
    if(sw>0 && sh>0)
     SceneResizeViewport(sw, sh);
   }
   else
   {
    SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
     GetSystemMetrics( SM_CYSCREEN ));
   }

   return 0;

case WM_CLOSE:                                                 //是否收到一个关闭信息?
   ShowWindow (hWnd, SW_HIDE);
   PostQuitMessage( 0 );
   return 0;

case WM_DESTROY:
   return 0;

case WM_KEYDOWN:                                                //是否有一个键被按下?
   switch( wParam )
   {
   case VK_ESCAPE:
    PostMessage(hWnd, WM_CLOSE, 0, 0);
    break;
   }
   return 0;
default:
   return DefWindowProc( hWnd,message, wParam, lParam );        //一些无须在意的信息视窗自己处理
}
}


int APIENTRY WinMain(HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR      lpCmdLine,
       int        nCmdShow)
{
WNDCLASS wc;               //窗口类
MSG msg;                   //检测是否有信息在等待处理
bool bQuit = false;        //bQuit为FLASE,程序当前在运行;为TRUE程序将退出


     //询问选择那种屏幕模式
if (MessageBox(NULL,"是否选择全屏显示模式?", "全屏模式运行?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
   fullscreen=0;        //窗口模式
}
      //创建OpenGL窗口,设置标题、宽高及颜色数
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "Name";
RegisterClass( &wc );


if(fullscreen)
{
   ChangeResolution(640, 480, 16);
   hWnd = CreateWindow(
    "Name",
    "Lesson1",
    WS_POPUP |   WS_CLIPSIBLINGS | WS_VISIBLE,
    0, 0,
    GetSystemMetrics( SM_CXSCREEN ),
    GetSystemMetrics( SM_CYSCREEN ),
    NULL, NULL,
    hInstance,
    NULL );
}else
{
   hWnd = CreateWindow(
    "Name",
    "Model001",
    WS_TILEDWINDOW | WS_VISIBLE,
    GetSystemMetrics( SM_CXSCREEN )/2-sw/2,
    GetSystemMetrics( SM_CYSCREEN )/2-sh/2,
    sw,
    sh,
    NULL, NULL,
    hInstance,
    NULL );
   ChangeDisplaySettings(NULL, 0);
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);

//初始化
EnableOpenGL();
SceneInit(sw, sh);

if(!fullscreen)
{
   GetWindowRect(hWnd, &rect);
   sw = rect.right - rect.left;
   sh = rect.bottom - rect.top;
   if(sw>0 && sh>0)
    SceneResizeViewport(sw, sh);
}
else
{
   SceneResizeViewport(GetSystemMetrics( SM_CXSCREEN ),
   GetSystemMetrics( SM_CYSCREEN ));
}
//下面开始循环,如果bQuit的值一直是FLASE,循环将一直重复下去
while ( !bQuit )
{
   if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )     //通过PeekMessage(),检测是否有消息
                                                        //在等待,又不会使程序挂起
    if ( msg.message == WM_QUIT )                        //检测是否有退出消息发出               
     bQuit = true;
    else
    {
     TranslateMessage( &msg );//如果消息不是退出,使得WndProc()或窗口能处理它
     DispatchMessage( &msg );
    }
   else
   {

    // OpenGL 动画,如果程序被激活并且ESC没有被按下,可以渲染场景及交换缓冲区(通过使用
    //双缓冲区可获得平滑运动的动画)
    //通过使用双缓存,先在不可见的隐藏屏幕上绘制,当交换缓冲区时,隐藏屏幕变为可见屏幕,
    //原先可见的屏幕变为隐藏,这样
    //就看不到屏幕被绘制的过程,画面会马上出现,这样看上去会更真实。
   
    SceneShow();
    SwapBuffers(hDC);

   }
}

//关闭,退出程序。清除OpenGL窗口,以便释放所有资源,然后退出程序。
DisableOpenGL();

ShowWindow (hWnd, SW_HIDE);
DestroyWindow( hWnd );

ChangeDisplaySettings(NULL, 0);

return msg.wParam;

return 0;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-5-3 10:19

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表