outdated: 24. Tokens, Extensions, Scissor Testing And TGA Loading

这一篇主要说的是,怎样实现在窗口中裁剪一个小的视图窗口(即glScissor()函数)?以及对glGetString()函数的应用。

在本文中,用到的贴图材质是TGA格式图片,相对于JPG格式,会更加清晰,因使用不失真的压缩。不了解TGA格式图片的可以看看这篇。基于对TGA格式的了解,具有独有的一个8位的Alpha通道。在其代码中,在24位和32位之间来转换,差的8位即为Alpha。所以,一开始会有一个变量type,默认为32位---GL_RGBA。支持扩展是很好的一个特性,使得DrawGLScene()函数中的glGetString()函数可以使用。

LoadTGA()函数中,只会加载24位和32位的TGA,首先第一个变量,

GLubyte TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

在与所读文件前12个字节比较后,确保是Targa文件。

下一个变量,

GLubyte header[6];

读取宽(位置)、高(位置)和每像素值的比特位,共6字节。

glPrint函数中的glScalef()函数用来设置字体的形变。

DrawGLScene()函数中的glGetString()函数,其参数有四个,依次为渲染器,渲染器出处,渲染器版本,支持的扩展。

  Meaning
GL_VENDOR

Returns the company responsible for this OpenGL implementation. This name does not change from release to release.

GL_RENDERER

Returns the name of the renderer. This name is typically specific to a particular configuration of a hardware platform. It does not change from release to release.

GL_VERSION

Returns a version or release number.

GL_EXTENSIONS

Returns a space-separated list of supported extensions to OpenGL.

glScissor()函数,设置一个小窗口,当然都是在windows窗体的限制内。

void WINAPI glScissor(
   GLint   x,
   GLint   y,
   GLsizei width,
   GLsizei height
);

下面为代码,同样修改部分位于双行星号内。

  1 #include <windows.h>
  2 #include <stdarg.h>
  3 #include <stdio.h>
  4 #include <math.h>
  5 #include <string.h>
  6 #include <gl/glew.h>
  7 #include <gl/glut.h>
  8 #include <GL/GLUAX.H>
  9 #include <GL/glext.h>
 10 #pragma comment(lib, "legacy_stdio_definitions.lib")
 11
 12 /*
 13 *  Every OpenGL program is linked to a Rendering Context.
 14 *  A Rendering Context is what links OpenGL calls to the Device Context.
 15 *  In order for your program to draw to a Window you need to create a Device Context.
 16 *  The DC connects the Window to the GDI (Graphics Device Interface).
 17 */
 18
 19 HGLRC     hRC = NULL;         // Permanent rendering context
 20 HDC       hDC = NULL;         // Private GDI device context
 21 HWND      hWnd = NULL;        // Holds our window handle
 22 HINSTANCE hInstance;          // Holds the instance of the application
 23
 24 /*
 25 *  It‘s important to make this global so that each procedure knows if
 26 *  the program is running in fullscreen mode or not.
 27 */
 28
 29 bool keys[256];         // Array used for the keyboard routine
 30 bool active = TRUE;     // Window active flag set to TRUE by default
 31 bool fullscreen = TRUE; // Fullscreen flag set to fullscreen mode by default
 32 /******************************************************************************************************************************************/
 33 /******************************************************************************************************************************************/
 34 int scroll;             // Used for scrolling the screen
 35 int maxtokens;          // Keeps track of the number of extensions supported
 36 int swidth;             // Scissor width
 37 int sheight;            // Scissor height
 38
 39 GLuint base;            // Base display list for the font
 40
 41 typedef struct {
 42     GLubyte* imageData;
 43     GLuint bpp;        // Image color depth in bits per pixel
 44     GLuint width;
 45     GLuint height;
 46     GLuint texID;      // Texture ID used to select a texture
 47 } TextureImage;
 48
 49 TextureImage texture[1];
 50
 51 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration for WndProc
 52
 53 bool LoadTGA(TextureImage* texture, char* filename)                        // Loads a TGA filr into memory
 54 {
 55     GLubyte TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };        // Uncompressed TGA
 56     GLubyte TGAcompare[12];       // Used to compare TGA header
 57     GLubyte header[6];            // First 6 useful bytes from the header
 58     GLuint bytesPerpixel;         // Holds number of byte per pixel used in the TGA file
 59
 60     GLuint imageSize;             // Used to store the image size when setting aside ram
 61     GLuint temp;                  // Temporary variable
 62     GLuint type = GL_RGBA;        // Set the default GL mode to RGBA (32 bpp)
 63
 64     FILE* file = fopen(filename, "rb");
 65
 66     if ((file == NULL) ||         // Dose file even exits
 67         (fread(TGAcompare, 1, sizeof(TGAcompare), file) != sizeof(TGAcompare)) || // Are there 12 bytes to read
 68             (memcmp(TGAheader, TGAcompare, sizeof(TGAheader)) != 0) || // Dose the header match what we want
 69             (fread(header, 1, sizeof(header), file) != sizeof(header))) // If so read next 6 header bytes
 70     {
 71         if (file == NULL) {
 72             return false;
 73         }
 74         else {
 75             fclose(file);
 76             return false;
 77         }
 78     }
 79     texture->width = header[1] * 256 + header[0];   // Determine the TGA width (highbyte * 256 + lowbyte)
 80     texture->height = header[3] * 256 + header[2];  // Determine the TGA height (highbyte * 256 + lowbyte)
 81
 82     if (texture->width <= 0 || texture->height <= 0 || (header[4] != 24 && header[4] != 32)) {
 83         fclose(file);
 84         return false;
 85     }
 86
 87     texture->bpp = header[4];                       // Grab the TGA‘s bits per pixel (24 or 32)
 88     bytesPerpixel = texture->bpp / 8;               // Divide by 8 to get the bytes per pixel
 89     // Calculate the memory required for the TGA data
 90     imageSize = texture->width * texture->height * bytesPerpixel;
 91
 92     texture->imageData = (GLubyte*)malloc(imageSize);     // Resever memory to hold the TGA data
 93
 94     if (texture->imageData == NULL ||
 95         fread(texture->imageData, 1, imageSize, file) != imageSize)
 96     {
 97         if (texture->imageData == NULL) {
 98             free(texture->imageData);
 99         }
100         fclose(file);
101         return false;
102     }
103
104     for (GLuint i = 0; i < int(imageSize); i += bytesPerpixel) {
105         temp = texture->imageData[i];        // Swap the 1st and 3rd bytes (R and B)
106         texture->imageData[i] = texture->imageData[i + 2];
107         texture->imageData[i + 2] = temp;
108     }
109     fclose(file);
110
111     // Build a texture from the data
112     glGenTextures(1, &texture[0].texID);
113
114     glBindTexture(GL_TEXTURE_2D, texture[0].texID);
115     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117
118     // The TGA was 24 bit, the type will be GL_RGB,  the TGA was 32 bit, the type would be GL_RGBA
119     if (texture[0].bpp == 24) {
120         type = GL_RGB;
121     }
122
123     glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type,
124         GL_UNSIGNED_BYTE, texture[0].imageData);
125     return true;
126 }
127
128 GLvoid BuildFont(GLvoid)
129 {
130     base = glGenLists(256);
131     glBindTexture(GL_TEXTURE_2D, texture[0].texID);
132
133     for (int loop = 0; loop < 256; ++loop) {
134         float cx = float(loop % 16) / 16.0f;          // X position of current character
135         float cy = float(loop / 16) / 16.0f;          // Y position of current character
136         glNewList(base + loop, GL_COMPILE);
137             glBegin(GL_QUADS);
138                 glTexCoord2f(cx, 1.0f - cy - 0.0625f);        // Texture coord
139                 glVertex2d(0, 16);                            // Vertex coord
140                 glTexCoord2f(cx + 0.0625f, 1.0f - cy - 0.0625f);
141                 glVertex2i(16, 16);
142                 glTexCoord2f(cx + 0.0625f, 1.0f - cy - 0.001f);
143                 glVertex2i(16, 0);
144                 glTexCoord2f(cx, 1.0f - cy - 0.001f);
145                 glVertex2i(0, 0);
146             glEnd();
147             glTranslated(14, 0, 0);
148         glEndList();
149     }
150 }
151
152 GLvoid KillFont(GLvoid)
153 {
154     glDeleteLists(base, 256);
155 }
156
157 GLvoid glPrint(GLint x, GLint y, int set, const char* fmt, ...)
158 {
159     char text[1024];
160     va_list ap;                 // Pointer to list of arguments
161
162     if (fmt == NULL) {
163         return;
164     }
165
166     va_start(ap, fmt);          // Parses the string for variables
167         vsprintf(text, fmt, ap);    // And converts symbols to actual
168     va_end(ap);                 // Result are stored in text
169
170     if (set > 1) {
171         set = 1;
172     }
173     glEnable(GL_TEXTURE_2D);
174     glLoadIdentity();
175     glTranslated(x, y, 0);
176     glListBase(base - 32 + (128 * set));              // Choose the font set (0 or 1)
177
178     glScalef(1.0f, 2.0f, 1.0f);                       // Make the text 2X taller
179
180     glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);   // Write the text to the screen
181
182     glDisable(GL_TEXTURE_2D);
183 }
184
185 GLvoid ReSizeGLScene(GLsizei width, GLsizei height)   // Resize and initialize the GL window
186 {
187     swidth = width;                                   // Set scissor width to window width
188     sheight = height;
189
190     if (height == 0) {                                // Prevent a divide by zero by
191         height = 1;                                   // Making height equal one
192     }
193
194     glViewport(0, 0, width, height);                  // Reset the current viewport
195
196     /*
197      *  The following lines set the screen up for a perspective view.
198      *  Meaning things in the distance get smaller. This creates a realistic looking scene.
199      *  The perspective is calculated with a 45 degree viewing angle based on
200      *  the windows width and height. The 0.1f, 100.0f is the starting point and
201      *  ending point for how deep we can draw into the screen.
202      *
203      *  The projection matrix is responsible for adding perspective to our scene.
204      *  glLoadIdentity() restores the selected matrix to it‘s original state.
205      *  The modelview matrix is where our object information is stored.
206      *   Lastly we reset the modelview matrix.
207      */
208
209     glMatrixMode(GL_PROJECTION);                      // Select the projection matrix
210     glLoadIdentity();                                 // Reset the projection matrix
211
212                                                       // Calculate the aspect ratio of the window
213 //    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
214     glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f);  // Create orhto 640X480 view (0, 0, at the top)
215
216     glMatrixMode(GL_MODELVIEW);                       // Seclet the modelview matrix
217     glLoadIdentity();                                 // Reset the modelview matrix
218 }
219
220 int InitGL(GLvoid)                                    // All setup for OpenGL goes here
221 {
222     if (!LoadTGA(&texture[0], "Font.tga")) {
223         return FALSE;
224     }
225
226     BuildFont();
227
228     glShadeModel(GL_SMOOTH);                          // Enables smooth shading
229     glClearColor(0.0f, 0.0f, 0.0f, 0.5f);             // Black background
230
231     glClearDepth(1.0f);                               // Depth buffer setup
232
233     glBindTexture(GL_TEXTURE_2D, texture[0].texID);
234
235     return TRUE;
236 }
237 /*
238  *  For now all we will do is clear the screen to the color we previously decided on,
239  *  clear the depth buffer and reset the scene. We wont draw anything yet.
240  */
241 int DrawGLScene(GLvoid)                                  // Here‘s where we do all the drawing
242 {
243     char* token;                                         // Storage for our token
244     int cnt = 0;                                         // Loacl counter variable
245
246     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
247
248     glColor3f(1.0f, 0.5f, 0.5f);
249     glPrint(50, 16, 1, "Renderer");
250     glPrint(80, 48, 1, "Vendor");
251     glPrint(66, 80, 1, "Version");
252
253     glColor3f(1.0f, 0.7f, 0.4f);
254     glPrint(200, 16, 1, (char*)glGetString(GL_RENDERER));
255     glPrint(200, 48, 1, (char*)glGetString(GL_VENDOR));
256     glPrint(200, 80, 1, (char*)glGetString(GL_VERSION));
257
258     glColor3f(0.5f, 0.5f, 1.0f);
259     glPrint(250, 432, 1, "OpenGl");
260
261     glLoadIdentity();
262     glColor3f(1.0f, 1.0f, 1.0f);
263     glBegin(GL_LINE_STRIP);
264         glVertex2d(639, 417);
265         glVertex2d(0, 417);
266         glVertex2d(0, 480);
267         glVertex2d(639, 480);
268         glVertex2d(639, 128);
269     glEnd();
270     glBegin(GL_LINE_STRIP);
271         glVertex2d(0, 128);
272         glVertex2d(639, 128);
273         glVertex2d(639, 1);
274         glVertex2d(0, 1);
275         glVertex2d(0, 417);
276     glEnd();
277
278     glScissor(1, int(0.135416f * sheight), swidth - 2, int(0.597916f * sheight)); // Define scissor region
279     glEnable(GL_SCISSOR_TEST);
280     // Allocate memory for our extension string
281     char* text = (char*)malloc(strlen((char*)glGetString(GL_EXTENSIONS)) + 1);
282     strcpy(text, (char*)glGetString(GL_EXTENSIONS));  // Grab the extension list, store in text
283
284     token = strtok(text, " ");
285     while (token != NULL) {
286         cnt++;
287         if (cnt > maxtokens) {
288             maxtokens = cnt;
289         }
290
291         glColor3f(0.5f, 1.0f, 0.5f);
292         glPrint(0, 96 + (cnt * 32) - scroll, 0, "%i", cnt);    // Print the current extension number
293
294         glColor3f(1.0f, 1.0f, 0.5f);
295         glPrint(50, 96 + (cnt * 32) - scroll, 0, token);       // Print the current token extension name
296
297         token = strtok(NULL, " ");                // Serch for the next token
298     }
299
300     glDisable(GL_SCISSOR_TEST);
301     free(text);
302
303     glFlush();
304     return true;
305 }
306 /******************************************************************************************************************************************/
307 /******************************************************************************************************************************************/
308 /*
309  *  The job of KillGLWindow() is to release the Rendering Context,
310  *  the Device Context and finally the Window Handle.
311  */
312
313 GLvoid KillGLWindow(GLvoid)                              // Properly kill the window
314 {
315     if (fullscreen) {                                    // Are we in fullscreen mode
316
317         /*
318          *  We use ChangeDisplaySettings(NULL,0) to return us to our original desktop.
319          *  After we‘ve switched back to the desktop we make the cursor visible again.
320          */
321
322         ChangeDisplaySettings(NULL, 0);                  // if so switch back to the desktop
323         ShowCursor(TRUE);                                // Show mouse pointer
324     }
325
326     if (hRC) {                                           // Do we have a rendering context
327         if (!wglMakeCurrent(NULL, NULL)) {                // Are we able to release the DC and RC contexts
328             MessageBox(NULL, "Release of DC and RC failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
329         }
330
331         if (!wglDeleteContext(hRC)) {                     // Are we able to delete the RC
332             MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
333             hRC = NULL;                                  // Set RC to NULL
334         }
335
336         if (hDC && !ReleaseDC(hWnd, hDC)) {              // Are we able to release the DC
337             MessageBox(NULL, "Release device context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
338             hDC = NULL;                                  // Set DC to NULL
339         }
340         if (hWnd && !DestroyWindow(hWnd)) {              // Are we able to destroy the window
341             MessageBox(NULL, "Could not release hWnd.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
342             hWnd = NULL;                                 // Set hWnd to NULL
343         }
344
345         if (!UnregisterClass("OpenGL", hInstance)) {     // Are we able to unregister class
346             MessageBox(NULL, "Could not register class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
347             hInstance = NULL;                            // Set hInstance to NULL
348         }
349     }
350 /******************************************************************************************************************************************/
351 /******************************************************************************************************************************************/
352     KillFont();
353 /******************************************************************************************************************************************/
354 /******************************************************************************************************************************************/
355 }
356
357 /*
358  * The next section of code creates our OpenGL Window.
359  */
360
361 BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
362 {
363     /*
364      * Find  a pixel format that matches the one we want
365      */
366     GLuint PixelFormat;                                  // Holds the result after serching for a match
367
368     /*
369      * Before you create a window, you MUST register a Class for the window
370      */
371     WNDCLASS wc;                                         // Windows class structure
372
373     /*
374      *  dwExStyle and dwStyle will store the Extended and normal Window Style Information.
375     */
376     DWORD dwExStyle;                                     // Window extend style
377     DWORD dwStyle;                                       // Window style
378
379     RECT WindowRect;                                     // Grabs rectangle upper left/lower right values
380     WindowRect.left = (long)0;                           // Set left value to 0
381     WindowRect.right = (long)width;                      // Set right value to requested width
382     WindowRect.top = (long)0;                            // Set top value to 0
383     WindowRect.bottom = (long)height;                    // Set bottom value to requested height
384
385     fullscreen = fullscreenflag;                         // Set the global fullscreen flag
386
387     /*
388      *  The style CS_HREDRAW and CS_VREDRAW force the Window to redraw whenever it is resized.
389      *  CS_OWNDC creates a private DC for the Window. Meaning the DC is not shared across applications.
390      *  WndProc is the procedure that watches for messages in our program.
391      *  No extra Window data is used so we zero the two fields. Then we set the instance.
392      *  Next we set hIcon to NULL meaning we don‘t want an ICON in the Window,
393      *  and for a mouse pointer we use the standard arrow. The background color doesn‘t matter
394      *  (we set that in GL). We don‘t want a menu in this Window so we set it to NULL,
395      *  and the class name can be any name you want. I‘ll use "OpenGL" for simplicity.
396      */
397     hInstance = GetModuleHandle(NULL);                   // Grab an instance for our window
398     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;       // Redraw on move, and own DC for window
399     wc.lpfnWndProc = (WNDPROC)WndProc;                   // WndProc handles message
400     wc.cbClsExtra = 0;                                   // No extra window date
401     wc.cbWndExtra = 0;                                   // No extra window date
402     wc.hInstance = hInstance;                            // set the instance
403     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);              // Load the default icon
404     wc.hCursor = LoadCursor(NULL, IDC_ARROW);            // Load the arrow pointer
405     wc.hbrBackground = NULL;                             // No background requried for GL
406     wc.lpszMenuName = NULL;                              // We don‘t want a menu
407     wc.lpszClassName = "OpenGL";                         // set the class name
408
409     if (!RegisterClass(&wc)) {                           // Attempt to register the window class
410         MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
411         return FALSE;                                    // Exit and return false
412     }
413
414     if (fullscreen) {                                    // attempt fullsreen model
415
416         /*
417         T*  here are a few very important things you should keep in mind when switching to full screen mode.
418          *  Make sure the width and height that you use in fullscreen mode is the same as
419          *  the width and height you plan to use for your window, and most importantly,
420          *  set fullscreen mode BEFORE you create your window.
421          */
422         DEVMODE dmScreenSettings;                        // Device mode
423         memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); // Make sure memory‘s cleared
424         dmScreenSettings.dmSize = sizeof(dmScreenSettings);     // Size of devmode structure
425         dmScreenSettings.dmPelsWidth = width;            // Select window width
426         dmScreenSettings.dmPelsHeight = height;          // Select window height
427         dmScreenSettings.dmBitsPerPel = bits;            // Select bits per pixel
428         dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
429
430         /*
431          *  In the line below ChangeDisplaySettings tries to switch to a mode that matches
432          *  what we stored in dmScreenSettings. I use the parameter CDS_FULLSCREEN when switching modes,
433          *  because it‘s supposed to remove the start bar at the bottom of the screen,
434          *  plus it doesn‘t move or resize the windows on your desktop when you switch to
435          *  fullscreen mode and back.
436          */
437         //Try to set selected mode and get results. Note: CDS_FULLSCREEN gets rid of start bar
438         if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
439             //If the mode fails, offer two options. Quit or run in a window
440             if (MessageBox(NULL, "The requested fullscreen mode is not supported by\n your video card. Use"
441                 "windowed mode instead?", "GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
442             {
443                 fullscreen = FALSE;                       // Select windowed mode (fullscreen=FLASE)
444             }
445             else {
446                 // Pop up a message box letting user know the programe is closing.
447                 MessageBox(NULL, "Program will now close.", "ERROR", MB_OK | MB_ICONSTOP);
448                 return FALSE;                             // Exit and return FALSE
449             }
450         }
451     }
452
453     if (fullscreen) {                                     // Are we still in fullscreen mode
454
455         /*
456          *  If we are still in fullscreen mode we‘ll set the extended style to WS_EX_APPWINDOW,
457          *  which force a top level window down to the taskbar once our window is visible.
458          *  For the window style we‘ll create a WS_POPUP window.
459          *  This type of window has no border around it, making it perfect for fullscreen mode.
460
461          *  Finally, we disable the mouse pointer. If your program is not interactive,
462          *  it‘s usually nice to disable the mouse pointer when in fullscreen mode. It‘s up to you though.
463          */
464         dwExStyle = WS_EX_APPWINDOW;                      // Window extended style
465         dwStyle = WS_POPUP;                               // Window style
466         ShowCursor(FALSE);                                // Hide mosue pointer
467     }
468     else {
469
470         /*
471          *  If we‘re using a window instead of fullscreen mode,
472          *  we‘ll add WS_EX_WINDOWEDGE to the extended style. This gives the window a more 3D look.
473          *  For style we‘ll use WS_OVERLAPPEDWINDOW instead of WS_POPUP.
474          *  WS_OVERLAPPEDWINDOW creates a window with a title bar, sizing border,
475          *  window menu, and minimize / maximize buttons.
476          */
477         dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;   // Window extended style
478         dwStyle = WS_OVERLAPPEDWINDOW;                    // Window style
479     }
480
481     /*
482      *  By using the AdjustWindowRectEx command none of our OpenGL scene will be covered up by the borders,
483      *  instead, the window will be made larger to account for the pixels needed to draw the window border.
484      *  In fullscreen mode, this command has no effect.
485      */
486     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);  // Adjust window to true resqusted
487
488     /*
489      *  WS_CLIPSIBLINGS and WS_CLIPCHILDREN are both REQUIRED for OpenGL to work properly.
490      *  These styles prevent other windows from drawing over or into our OpenGL Window.
491      */
492     if (!(hWnd = CreateWindowEx(dwExStyle,                // Extended style for the window
493         "OpenGL",                                         // Class name
494         title,                                            // Window title
495         WS_CLIPSIBLINGS |                                 // Requried window style
496         WS_CLIPCHILDREN |                                 // Requried window style
497         dwStyle,                                          // Select window style
498         0, 0,                                             // Window position
499         WindowRect.right - WindowRect.left,               // Calculate adjusted window width
500         WindowRect.bottom - WindowRect.top,               // Calculate adjusted window height
501         NULL,                                             // No parent window
502         NULL,                                             // No menu
503         hInstance,                                        // Instance
504         NULL)))                                           // Don‘t pass anything to WM_CREATE
505     {
506         KillGLWindow();                                   //Reset the display
507         MessageBox(NULL, "Window creation error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
508         return FALSE;                                     // Retrurn FALSE;
509     }
510
511     /*
512      *  aside from the stencil buffer and the (slow) accumulation buffer
513      */
514     static PIXELFORMATDESCRIPTOR pfd =                    // pfd tells windows how we want things to be
515     {
516         sizeof(PIXELFORMATDESCRIPTOR),                    // Size of this pixel format descriptor
517         1,                                                // Version number
518         PFD_DRAW_TO_WINDOW |                              // Format must support window
519         PFD_SUPPORT_OPENGL |                              // Format must support OpenGL
520         PFD_DOUBLEBUFFER,                                 // Must support double buffer
521         PFD_TYPE_RGBA,                                    // Request an RGBA format
522         bits,                                             // Select our color depth
523         0, 0, 0, 0, 0, 0,                                 // Color bits ignored
524         0,                                                // No alpha buffer
525         0,                                                // shift bit ignored
526         0,                                                // No accumulation buffer
527         0, 0, 0, 0,                                       // Accumulation bits ignored
528         16,                                               // 16Bits Z_Buffer (depth buffer)
529         0,                                                // No stencil buffer
530         0,                                                // No auxiliary buffer
531         PFD_MAIN_PLANE,                                   // Main drawing layer
532         0,                                                // Reserved
533         0, 0, 0                                           // Layer makes ignored
534     };
535
536     if (!(hDC = GetDC(hWnd))) {                           // Did we get a device context
537         KillGLWindow();                                   // Reset the display
538         MessageBox(NULL, "Can‘t create a GL device context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
539         return FALSE;                                     // Return FALSE
540     }
541
542     if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {  // Did window find a matching pixel format
543         KillGLWindow();                                   // Reset the display
544         MessageBox(NULL, "Can‘t find a suitable pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
545         return FALSE;                                     // Return FALSE;
546     }
547
548     if (!SetPixelFormat(hDC, PixelFormat, &pfd)) {        // Are we able to set the pixel format
549         KillGLWindow();                                   // Reset the display
550         MessageBox(NULL, "Can‘t set the pixelformat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
551         return FALSE;                                     // Return FALSE;
552     }
553
554     if (!(hRC = wglCreateContext(hDC))) {                 // Are we able to rendering context
555         KillGLWindow();                                   // Reset the display
556         MessageBox(NULL, "Can‘t create a GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
557         return FALSE;                                     // Return FASLE;
558     }
559
560     if (!wglMakeCurrent(hDC, hRC)) {                      // Try to activate the rendering context
561         KillGLWindow();                                   // Reset the display
562         MessageBox(NULL, "Can‘t activate the GL rendering context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
563         return FALSE;                                     // Return FALSE
564     }
565
566     /*
567      *  ReSizeGLScene passing the screen width and height to set up our perspective OpenGL screen.
568      */
569     ShowWindow(hWnd, SW_SHOW);                            // Show the window
570     SetForegroundWindow(hWnd);                            // slightly higher priority
571     SetFocus(hWnd);                                       // Sets keyboard focus to the window
572     ReSizeGLScene(width, height);                         // Set up our perspective GL screen
573
574 /*
575  *  we can set up lighting, textures, and anything else that needs to be setup in InitGL().
576  */
577     if (!InitGL()) {                                      // Initialize our newly created GL window
578         KillGLWindow();                                   // Reset the display
579         MessageBox(NULL, "Initialize Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
580         return FALSE;                                     // Return FALSE
581     }
582     return TRUE;
583 }
584
585 LRESULT CALLBACK WndProc(HWND hWnd,                       // Handle for this window
586     UINT uMsg,                                            // Message for this window
587     WPARAM wParam,                                        // Additional message information
588     LPARAM lParam)                                        // Additional message information
589 {
590     switch (uMsg) {                                       // Check for window message
591     case WM_ACTIVATE: {                               // Check minimization state
592         if (!HIWORD(wParam)) {
593             active = TRUE;                            // Program is active
594         }
595         else {
596             active = FALSE;                           // Program is no longer active
597         }
598         return 0;                                     // Return to the message loop
599     }
600     case WM_SYSCOMMAND: {                             // Intercept system commands
601         switch (wParam) {                             // Check system calls
602         case SC_SCREENSAVE:                       // Screensaver trying to start
603         case SC_MONITORPOWER:                     // Monitor trying to enter powersave
604             return 0;                                 // Prevent form happening
605         }
606         break;                                        // Exit
607     }
608     case WM_CLOSE: {                                  // Did we receive a close message
609         PostQuitMessage(0);                           // Send a quit message
610         return 0;
611     }
612     case WM_KEYDOWN: {                                // Is a key being held down
613         keys[wParam] = TRUE;                          // if so, mark it as TRUE
614         return 0;                                     // Jump back
615     }
616     case WM_KEYUP: {                                  // Has a key been released
617         keys[wParam] = FALSE;                         // if so, mark it as FALSE
618         return 0;                                     // Jump back
619     }
620     case WM_SIZE: {                                   // Resize the OpenGL window
621         ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));   // LoWord = width HiWord = height
622         return 0;                                     // Jump back
623     }
624     }
625     return DefWindowProc(hWnd, uMsg, wParam, lParam);     // Pass all unhandled message to DefWindwProc
626 }
627
628 int WINAPI WinMain(HINSTANCE hInstance,                   // Instance
629     HINSTANCE hPrevInstance,                              // Previous instance
630     LPSTR lpCmdLine,                                      // Command line parameters
631     int nCmdShow)                                         // Window show state
632 {
633     MSG msg;                                              // Window message structure
634     BOOL done = FALSE;                                    // Bool variable to exit loop
635                                                           // Ask the user which screen mode they prefer
636     if (MessageBox(NULL, "Would you like to run in fullscreen mode?",
637         "Start fullscreen?", MB_YESNO | MB_ICONQUESTION) == IDNO)
638     {
639         fullscreen = FALSE;                               // Window mode
640     }
641     // Create our OpenGL window
642     if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {  // (Modified)
643         return 0;                                         // Quit if window was not create
644     }
645 /******************************************************************************************************************************************/
646 /******************************************************************************************************************************************/
647
648     while (!done) {                                       // Loop that runs until donw = TRUE
649         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {   // Is there a message wating
650             if (msg.message == WM_QUIT) {                 // Havw we received a quit message
651                 done = TRUE;                              // if so done  = TRUE
652             }
653             else {                                        // If not, deal with window message
654                 TranslateMessage(&msg);                   // Translate message
655                 DispatchMessage(&msg);                    // Dispatch message
656             }
657         }
658         else {
659             // Draw the scene. Watch for ESC key and quit message from DrawGLScene()
660             if (active) {                                 // Program active
661                 if (keys[VK_ESCAPE]) {                    // Was ESC pressed
662                     done = TRUE;                          // ESC signalled a quit
663                 }
664                 else {                                    // Not time to quit, update screen
665                     DrawGLScene();                        // Draw scene
666                     SwapBuffers(hDC);                     // Swap buffers (double buffering)
667                 }
668             }
669
670             if (keys[VK_UP] && (scroll > 0)) {
671                 scroll -= 2;
672             }
673             if (keys[VK_DOWN] && (scroll < 32 * (maxtokens - 9))) {
674                 scroll += 2;
675             }
676             /*
677             *  It allows us to press the F1 key to switch from fullscreen mode to
678             *  windowed mode or windowed mode to fullscreen mode.
679             */
680             if (keys[VK_F1]) {                            // Is F1 being pressed
681                 keys[VK_F1] = FALSE;                      // If so make key FASLE
682                 KillGLWindow();                           // Kill our current window
683                 fullscreen = !fullscreen;                 // Toggle fullscreen / window mode
684                 //Recreate our OpenGL window(modified)
685                 if (!CreateGLWindow("3D Shapes", 640, 480, 16, fullscreen)) {
686                     return 0;                             // Quit if window was not create
687                 }
688             }
689         }
690     }
691     // Shutdown
692     KillGLWindow();                                       // Kill the window
693     return (msg.wParam);                                  // Exit the program
694 }
695 /******************************************************************************************************************************************/
696 /******************************************************************************************************************************************/

Thanks for Nehe‘s tutorials, this is his home.

时间: 2024-07-28 13:14:56

outdated: 24. Tokens, Extensions, Scissor Testing And TGA Loading的相关文章

outdated: 33.Loading Compressed And Uncompressed TGA&#39;s

这一篇主要讲的是TGA文件的加载,TGA文件分为压缩与未压缩的两种. uncompressed和compressed的标头是不一样, // Uncompressed TGA header GLubyte uTGAcompare[12] = { 0,0,2,0,0,0,0,0,0,0,0,0 }; // Compressed TGA header GLubyte cTGAcompare[12] = { 0,0,10,0,0,0,0,0,0,0,0,0 }; 未压缩的TGA文件,在最后直接读取ima

NeHe OpenGL教程 第三十三课:TGA文件

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十三课:TGA文件 加载压缩和未压缩的TGA文件: 在这一课里,你将学会如何加载压缩和为压缩的TGA文件,由于它使用RLE压缩,所以非常的简单,你能很快地熟悉它的. 我见过很多人在游戏开发论坛或其它地方询问关于TGA读取的问题.

使用Unity3D50个技巧-50 Tips for Working with Unity (Best Practices)

原文: 50 Tips for Working with Unity (Best Practices) About these tips These tips are not all applicable to every project. They are based on my experience with projects with small teams from 3 to 20 people. There's is a price for structure, re-usabilit

『TensorFlow』徒手装高达_初号机_添加训练模组并整合为可用分类网络

摘要: 本次整合了前面两节的模组,并添加向前传播&反馈训练部分,使之成为一个包含训练&验证&测试的分类网络. 文件架构: 代码整合: image_info.py,图片读取部分 1 import glob 2 import os.path 3 import random 4 import numpy as np 5 import tensorflow as tf 6 7 def creat_image_lists(validation_percentage,testing_perce

[转] KVM/QEMU hypervisor driver

KVM/QEMU hypervisor driver Project Links Deployment pre-requisites Connections to QEMU driver Driver security architecture Driver instances POSIX users/groups Linux process capabilities SELinux basic confinement SELinux sVirt confinement AppArmor sVi

openGL+VS2010的例程--特效(三维)

效果图如上: 步骤:略. 实现代码如下: main.cpp 1 /********************************************************************** 2 3 Particle Engine / Billboarding 4 5 October, 21st, 2002 6 7 This tutorial was written by Philipp Crocoll 8 Contact: 9 [email protected] 10 www.

意料之外,情理之中,Spring.NET 3.0 版本发布-

意料之外,情理之中,Spring.NET 3.0 版本发布- 备受社区和企业开发者广泛关注的Spring.NET在上周发布了3.0版本,并且目前已经保持着持续的更新,让我们一起来看一看他究竟发布了哪些令人激动的新特性吧! Github上的原贴地址为:https://github.com/spring-projects/spring-net. 1.引言 Spring.NET 3.0.0版本包含 一个功能齐全的控制反转容器 面向方面的编程框架 轻量级脚本的表达式语言 UI不可知的验证框架 ASP.N

记一次企业级爬虫系统升级改造(五):基于JieBaNet+Lucene.Net实现全文搜索

实现效果: 上一篇文章有附全文搜索结果的设计图,下面截一张开发完成上线后的实图: 基本风格是模仿的百度搜索结果,绿色的分页略显小清新. 目前已采集并创建索引的文章约3W多篇,索引文件不算太大,查询速度非常棒. 刀不磨要生锈,人不学要落后.每天都要学一些新东西. 基本技术介绍: 还记得上一次做全文搜索是在2013年,主要核心设计与代码均是当时的架构师写的,自己只能算是全程参与. 当时使用的是经典搭配:盘古分词+Lucene.net. 前几篇文章有说到,盘古分词已经很多年不更新了,我在Support

Net Core WebApi单元测试

单元测试 本篇将结合这个系列的例子的基础上演示在Asp.Net Core里如何使用XUnit结合Moq进行单元测试,同时对整个项目进行集成测试. 第一部分.XUnit 修改 Project.json 文件内容,增加XUnit相关的nuget包引用,并修改部分配置. 1 { 2 "version": "1.0.0-*", 3 "testRunner": "xunit", // 设置测试工具为xunit 4 5 "bui