Bonjour à tous,
J'essaie de faire un écran de veille avec un cube qui tourne en utilisant OpenGL (je me sers des tutoriaux de Nehe et de Christian Coders Network). J'arrive à compiler mon projet (sous Dev-cpp) mais j'ai quelques problèmes surtout au niveau de la gestion de hDC et de hWnd, et puis, mes textures sont sales, pixellisées (mais peut-être que c'est lié).
Est-ce que quelqu'un aurait une idée pour améliorer ça ?
Merci.
P.S. : le projet contient 2 fichiers : screen_saver.h et main.cpp
// include file for SimpleSaver
#ifndef SIMPLESAVER_H // these two lines prevent multiple inclusions of
#define SIMPLESAVER_H // this .h file, a handy practice
// screen saver states, based on command line switches
enum States
{
state_normal, state_configure, state_preview, state_password
};
// setting for our saver
struct Settings
{
// handy stuff to keep track of
HINSTANCE hInst; // the instance handle
HWND hWnd; // our main window handle
int wndWidth; // width and height of our window
int wndHeight;
bool active; // are we initialized? Save to draw?
// run time states and settings
States state; // to keep track if we're running fullscreen, in
// configure mode, preview mode
// or password change mode
HWND previewParentHWnd; // Window handle of parent in preview mode
// user settings to save in the registry
// - nothing here yet, we'll do this in a later article
};
extern Settings g_settings; // so any other .cpp files we add later can see
// our global settings
// function prototypes
void DetermineState(LPSTR lpsz);
void DoConfigure();
AUX_RGBImageRec *LoadBMP(char *Filename);
int LoadGLTextures();
GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
int InitGL(GLvoid);
int DrawGLScene(GLvoid);
GLvoid KillGLWindow(GLvoid);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
int Run();
#endif // SIMPLESAVER_H
// main.cpp : Defines the entry point for the application.
//
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include "screen_saver.h"
//les prototypes des fonctions sont dans screen_saver.h
//variables globales
Settings g_settings; // our global screen saver settings
bool fullscreen = true;
HGLRC hRC = NULL; // Permanent Rendering Context
HDC hDC = NULL; // Private GDI Device Context
HINSTANCE hInstance; // Holds The Instance Of The Application
GLfloat xrot; // X Rotation
GLfloat yrot; // Y Rotation
GLfloat zrot; // Z Rotation
GLuint texture[3]; // Storage For Three Textures
int loop;
// given the command line, determine in which state we're supposed to
// start up in
void DetermineState(LPSTR lpsz)
{
// assume we want to start in configure mode, which is what we should do
// if there is no command line arguments
g_settings.state = state_configure;
// if the string is not NULL and not empty, we need to determine what mode
// to start up in. Otherwise, the default we just set above will be used
if((lpsz) && (lpsz[0]))
{
char param;
// ignore the switch character, which could be either a - or a /
if((lpsz[0] == '-') || (lpsz[0] == '/'))
lpsz++;
// and the next character tells us what state we need
param = tolower(lpsz[0]); // be case insensitive, just for safety
switch(param)
{
case 'p': // preview mode
case 'l': // preview mode
g_settings.state = state_preview;
// and save the parent window handle
lpsz++;
sscanf(lpsz, "%lu", &g_settings.previewParentHWnd);
break;
case 's': // start normal mode
g_settings.state = state_normal;
break;
default: // anything else ('c' or something invalid), just start
// in configure mode
g_settings.state = state_configure;
break;
}
}
} // DetermineState
void DoConfigure()
{
// in here is where you would create a dialog window, set up the wndproc
// for it, etc.
// We'll do that in a later lesson, for now just say:
MessageBox(NULL, "Nothing to configure", "Saver Configuration", MB_OK);
} // DoConfigure
AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image
{
FILE *File=NULL; // File Handle
if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}
File=fopen(Filename,"r"); // Check To See If The File Exists
if (File) // Does The File Exist?
{
fclose(File); // Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}
return NULL; // If Load Failed Return NULL
}//LoadBMP
int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
int Status=FALSE; // Status Indicator
AUX_RGBImageRec *TextureImage[3]; // Create Storage Space For The Texture
memset(TextureImage,0,sizeof(void *)*3); // Set The Pointer To NULL
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if ((TextureImage[0]=LoadBMP("Data/img01.bmp")) &&
(TextureImage[1]=LoadBMP("Data/img02.bmp")) &&
(TextureImage[2]=LoadBMP("Data/img03.bmp")))
{
Status=TRUE; // Set The Status To TRUE
glGenTextures(3, &texture[0]); // Create The Textures
// Typical Texture Generation Using Data From The Bitmap
for (loop=0; loop<3; loop++) // Loop Through All 3 Textures
{
glBindTexture(GL_TEXTURE_2D, texture[loop]);//loop replaces the normal [0] to make 3
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
}
for (loop=0; loop<3; loop++) // Loop Through All 3 Textures freeing the data
{
if (TextureImage[loop]) // If Texture Exists
{
if (TextureImage[loop]->data) // If Texture Image Exists
{
free(TextureImage[loop]->data); // Free The Texture Image Memory
}
free(TextureImage[loop]); // Free The Image Structure
}
}
}
else
{
MessageBox(NULL, "Bitmaps not found.", "WARNING", MB_OK | MB_ICONEXCLAMATION);
}
return Status; // Return The Status
}//LoadGLTextures
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
}
glViewport(0, 0, width, height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}//ReSizeGLScene
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn't Load Return FALSE
}
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enables Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}//InitGL
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
// if we're not active, don't do anything
if(!g_settings.active)
return FALSE;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Matrix
glTranslatef(0.0f,0.0f,-5.0f); // Move Into The Screen 5 Units
glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis
glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis
glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Texture
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// Back Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]); // Select Our Texture
glBegin(GL_QUADS);
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// Left Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[2]); // Select Our Texture
glBegin(GL_QUADS);
// Top Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// Bottom Face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glEnd();
xrot+=0.3f; // X Axis Rotation
yrot+=0.2f; // Y Axis Rotation
zrot+=0.4f; // Z Axis Rotation
return TRUE; // Keep Going
}//DrawGLScene
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
}
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);
}
if(!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL, "Release rendering context failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;
}
if(hDC && !ReleaseDC(g_settings.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
}
if(g_settings.hWnd && !DestroyWindow(g_settings.hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
g_settings.hWnd = NULL; // Set hWnd To NULL
}
if(!UnregisterClass("WindowsScreenSaverClass", 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
}
}// KillGLWindow
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
{
static DWORD dwFakeMouseMoveMsgAllowed = 5;
static RECT rc; // RECT structure
switch (uMsg) // Check For Windows Messages
{
case WM_CREATE: // do any initialization in here, e.g. create timers, etc.
break;
case WM_SETCURSOR: // Windows wants us to initialize our mouse cursor
// if we're in normal, full screen mode, hide the mouse cursor
if(g_settings.state == state_normal)
SetCursor(NULL);
break;
case WM_PAINT: // Windows wants us to redraw the window. We'll just
// fill the screen with black here, as our DoFrame function will
// do the real drawing.
// Get the window's DC
hDC = GetDC(hWnd);
// get the size of the client area (our drawing area)
GetClientRect (hWnd, &rc);
// fill that area with black
FillRect (GetDC(hWnd), &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
// we're done with the DC
ReleaseDC(hWnd,GetDC(hWnd));
// BTW, if Windows is sending us paint messages, we must be active
g_settings.active = true;
break;
case WM_ACTIVATE: // Windows is telling us to activate or deactivate
// if Windows is telling us we should be inactive...
if(LOWORD(wParam) == WA_INACTIVE)
{
// remember that we are now inactive, so our DrawGLScene doesn't try
// to draw when it shouldn't
g_settings.active = false;
// and send ourselves a close message
PostMessage(hWnd, WM_CLOSE, 0, 0);
}
else
{
// else Windows is activating us
g_settings.active = true;
}
break;
case WM_SYSCOMMAND: // Special system ommands
{
switch (wParam) // Which command?
{
case SC_SCREENSAVE: // If another instance of any screensaver
// is trying to start,
return 0; // we don't let it. Returning 0 tells
// Windows it should let that saver start.
}
break;
}
case WM_CLOSE: // We're supposed to close down
// we are no longer active
g_settings.active = false;
// Send ourselves a quit message, which is the final message an
// app receives. We'll use it in our Run function below to
// break out of our main loop.
PostQuitMessage(0);
break;
// on key presses or mouse events
case WM_MOUSEMOVE: // Windows is telling us that the mouse has moved
// Normally, we want to close our screen saver at this point (if
// we're running in normal mode), but in between the time our app
// starts and the window is actually created and ready for drawing,
// mouse move messages might sneak in. We want to ignore the first
// few mouse move messages to prevent the saver from closing as soon
// as it starts up.
// If we have any fake move messages left to count
if(dwFakeMouseMoveMsgAllowed)
{
// decrease our count and keep going, not worrying about it
dwFakeMouseMoveMsgAllowed--;
break;
}
// else, fall through to next case which will potentially close
// our saver
case WM_KEYDOWN: // Windows is telling us a key has been pressed
case WM_LBUTTONDOWN: // the left mouse button was pressed
case WM_RBUTTONDOWN: // the right mouse button was pressed.
case WM_MBUTTONDOWN: // the middlee mouse button was pressed.
// if we're in normal, full screen mode, we normally want to shutdown
// our screen saver as a result
if(g_settings.state == state_normal)
{
// send ourselves a close message
PostMessage(hWnd, WM_CLOSE, 0, 0);
}
break;
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
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 Rectangle 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
fullscreen = fullscreenflag; // Set The Global Fullscreen Flag
hInstance = g_settings.hInst; // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, 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 = NULL; // No Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "WindowsScreenSaverClass"; // Set The Class Name
if(!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL, "Failed to register the window class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Exit And Return FALSE
}
if(fullscreen)
{
DEVMODE dmScreenSettings; // Device Mode
memset(&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;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","CjC Screen Saver",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen = false; // Select Windowed Mode (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; // Exit And Return FALSE
}
}
}
////////////////////////////////////////////////////////////////////////////////
// Create the main window.
// if our saver is starting in normal, full screen mode...
if(g_settings.state == state_normal&&fullscreen)
{
// our size is 0,0 (top,left) to bottom,right of the entire screen
SetRect(&WindowRect, 0, 0, GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
// and we want a popup, topmost window with no borders, caption, etc.
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle = WS_POPUP | WS_EX_TOPMOST; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else // we're in preview mode
{
// our size is the size of our parent's client area
GetClientRect(g_settings.previewParentHWnd, &WindowRect);
// and we are a child window
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_CHILD; // Windows Style
}
////////////////////////////////////////////////////////////////////////////////
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
if (!(g_settings.hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"WindowsScreenSaverClass", // Class Name
title, // Window Title
WS_CLIPSIBLINGS | // Required Window Style for OpenGL
WS_CLIPCHILDREN | // Required Window Style for OpenGL
dwStyle, // Selected Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Adjusted Window Width
WindowRect.bottom-WindowRect.top, // Calculate Adjusted Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Don't Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(g_settings.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
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&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
}
if(!SetPixelFormat(hDC,PixelFormat,&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
}
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
}
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
}
ShowWindow(g_settings.hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(g_settings.hWnd); // Slightly Higher Priority
SetFocus(g_settings.hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
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
}
return TRUE; // Success
}// CreateGLWindow
// the main message loop: run until WM_QUIT
int Run()
{
MSG msg;
bool done = false;
CreateGLWindow("CjC Screen Saver",1024,768,16,true);
while(!done)
{
// Is There A Message Waiting?
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// WM_QUIT means we're all done
if(msg.message == WM_QUIT)
{
done = true;
}
else
{
TranslateMessage(&msg); // for virtual keys, etc.
DispatchMessage(&msg); // send to our winproc for processing
}
}
else
{
// Draw The Scene
if (g_settings.active) // only if we're in an active state
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
Sleep(5); // Sleep to give the system a chance to process
// background tasks. Without a Sleep, our loop will
// run as past as possible (which *might* be what
// you want), but will eat 99.99% of your CPU time
// (ie. background processes will run slower!).
// Not a good idea if this saver is running on
// a server, etc.
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
} // Run
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// basic initialization
g_settings.active = false;
g_settings.hInst = hInstance; // save instance handle
g_settings.previewParentHWnd = NULL;
// determine which state our saver needs to start in
DetermineState(lpCmdLine);
// if it's a password request (Win9x), let's not bother.
// Maybe I'll add this later, if anyone really wants it
if(g_settings.state == state_password)
{
return 0;
}
// are we supposed to show the configure dialog box?
if(g_settings.state == state_configure)
{
DoConfigure();
return 0;
}
// Start the message loop.
int rc = Run();
// Return the exit code to the system.
return rc;
} // WinMain
Vith