⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter4.cpp

📁 一本关于OPenGL的很好的电子书
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
 chapter4.cpp
 
 This demo program displays a number of OpenGL primitive types, as well as
 how changing certain parameters can alter how the primitive is drawn.

 To change the primitive being displayed and the properties applied to it,
 use the following controls:

         Key  Action
         ---  ------
          1   Draw points
          2   Draw lines
          3   Draw triangles
          4   Draw a triangle strip
          5   Draw a triangle fan
          6   Draw quads
          7   Draw a polygon
          a   Toggle antialiasing
          s   Toggle stippling
          p   Rotate through polygon modes

  
 Author   :   Dave Astle
 Date     :   10/23/2000

 Written for OpenGL Game Programming
*****************************************************************************/


/********************************* Includes *********************************/
#define WIN32_LEAN_AND_MEAN				// trim the excess fat from Windows


#include <windows.h>					// standard Windows app include
#include <winuser.h>          // Windows constants
#include <gl/gl.h>						// standard OpenGL include
#include <gl/glu.h>						// OpenGL utilties
#include <stdlib.h>           // for random numbers


/*************************** Macros and Constants ***************************/
#define WND_CLASS_NAME  "OpenGL Window Class"


/******************************** Data types ********************************/
// used to track which primitive we're drawing
enum primtypes_t
{
  PT_POINT,
  PT_LINE,
  PT_TRIANGLE,
  PT_TRIANGLE_STRIP,
  PT_TRIANGLE_FAN,
  PT_QUAD,
  PT_POLYGON
};


/********************************* Globals **********************************/
// Windows variables
HDC       g_hdc;								  // global device context
HGLRC     g_hrc;                  // global rendering context
BOOL      g_isFullscreen = TRUE;  // toggles fullscreen and windowed display
BOOL      g_isActive = TRUE;      // false if window is minimized
HWND      g_hwnd = NULL;          // handle of our window  
HINSTANCE g_hInstance;            // application instance

// the current primitive
primtypes_t g_currentPrimitive = PT_POINT;

// used to hold data retrieved from OpenGL
GLfloat g_pointSize = 1.0;
GLfloat g_pointSizeStep;
GLfloat g_pointSizeMinMax[2];
GLfloat g_lineWidth = 1.0;
GLfloat g_lineWidthStep;
GLfloat g_lineWidthMinMax[2];

// the size of the window
GLuint g_width, g_height;


/******************************** Prototypes ********************************/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
BOOL SetupWindow(char *title, int width, int height, int bits, bool isFullscreen);
BOOL InitializeScene();
GLvoid ResizeScene(GLsizei width, GLsizei height);
BOOL DisplayScene();
BOOL KillWindow();


/****************************************************************************
 WinMain()

 Main Windows entry point. Creates a window, sets up OpenGL, and enters an
 event loop.
*****************************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
  MSG   msg;       // message
  BOOL  isDone;    // flag saying when our app is complete

  // create our window and set up OpenGL
  SetupWindow("Primitives Demo", 800, 600, 32, TRUE);

  // intialize the loop condition variable
  isDone = FALSE;

  // main message loop
  while (!isDone)
  {
    // get a message if one is ready
    if(PeekMessage(&msg, g_hwnd, NULL, NULL, PM_REMOVE))
    {
      // look for a quit message, in which case, we're done
      if (msg.message == WM_QUIT)
      {
        isDone = TRUE;
      }
      else
      {
        // translate and dispatch to event queue
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
    }

    // render the current scene
    DisplayScene();

    // bring backbuffer to foreground
    SwapBuffers(g_hdc);
  }

  // cleanup
  KillWindow();

  return msg.wParam;
} // end WinMain()


/****************************************************************************
 WndProc

 Windows message handler
*****************************************************************************/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  static BOOL   antialias = false;    // controls antialiasing
  static GLenum polyMode  = GL_FILL;  // controls the polygon mode
  static BOOL   stipple   = false;    // controls stippling

  switch(message)
  {
  case WM_ACTIVATE:  // watch for the window being minimized and restored
    {
      if (!HIWORD(wParam))
      {
        // program was restored or maximized
        g_isActive = TRUE;
      }
      else
      {
        // program was minimized
        g_isActive=FALSE;
      }

      return 0;
    }
  case WM_SYSCOMMAND:  // look for screensavers and powersave mode
    {
      switch (wParam)
			{
				case SC_SCREENSAVE:     // screensaver trying to start
				case SC_MONITORPOWER:   // monitor going to powersave mode
          // returning 0 prevents either from happening
  				return 0;
        default:
          break;
      }
    } break;
  case WM_CLOSE:    // window is being closed
    {
      // send WM_QUIT to message queue
      PostQuitMessage(0);
      return 0;
    }
  case WM_SIZE:
    {
      // update perspective with new width and height
      ResizeScene(LOWORD(lParam), HIWORD(lParam));
      return 0;
    }
  case WM_CHAR:
    {
      switch (toupper(wParam))
      {
      case VK_ESCAPE:
        {
          // send WM_QUIT to message queue
          PostQuitMessage(0);
          return 0;
        }
      case 'A':   // toggle antialiasing
        {
          antialias = !antialias;

          // if antialiasing was just turned on, enable it
          if (antialias)
          {
            glEnable(GL_POINT_SMOOTH);
            glEnable(GL_LINE_SMOOTH);
            glEnable(GL_POLYGON_SMOOTH);
            glEnable(GL_BLEND);
          }
          // otherwise, disable it
          else
          {
            glDisable(GL_POINT_SMOOTH);
            glDisable(GL_LINE_SMOOTH);
            glDisable(GL_POLYGON_SMOOTH);
            glDisable(GL_BLEND);
          }
          return 0;
        }
      case 'S':   // toggle stippling
        {
          stipple = !stipple;

          // if stippling was just turned on, enable it
          if (stipple)
          {
            glEnable(GL_LINE_STIPPLE);
            glEnable(GL_POLYGON_STIPPLE);
          }
          // otherwise, disable it
          else
          {
            glDisable(GL_LINE_STIPPLE);
            glDisable(GL_POLYGON_STIPPLE);
          }
          return 0;
        }
      case 'P':   // rotate polygon mode
        {
          // go to the next mode
          polyMode++;

          // wrap around if we need to
          if (polyMode > GL_FILL)
            polyMode = GL_POINT;

          // select the new polygon mode
          glPolygonMode(GL_FRONT_AND_BACK, polyMode);
        }
      case '+':   // increase sizes
        {
          // increase point sizes (if we're not already at the max)
          if (g_pointSize < g_pointSizeMinMax[1])
            g_pointSize += g_pointSizeStep;

          glPointSize(g_pointSize);

          // increase line widths (if we're not already at the max)
          if (g_lineWidth < g_lineWidthMinMax[1])
            g_lineWidth += g_lineWidthStep;

          glLineWidth(g_lineWidth);

          return 0;
        }
      case '-':   // decrease sizes
        {
          // decrease point sizes (if we're not already at the min)
          if (g_pointSize > g_pointSizeMinMax[0])
            g_pointSize -= g_pointSizeStep;

          glPointSize(g_pointSize);

          // decrease line widths (if we're not already at the min)
          if (g_lineWidth > g_lineWidthMinMax[0])
            g_lineWidth -= g_lineWidthStep;

          glLineWidth(g_lineWidth);

          return 0;
        }
      case '1':   // select points
        {
          g_currentPrimitive = PT_POINT;
          return 0;
        }
      case '2':   // select lines
        {
          g_currentPrimitive = PT_LINE;
          return 0;
        }
      case '3':   // select triangles
        {
          g_currentPrimitive = PT_TRIANGLE;
          return 0;
        }
      case '4':   // select triangle strip
        {
          g_currentPrimitive = PT_TRIANGLE_STRIP;
          return 0;
        }
      case '5':   // select triangle fan
        {
          g_currentPrimitive = PT_TRIANGLE_FAN;
          return 0;
        }
      case '6':   // select quads
        {
          g_currentPrimitive = PT_QUAD;
          return 0;
        }
      case '7':   // select polygon
        {
          g_currentPrimitive = PT_POLYGON;
          return 0;   // select 
        }
      default:
        break;
      };
    } break;

  default:
    break;
  }

  // pass any remaining messages up to the default handler
  return (DefWindowProc(hwnd, message, wParam, lParam));
} // end WndProc()


/****************************************************************************
 SetupWindow()

 Creates a window and the device and rendering contexts for it.
*****************************************************************************/
BOOL SetupWindow(char *title, int width, int height, int bits, bool isFullscreen)
{
  // set the global flag
  g_isFullscreen = isFullscreen;

  // get our instance handle
  g_hInstance	= GetModuleHandle(NULL);

  WNDCLASSEX  wc;    // window class

  // fill out the window class structure
  wc.cbSize         = sizeof(WNDCLASSEX);
  wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  wc.lpfnWndProc    = WndProc;
  wc.cbClsExtra     = 0;
  wc.cbWndExtra     = 0;
  wc.hInstance      = g_hInstance;
  wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);	// default icon
  wc.hIconSm        = LoadIcon(NULL, IDI_WINLOGO);		  // windows logo small icon
  wc.hCursor        = LoadCursor(NULL, IDC_ARROW);		  // default arrow
  wc.hbrBackground  = NULL; //(HBRUSH) GetStockObject(BLACK_BRUSH);   // black background
  wc.lpszMenuName   = NULL;     // no menu
  wc.lpszClassName  = WND_CLASS_NAME;
  
  // register the windows class
  if (!RegisterClassEx(&wc))
  {
    MessageBox(NULL,"Unable to register the window class", "Error", MB_OK | MB_ICONEXCLAMATION);
    return FALSE;							// Exit And Return FALSE
  }

  // if we're in fullscreen mode, set the display up for it
  if (g_isFullscreen)
  {
    // set up the device mode structure
    DEVMODE screenSettings;
    memset(&screenSettings,0,sizeof(screenSettings));

    screenSettings.dmSize       = sizeof(screenSettings);	
    screenSettings.dmPelsWidth  = width;			// screen width
    screenSettings.dmPelsHeight = height;			// screen height
    screenSettings.dmBitsPerPel = bits;				// bits per pixel
    screenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

    // attempt to switch to the resolution and bit depth we've selected
    if (ChangeDisplaySettings(&screenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
    {
      // if we can't get fullscreen, let them choose to quit or try windowed mode
      if (MessageBox(NULL, "Cannot run in the fullscreen mode at the selected resolution\n"
                           "on your video card. Try windowed mode instead?",
                           "OpenGL Game Programming",
                           MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
      {
        g_isFullscreen = FALSE;	
      }
      else
			{
				return FALSE;
			}
    }
  }

	DWORD dwExStyle;
	DWORD dwStyle;

  // if we're still in fullscreen mode, set the window style appropriately
	if (g_isFullscreen)
	{
		dwExStyle = WS_EX_APPWINDOW;
		dwStyle = WS_POPUP;						// simple window with no borders or title bar
		ShowCursor(FALSE);            // hide the cursor for now
	}
	else
	{
		dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
		dwStyle = WS_OVERLAPPEDWINDOW;
	}

  // set up the window we're rendering to so that the top left corner is at (0,0)
  // and the bottom right corner is (height,width)
  RECT  windowRect;
  windowRect.left = 0;
  windowRect.right = (LONG) width;
  windowRect.top = 0;
  windowRect.bottom = (LONG) height;

  // change the size of the rect to account for borders, etc. set by the style
  AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);

  // class registered, so now create our window
  g_hwnd = CreateWindowEx(dwExStyle,          // extended style
                          WND_CLASS_NAME,     // class name
                          title,              // app name
                          dwStyle |           // window style
                          WS_CLIPCHILDREN |   // required for
                          WS_CLIPSIBLINGS,    // using OpenGL
                          0, 0,               // x,y coordinate
                          windowRect.right - windowRect.left, // width
                          windowRect.bottom - windowRect.top, // height
                          NULL,               // handle to parent
                          NULL,               // handle to menu

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -