kmusttywyc 发表于 2004-10-15 21:27

[分享]OPENGL

<P>这是NENE的OPENGL的框架CB原代码,是黑屏的效果,最简单的。OPENGL我才开始学,很多不懂的,希望和大家交流,共同进步,我会把我的资料和大家共享的!</P>
<P>首先在CB下建立一个CONSOLE的程序,然后把CONSOLE APPLICATION的勾去掉即可。然后再把以下的原代码粘贴上去就可以运行了!!</P>
<P>//---------------------------------------------------------------------------</P>
<P>#include &lt;vcl.h&gt;
#include &lt;windows.h&gt;    // Header file for windows
#include &lt;gl\gl.h&gt;      // Header file for the OpenGL32 library
#include &lt;gl\glu.h&gt;     // Header file for the GLu32 library
#include &lt;gl\glaux.h&gt;   // Header file for the GLaux library
#pragma hdrstop</P>
<P>//---------------------------------------------------------------------------
#pragma argsused</P>
<P>HGLRC hRC = NULL;               // Permanent rendering context
HDC hDC = NULL;                 // Private GDI device context
HWND hWnd = NULL;               // Holds our window handle
HINSTANCE hInstance = NULL;     // Holds the instance of the application</P>
<P>bool keys;                 // Array used for the keyboard routine
bool active = true;             // Window active flag set to true by default
bool fullscreen = true;         // Fullscreen flag set to fullscreen mode by default</P>
<P>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   // Declaration for WndProc</P>
<P>GLvoid ReSizeGLScene(GLsizei width, GLsizei height)     // Resize and initialize the GL window
{
        if (height == 0)                        // Prevent a divide by zero by
        {
                height = 1;                     // Making height equal One
        }</P>
<P>        glViewport(0, 0, width, height);        // Reset the current viewport</P>
<P>        glMatrixMode(GL_PROJECTION);            // Select the projection matrix
glLoadIdentity();                       // Reset the projection matrix</P>
<P> // Calculate the aspect ratio of the window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);</P>
<P> glMatrixMode(GL_MODELVIEW);             // Select the modelview matrix
glLoadIdentity();                       // Reset the modelview matrix
}</P>
<P>int InitGL(GLvoid)      // All setup for OpenGL goes here
{
glShadeModel(GL_SMOOTH);                // Enable smooth shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);   // Black background
glClearDepth(1.0f);                     // Depth buffer setup
glEnable(GL_DEPTH_TEST);                // Enables depth testing
glDepthFunc(GL_LEQUAL);                 // The type of depth testing to do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);      // Really nice perspective calculations
return true;                            // Initialization went OK
}</P>
<P>int DrawGLScene(GLvoid)         // Here's where we do all the drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer
glLoadIdentity();       // Reset the current modelview matrix
        
return true;            // Everything went OK
}</P>
<P>GLvoid KillGLWindow(GLvoid)     // Properly kill the window
{
if (fullscreen)         // Are we in fullscreen mode?
{
  ChangeDisplaySettings(NULL,0);  // If so switch back to the desktop
  ShowCursor(true);               // Show mouse pointer
}</P>
<P> if (hRC)        // Do we have a rendering context?
{
  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);
  }</P>
<P>  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
}</P>
<P> if (hDC &amp;&amp; !ReleaseDC(hWnd,hDC))        // Are we able to release the DC
{
  MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  hDC = NULL;             // Set DC to NULL
}</P>
<P> if (hWnd &amp;&amp; !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
}</P>
<P> if (!UnregisterClass("OpenGL",hInstance))       // Are we able to unregister class
{
  MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
  hInstance = NULL;       // Set hInstance to NULL
}
}</P>
<P>/* This Code Creates Our OpenGL Window.  Parameters Are:
* title   - Title To Appear At The Top Of The Window
* width   - Width Of The GL Window Or Fullscreen Mode
* height   - Height Of The GL Window Or Fullscreen Mode
* bits   - Number Of Bits To Use For Color (8/16/24/32)
* fullscreenflag - Use Fullscreen Mode (true) Or Windowed Mode (false)*/

bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint  PixelFormat;  // Holds the results after searching for a match
WNDCLASS wc;          // Windows class structure
DWORD  dwExStyle;              // Window extended style
DWORD  dwStyle;                // Window style
RECT  WindowRect;             // Grabs rctangle upper left / lower right values
WindowRect.left = (long)0;              // Set left value to 0
WindowRect.right = (long)width;  // Set right value to requested width
WindowRect.top = (long)0;               // Set top value to 0
WindowRect.bottom = (long)height;       // Set bottom value to requested height</P>
<P> fullscreen = fullscreenflag;              // Set the global fullscreen flag</P>
<P> hInstance               = GetModuleHandle(NULL);  // Grab an instance for our window
wc.style                = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;   // Redraw on size, and own DC for window
wc.lpfnWndProc          = (WNDPROC) WndProc;   // WndProc handles messages
wc.cbClsExtra           = 0;     // No extra window data
wc.cbWndExtra           = 0;     // No extra window data
wc.hInstance            = hInstance;    // Set the Instance
wc.hIcon                = LoadIcon(NULL, IDI_WINLOGO);  // Load the default icon
wc.hCursor              = LoadCursor(NULL, IDC_ARROW);  // Load the arrow pointer
wc.hbrBackground        = NULL;     // No background required for GL
wc.lpszMenuName  = NULL;     // We don't want a menu
wc.lpszClassName = "OpenGL";    // Set the class name</P>
<P> if (!RegisterClass(&amp;wc))     // Attempt to register the window class
{
  MessageBox(NULL,"Failed to register the window class.","Error",MB_OK|MB_ICONEXCLAMATION);</P>
<P>  return false;   // Return false
}

if (fullscreen)         // Attempt fullscreen mode?
{
  DEVMODE dmScreenSettings;                                       // Device mode
  memset(&amp;dmScreenSettings,0,sizeof(dmScreenSettings));         // Makes sure memory's cleared
  dmScreenSettings.dmSize         = sizeof(dmScreenSettings);     // Size of the devmode structure
  dmScreenSettings.dmPelsWidth = width;                        // Selected screen width
  dmScreenSettings.dmPelsHeight = height;                       // Selected screen height
  dmScreenSettings.dmBitsPerPel = bits;                         // Selected bits per pixel
  dmScreenSettings.dmFields       = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;</P>
<P>  // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
  if (ChangeDisplaySettings(&amp;dmScreenSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
  {
   // If the mode fails, offer two options. Quit or use windowed mode.
   if (MessageBox(NULL,"The requested fullscreen mode is not supported by\nyour video card. Use windowed mode instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION) == IDYES)
   {
    fullscreen = false;       // Windowed mode selected. Fullscreen = false
   }
   else
   {
    // Pop up a message box letting user know the program is closing.
    MessageBox(NULL,"Program will now close.","ERROR",MB_OK|MB_ICONSTOP);
    return false;           // Return false
   }
  }
}</P>
<P> if (fullscreen)                         // Are We Still In Fullscreen Mode?
{
  dwExStyle = WS_EX_APPWINDOW;    // Window extended style
  dwStyle = WS_POPUP;  // Windows style
  ShowCursor(false);  // Hide mouse pointer
}
else
{
  dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;           // Window extended style
  dwStyle = WS_OVERLAPPEDWINDOW;                            // Windows style
}</P>
<P> AdjustWindowRectEx(&amp;WindowRect,dwStyle,false,dwExStyle);        // Adjust window to true requested size</P>
<P> // Create the window
if (!(hWnd = CreateWindowEx(dwExStyle,          // Extended Style For The Window
                "OpenGL",    // Class name
  title,     // Window title
  dwStyle |    // Defined window style
  WS_CLIPSIBLINGS |   // Required window style
  WS_CLIPCHILDREN,   // Required window style
  0, 0,     // Window position
  WindowRect.right-WindowRect.left, // Calculate window width
  WindowRect.bottom-WindowRect.top, // Calculate window height
  NULL,     // No parent window
  NULL,     // No menu
  hInstance,    // Instance
  NULL)))     // Dont pass anything to WM_CREATE
{
  KillGLWindow();                         // Reset the display
  MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;                           // Return false
}</P>
<P> 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
};

if (!(hDC = GetDC(hWnd)))         // Did we get a device context?
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> if (!(PixelFormat = ChoosePixelFormat(hDC,&amp;pfd))) // Did windows find a matching pixel format?
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> if(!SetPixelFormat(hDC,PixelFormat,&amp;pfd))       // Are we able to set the pixel format?
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> if (!(hRC = wglCreateContext(hDC)))               // Are we able to get a rendering context?
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> if(!wglMakeCurrent(hDC,hRC))    // Try to activate the rendering context
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> ShowWindow(hWnd,SW_SHOW);       // Show the window
SetForegroundWindow(hWnd);      // Slightly higher priority
SetFocus(hWnd);                 // Sets keyboard focus to the window
ReSizeGLScene(width, height);   // Set up our perspective GL screen</P>
<P> if (!InitGL())                  // Initialize our newly created GL window
{
  KillGLWindow();         // Reset the display
  MessageBox(NULL,"Initialization failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return false;           // Return false
}</P>
<P> return true;                    // Success
}</P>
<P>LRESULT CALLBACK WndProc(HWND hWnd,     // Handle for this window
                        UINT uMsg,      // Message for this window
   WPARAM wParam,  // Additional message information
   LPARAM lParam)  // Additional message information
{
switch (uMsg)                           // Check for windows messages
{
  case WM_ACTIVATE:               // Watch for window activate message
  {
   if (!HIWORD(wParam))    // Check minimization state
   {
    active = true;  // Program is active
   }
   else
   {
    active = false; // Program is no longer active
   }</P>
<P>   return 0;               // Return to the message loop
  }</P>
<P>  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
  }</P>
<P>  case WM_CLOSE:                  // Did we receive a close message?
  {
   PostQuitMessage(0);     // Send a quit message
   return 0;               // Jump back
  }</P>
<P>  case WM_KEYDOWN:                // Is a key being held down?
  {
   keys = true;    // If so, mark it as true
   return 0;               // Jump back
  }</P>
<P>  case WM_KEYUP:                  // Has a key been released?
  {
   keys = false;   // If so, mark it as false
   return 0;               // Jump back
  }</P>
<P>  case WM_SIZE:                   // Resize the OpenGL window
  {
   ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord = Width, HiWord = Height
   return 0;               // Jump back
  }
}</P>
<P> // Pass all unhandled messages to DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}</P>
<P>WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
        MSG msg;                // Windows message structure
bool done = false;      // bool variable to exit loop</P>
<P> // Ask the user which screen mode they prefer
if (MessageBox(NULL,"Would you like to run in fullscreen mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION) == IDNO)
{
  fullscreen = false;       // Windowed mode
}</P>
<P> // Create our OpenGL window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
{
  return 0;               // Quit if window was not created
}</P>
<P> while(!done)                    // Loop that runs while done = false
{
  if (PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE)) // Is there a message waiting?
  {
   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(&amp;msg);         // Translate the message
    DispatchMessage(&amp;msg);          // Dispatch the message
   }
  }
  else            // If there are no messages
  {
   // Draw the scene.  Watch for ESC key and quit messages from DrawGLScene()
   if (active)                             // Program active?
   {
    if (keys)            // Was ESC pressed?
    {
     done = true;            // ESC signalled a quit
    }
    else                            // Not time to quit, Update screen
    {
     DrawGLScene();          // Draw the scene
     SwapBuffers(hDC);       // Swap buffers (Double buffering)
    }
   }</P>
<P>   if (keys)                        // Is F1 being pressed?
   {
    keys = false;            // If so make key false
    KillGLWindow();                 // Kill our current window
    fullscreen =! fullscreen;       // Toggle fullscreen / windowed mode
    // Recreate our OpenGL window
    if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
    {
     return 0;               // Quit if window was not created
    }
   }
  }
}</P>
<P> // Shutdown
KillGLWindow();         // Kill the window
return (msg.wParam);    // Exit the program
}
//---------------------------------------------------------------------------</P>

ilikenba 发表于 2004-10-16 00:37

<P>试验了,果然是黑屏的效果!</P>

ilikenba 发表于 2004-10-16 00:41

<P>我也支持一篇</P><P>转贴:Win 95/NT下OpenGL编程原理 ----</P><P>科学计算可视化,计算机动画和虚拟现实是现在计算机图形学的三个热点。而这三个热点的核心都是三维真实感图形的绘制。由于OpenGL(OpenGraphicsLibrary)具有跨平台性、简便、高效、功能完善,目前已经成为了三维图形制作方法中事实上的工业标准。自从WindowsNT3.51在微机平台上支持OpenGL以后,现在微软公司在Windows95OSR2、WindowsNT4.0中连续性的提供OpenGL开发环境。VisualC++从4.2版本以后已经完全支持
OpenGL API,使三维世界的"平民化"已成为必然。
----Windows操作系统对OpenGL的支持
----具有Windows编程经验的人都知道,在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数;用OpenGL作图也是类似,OpenGL函数是通过"渲染上下文"(RenderingContext简写RC)完成三维图形的绘制。Windows下的窗口和设备上下文支持"位图格式"(PIXELFORMAT)属性,和RC有着位图结构上的一致。只要在创建RC时与一个DC建立联系(RC也只能通过已经建立了位图格式的DC来创建),OpenGL的函数就可以通过RC对应的DC画到相应的显示设备上。这里还有以下需要注意的方面:
----1.一个线程只能拥有一个渲染上下文(RC),也就是说,用户如果在一个线程内对不同设备作图,只能通过更换与RC对应的DC来完成,而RC在
线程中保持不变。(当然,删除旧的RC后再创建新的是可以的)与此对应,一个RC也只能属于一个线程,不能被不同线程同时共享。
----2.设定DC位图格式等于设定了相应的窗口的位图格式,并且DC和窗口的位图格式一旦确定就不能再改变。这一点只能期望以后的Windows版本改进了。
----3.一个RC虽然可以更换DC,在任何时刻只能利用一个DC(这个DC称为RC的当前DC),但由于一个窗口可以让多个DC作图从而可以让多个线程利用多个RC在该窗口上执行OpenGL操作。
----4.现在的Windows下的OpenGL版本对OpenGL和GDI在同一个DC上作图有一定的限制。当使用双缓存用OpenGL产生动画时,不能使用GDI函数向该DC作图。
----5.不建议用ANSIC在Windows下编写OpenGL程序。这样的程序虽然具有跨平台的可移植性(比如很多SGI的例子程序),但是它们不能利用Windows操作系统的很多特性,实用价值不大。
</P><P>----用VC来编写OpenGL程序

----经过上面的分析,用VC来调用OpenGL作图的方法就很显然了。步骤如下:

----1.先设置显示设备DC的位图格式(PIXELFORMAT)属性。这通过填充一个PIXELFORMATDESCRIPTOR的结构来完成(关于PIXELFORMATDESCRIPTOR中

各项数据的意义,请参照VC的帮助信息),该结构决定了OpenGL作图的物理设备的属性,比如该结构中的数据项dwFlags中PFD_DOUBLEBUFFER位如果

没有设置(置1),通过该设备的DC上作图的OpenGL命令就不可能使用双缓冲来做动画。有一些位图格式(PIXELFORMAT)是DC支持的,而有一些DC

就不支持了。所以程序必须先用ChoosePixelFormat来选择DC所支持的与指定位图格式最接近的位图格式,然后用SetPixelFormat设置DC的位图格式



----2.利用刚才的设备DC建立渲染上下文RC(wglCreateContext),使得RC与DC建立联系(wglMakeCurrent)。

----3.调用OpenGL函数作图。由于线程与RC一一对应,OpenGL函数的参数中都不指明本线程RC的句柄(handle)

----4.作图完毕以后,先通过置当前线程的RC为NULL(::wglMakeCurrent(NULL,NULL);),断开当前线程和该渲染上下文的联系,由此断开与DC的

联系。此时RC句柄的有效性在微软自己的文档中也没有讲清楚,所以在后面删除RC的时候要先判断以下RC句柄的有效性(

if(m_hrc)::wglDeleteContext(m_hrc);)。再根据情况释放(ReleaseDC)或者删除(DeleteDC)DC

----所附程序说明

----所附的程序用MFC完成了一个简单的OpenGL作图,用OpenGL的辅助库画了一个有光照的实心圆球。OpenGL本身的函数这里就不解释了,仅对用

MFC编OpenGL时需要注意的内容做一个简要的说明:

----1.一旦设定了一个DC的位图格式,该DC所联系的窗口的位图格式随之设定。该窗口若含有子窗口或者有兄弟窗口,这些兄弟/子窗口的位图格式

没有设成与对应RC一致的格式,OpenGL在它们上面作图就容易出错。故而OpenGL作图的窗口必须具有WS_CLIPCHILDREN和WS_CLIPSIBLINGS风格,程

序中在主框窗的构造函数中用LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,NULL,NULL);指定了主窗口的风

格。

----2.在ANSIC的OpenGL编程中,由auxReshapeFunc定义设置OpenGL视口大小和作图尺寸的回调函数。在MFC中应该由WM_SIZ消息的处理函数来完成

。在ANSIC的OpenGL编程中,由EauxMainLoop定义作图的回调函数。在MFC中应该由WM_PAINT消息的处理函数来处理。相应的,由OpenGL定义的键盘

、鼠标处理函数都应该由相应的Windows处理函数来响应。

----3.OpenGL自己有刷新背景的函数glClear,故而应禁止Windows刷新窗口背景。否则,当窗口需要重画时,Windows会自动先发送WM_ERASEBKGND

,而缺省的处理函数使用白色的背景刷。当OpenGL使用的背景颜色不是白色时,作图时有一帧白色的闪烁。这种现象在做动画时特别明显。程序中

只需要在WM_ERASEBKGND的消息处理函数中禁止父窗口类的消息处理,简单的返回一个TRUE即可。

----4.由于OpenGL的跨平台性,它必须用操作系统的调色板。所以如果GL_INDEX_MODE作图时,必须用VC自己定义调色板。不过一般情况下,用

GL_RGBA_MODE模式比较方便,很少用到GL_INDEX_MODE模式。

----5.在OpenGL作图期间,RC对应的DC不能删除或者释放。

----6.由于OpenGL作图时需要长时间占用DC,所以最好把作图窗口类设成CS_OWNDC。MFC缺省的窗口类风格中没有设这一属性,程序中在主窗口C++

类的PreCreateWindow方法中自己注册了一个窗口类,除了设定了CS_OWNDC属性以外,还设定了CS_HREDRAW、CS_VREDRAW和CS_SAVEBITS。设定

CS_HREDRAW、CS_VREDRAW是为了让窗口缩放时产生WM_PAINT消息,修正OpenGL视口和作图尺寸;由于OpenGL作图需要很多计算,设定CS_SAVEBITS是

为了在OpenGL窗口被遮盖后显现出来时,不产生WM_PAINT消息,用内存存储的图象来填充,从而用空间消耗换取计算时间。

----7.本程序中没有对OpenGL函数的出错情况作出处理。OpenGL出错后返回错误码,不会抛出异常;而且在某一个函数出错以后,后继函数也一般

不会出现异常,只是返回错误码,一不小心就可能忽略某些错误。而对每一个OpenGL函数都做出错与否的判断比较麻烦,所以编程序时对OpenGL的

函数应当非常小心。

----参考书籍:

----《OpenGLProgrammer'sGuide》SGIinc.

----《OpenGL三维图形程序设计》廖朵朵、张华军著,星球地图出版社

----《VisualC++5.0联机帮助》

----附程序:

----程序运行时必须确定OpenGL32.dll、glu.dll、glaux.dll在Windows的System目录下。如果找不到这些文件,可以从Windows95OSR2的机器上面

将这些文件拷贝过来即可。OpenGL运行不需要注册库信息。在VC的STUDIO中运行程序时,工程文件中必须加入OpenGL.H、glu.h、glaux.h以及

OpenGL.lib、glu.lib、glaux.lib,这些文件由VC自带。

----主窗口类定义(OpenGLWnd.h):

s#if !defined(AFX_OPENGLWND_H__3FB1AB28_0E70
_11D2_9ACA_48543300E17D__INCLUDED_)
#define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2
_9ACA_48543300E17D__INCLUDED_

#if _MSC_VER &amp;= 1000
#pragma once
#endif // _MSC_VER &amp;= 1000

#include &amp; afxwin.h &amp;
#include "SimpleGLApp.h"
#include "resource.h"
// OpenGLWnd.h : header file
//
///////////////////////////////////////
//////////////////////////////////////
// COpenGLWnd frame

class COpenGLWnd : public CFrameWnd
{
DECLARE_DYNCREATE(COpenGLWnd)
public:
COpenGLWnd();&amp;&amp;
// protected constructor used by dynamic creation
protected:
HGLRC m_hrc;
CClientDC *m_pDC;
// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COpenGLWnd)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT&amp; cs);
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~COpenGLWnd();

// Generated message map functions
//{{AFX_MSG(COpenGLWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////
//////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert
additional declarations immediately before the previous line.

#endif // !defined(AFX_OPENGLWND_H__3FB1AB28_
0E70_11D2_9ACA_48543300E17D__INCLUDED_)
主窗口类的实现(OpenGLWnd.cpp):
// OpenGLWnd.cpp : implementation file
//

#include "stdafx.h"
#include "OpenGLWnd.h"
#include "SimpleGLApp.h"
#include "gl\glu.h"
#include "gl\gl.h"
#include "gl\glaux.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////
//////////////////////////////////////
// COpenGLWnd

IMPLEMENT_DYNCREATE(COpenGLWnd, CFrameWnd)

COpenGLWnd::COpenGLWnd()
{
m_pDC = NULL;
m_hrc = 0;
LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS
,NULL,NULL );
}

COpenGLWnd::~COpenGLWnd()
{
}


BEGIN_MESSAGE_MAP(COpenGLWnd, CFrameWnd)
//{{AFX_MSG_MAP(COpenGLWnd)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()



BOOL COpenGLWnd::PreCreateWindow(CREATESTRUCT&amp; cs)
{
// TOD Add your specialized
code here and/or call the base class
cs.lpszClass = AfxRegisterWndClass( CS_DBLCLKS |
CS_HREDRAW |
CS_VREDRAW |
CS_SAVEBITS |
CS_NOCLOSE |
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;CS_OWNDC
,AfxGetApp( )-
&amp; LoadStandardCursor(IDC_ARROW), 0 ,
AfxGetApp( )- &amp;LoadStandardIcon(IDI_APPLICATION));
return CFrameWnd::PreCreateWindow(cs);
}


int COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

&amp;&amp;&amp;&amp;int pixelformat;

&amp;&amp;&amp;&amp;m_pDC = new CClientDC(this);//在客户区作图
ASSERT(m_pDC != NULL);

static PIXELFORMATDESCRIPTOR pfd =
{
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;sizeof(PIXELFORMATDESCRIPTOR),&amp;&amp;//固定值
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;1,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;//固定值
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;PFD_DRAW_TO_WINDOW |&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// support window
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;PFD_SUPPORT_OPENGL |&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// support OpenGL
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;PFD_TYPE_RGBA,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// RGBA模式,不用调色板
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;16,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;//程序在16位色彩下运行
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0, 0, 0, 0, 0, 0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// color bits ignored
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// no alpha buffer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// shift bit ignored
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// no accumulation buffer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0, 0, 0, 0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// accum bits ignored
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;32,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// 32-bit z-buffer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// no stencil buffer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// no auxiliary buffer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;PFD_MAIN_PLANE,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// main layer
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0,&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// reserved
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;0, 0, 0&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;// layer masks ignored
&amp;&amp;&amp;&amp;};


if ( (pixelformat = ChoosePixelFormat
(m_pDC- &amp;GetSafeHdc(), &amp;pfd)) == 0 )
&amp;&amp;&amp;&amp;{
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;MessageBox("在该DC上找不到与PFD接近的位图结构");
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;return -1;
&amp;&amp;&amp;&amp;}

if (SetPixelFormat(m_pDC- &amp;
GetSafeHdc(), pixelformat, &amp;pfd) == FALSE)
&amp;&amp;&amp;&amp;{
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;MessageBox("无法在该DC上设置位图结构");
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;return -1;
&amp;&amp;&amp;&amp;}
&amp;&amp;&amp;&amp;m_hrc = wglCreateContext(m_pDC- &amp;GetSafeHdc());
&amp;&amp;&amp;&amp;wglMakeCurrent(m_pDC- &amp;GetSafeHdc(), m_hrc);

&amp;&amp;&amp;&amp;glClearDepth(1.0f);
&amp;&amp;&amp;&amp;glEnable(GL_DEPTH_TEST);


&amp;&amp;&amp;&amp;glMatrixMode(GL_PROJECTION);
&amp;&amp;&amp;&amp;glLoadIdentity();
&amp;&amp;&amp;&amp;glMatrixMode(GL_MODELVIEW);

return 0;//OpenGL窗口构造成功
}

void COpenGLWnd::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);

// TOD Add your message handler code here
&amp;&amp;&amp;&amp;if(cy &amp; 0)
&amp;&amp;&amp;&amp;{&amp;&amp;&amp;&amp;
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;glViewport(0, 0, cx, cy);
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;glMatrixMode(GL_PROJECTION);
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;glLoadIdentity();
if (cx &amp; = cy)
&amp;&amp;&amp;&amp;glOrtho(-3.0,3.0,-3.0 * (Glfloat)cx/(Glfloat)cy,
3.0 * (Glfloat)cx/(Glfloat)cy,-3.0,3.0);
else
glOrtho(-3.0,3.0,-3.0 * (Glfloat)cy/(Glfloat)cx,
3.0 * (Glfloat)cy/(Glfloat)cx,-3.0,3.0);
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;glMatrixMode(GL_MODELVIEW);
&amp;&amp;&amp;&amp;}
}

void COpenGLWnd::OnDestroy()
{

CFrameWnd::OnDestroy();
&amp;&amp;&amp;&amp;::wglMakeCurrent(NULL,&amp;&amp;NULL);
&amp;&amp;&amp;&amp;if (m_hrc)
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;::wglDeleteContext(m_hrc);
if (m_pDC)
&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;delete m_pDC;
// TOD Add your message handler code here
}

BOOL COpenGLWnd::OnEraseBkgnd(CDC* pDC)
{
// TOD Add your message
handler code here and/or call default
return TRUE;
//return CFrameWnd::OnEraseBkgnd(pDC);
}

void COpenGLWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting

Glfloat light_position[]={2.0f,0.0f,4.0f,0.0f};

// TOD Add your message handler code here

&amp;&amp;&amp;&amp;glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
&amp;&amp;&amp;&amp;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

&amp;&amp;&amp;&amp;glPushMatrix();

&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;glTranslatef(0.0f, 0.0f, -2.0f);
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
auxSolidSphere(1.0);

&amp;&amp;&amp;&amp;glPopMatrix();

&amp;&amp;&amp;&amp;glFinish();

// Do not call CFrameWnd::OnPaint() for painting messages
}
应用程序类的定义(SimpleGLApp.h):
#if !defined(AFX_SIMPLEGLAPP_H__3FB1AB29
_0E70_11D2_9ACA_48543300E17D__INCLUDED_)
#define AFX_SIMPLEGLAPP_H__3FB1AB29_0E70
_11D2_9ACA_48543300E17D__INCLUDED_

#if _MSC_VER &amp;= 1000
#pragma once
#endif // _MSC_VER &amp;= 1000
// SimpleGLApp.h : header file
//
#include &amp; afxwin.h &amp;
#include "OpenGLWnd.h"
#include "resource.h"

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp thread

class CSimpleGLApp : public CWinApp
{
DECLARE_DYNCREATE(CSimpleGLApp)
public:
CSimpleGLApp();
&amp;&amp;&amp;// protected constructor used by dynamic creation

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSimpleGLApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CSimpleGLApp();

// Generated message map functions
//{{AFX_MSG(CSimpleGLApp)
afx_msg void OnAppExit();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

///////////////////////////////////////
//////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert
additional declarations
immediately before the previous line.

#endif // !defined(AFX_SIMPLEGLAPP_H__3FB1AB29_
0E70_11D2_9ACA_48543300E17D__INCLUDED_)
应用程序类的实现(SimpleGLApp.cpp):
// SimpleGLApp.cpp : implementation file
//

#include "stdafx.h"
#include "SimpleGLApp.h"
#include "OpenGLWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp

IMPLEMENT_DYNCREATE(CSimpleGLApp, CWinApp)

CSimpleGLApp::CSimpleGLApp()
{
}

CSimpleGLApp::~CSimpleGLApp()
{
}

BOOL CSimpleGLApp::InitInstance()
{
// TOD&amp;&amp;perform and per-thread initialization here
m_pMainWnd = new COpenGLWnd();
m_pMainWnd- &amp;ShowWindow(m_nCmdShow);
m_pMainWnd- &amp;UpdateWindow();
return TRUE;
}

int CSimpleGLApp::ExitInstance()
{
return CWinApp::ExitInstance();
}

BEGIN_MESSAGE_MAP(CSimpleGLApp, CWinApp)
//{{AFX_MSG_MAP(CSimpleGLApp)
ON_COMMAND(ID_APP_EXIT, OnAppExit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////
//////////////////////////////////////
// CSimpleGLApp message handlers
void CSimpleGLApp::OnAppExit()
{
// TOD Add your command handler code here
CWinApp::OnAppExit();
}

CSimpleGLApp SimpleGLApp;</P>

xShandow 发表于 2004-11-16 19:05

<P>你们都知道我在看OpenGL啊.</P>
页: [1]
查看完整版本: [分享]OPENGL