Hi Again
Pelle, I did this simple First Person OpenGL 3D Engine a couple of weeks back, in Dev C++ and ported it today to Pelles C.
Next week I might have an opportunity to dedicate a couple of sessions to version 0.2 and hopefully improve it with:
- Texturing
- Tiling of textures
- some kind of mouse look like in UT or Quake
- strafing sideways
- Basic collision detection
- Some kind of Font Text capability
- Frames Per Second Timer
- some kind of a timing system
-( I was polling the high frequency timer in Dev C++
but, I was'nt satisfied with the timer anyways and decided
to leave it out, for now)
- might change some of the Hungarian Notation to Open
the Window for OpenGL
.........Well, I'm a learning too. The example compiled without a single error or warning but I'm definitley open to any suggestions to improve the little example.
ROM
/***************************************************************************
* Application Identification
*
* OPEN GL PURE C 3D ENGINE
* VER 0.1
*
* A Remake of a Classic original OpenGL Blaine Hodges' Example
* Totally recoded. It uses some of NEHE's ideas for movement
*
* Made by a Beginner for Beginners!
* Extremely well commented for novices
* Only 4 functions ! Incredible!
* Only one Small .c file to compile
* Easy to Understand. No Fan-Dangled OOP code to unscramble!
* A 3D World with Sun, Starfield, Ground and other 3D Objects
* Walk around your very own 3D World with arrow keys
* Exit with Escape Key
* Quick Exit with Control_F4 Keys
* Two Fullscren Resolutions available to user
* Best Way to Learn OpenGL Basics by creating in a 3D World!
* Add the 3D Primitives in the " All openGL Code Goes Here" section
* Modify to your liking
* Free for any use!
*
*
*PellesC/Project/project Options/ linker :
*opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib advapi32.lib
*PellesC/Project/project Options/ Compiler:
*in Warnings: Level 1... in Calling conventions: __stdCall .... check enable MS extensions
*in Optimizations: Maximize speed ...in Define Preprocessor symbols: WIN32,_WINDOWS
*
*
****************************************************************************/
/************************
* Includes
* Includes and defines
************************/
#include <stdlib.h>
#include <windows.h> // Header File For Windows
#include <math.h> // Math Library Header File
#include <stdio.h> // Header File For Standard Input/Output
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library
#include <stdbool.h> // Header File For The C99 bool definitions
/**************************************
* Prototype Function Declarations
*
**************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int EnableOpenGL(HWND hWnd, HDC *hDC, HGLRC *hRC);
int DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);
/**************************************************
* Declare various variables as static
**************************************************/
static int width;
static int height;
/************************************************************
* 1.Main Windows Function Declaration and Definition
*
* Create instance for window, register window class,
* Program main loop with object scene animation.
************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int iCmdShow)
{ //Opening Brace For WinMain
// At Start of App, Offer Two Resolutions, 1024*768 or 640x480 In Fullscreen.
if (MessageBox(NULL," Use 1024x768 Resolution instead of 640x480?","C++ 3D Engine",MB_YESNO|MB_ICONINFORMATION)==IDYES)
{
width= 1024;
height= 768;
}
else
{
width= 640;
height= 480;
}
//WinMain´s Variable Declarations
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
//Variables For Screen
DWORD dWinStyle; //Var to hold Window Style
dWinStyle=WS_POPUP; // Windows Style
RECT WindowRect; // Grabs Rectangle Upper Left and 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
bool quit = FALSE; //Enter Main Program Loop By Default
GLfloat cubePosInitX = -15.0f;
GLfloat cubePosInitY = 1.0f;
GLfloat cubePosInitZ = 0.0f;
GLfloat rotateCube = 0.0f ;
//Initial ground position values
GLfloat initGroundPosX = 0.0f;
GLfloat initGroundPosY = -1.0f;
GLfloat initGroundPosZ = 0.0f;
//Initial pyramid positions
GLfloat initPyramidPosX = 0.0f;
GLfloat initPyramidPosY = 1.0f;
GLfloat initPyramidPosZ = -10.0f;
const float piover180 = 0.0174532925f;
GLfloat heading;
GLfloat xpos = 0.0f;
GLfloat zpos = 0.0f;
GLfloat ypos= 0.0f;
GLfloat yrot; // Y Rotation
GLfloat Bob = 0.0f; // player head bobbing
// Set Up Window Class
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "GLSample";
//Register The &wc Window Class
if (!RegisterClass(&wc)) // Failed Attempt At Registering Window Class
{
MessageBox(NULL,"Failed Attempt at Registering Window Class.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE; // Exit And Return FALSE
}
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = width;
dmScreenSettings.dmPelsHeight =height;
dmScreenSettings.dmBitsPerPel = 16;
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// Pop Up A Message Box To Inform User Resolution Failed
MessageBox(NULL,"Failed Resolution Attempt. \n Choose A Lower Resolution. ","ERROR",MB_OK|MB_ICONSTOP);
return FALSE;
}
// Create Main Window
hWnd = CreateWindow
(
"GLSample",
"C++ 3D Engine", // Window caption
WS_CLIPSIBLINGS| // Must be set for OpenGL to work
WS_CLIPCHILDREN| // WS_CLIPCHILDREN and WS_CLIPSIBLINGS
dWinStyle, // Popup window variable
0, // Initial x position
0, // Initial y position
WindowRect.right-WindowRect.left, // Calculate Adjusted Window Width
WindowRect.bottom-WindowRect.top, // Calculate Adjusted Window Height
NULL, // Parent window handle
NULL, // Window menu handle
hInstance, // Program instance handle
NULL // Creation parameters
);
// Open window maximized
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd);
UpdateWindow (hWnd);
// Hide Mouse Pointer
ShowCursor(FALSE);
// enable OpenGL for the window
EnableOpenGL( hWnd, &hDC, &hRC );
/*Set depth testing, buffers and Viewport*/
glViewport (0, 0, width, height);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
//Projection Matrix for viewing volumes
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
// glFrustum (-width/height, width/height, -1.0, 1.0, 1.0, 10000.0);
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,1000.0f);
// Modelview Matrix for Objects
glMatrixMode (GL_MODELVIEW);
// Program Main Loop
while ( !quit )
{
// check for messages
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
// handle or dispatch messages
if ( msg.message == WM_QUIT )
{
quit = TRUE;
}
else
{
TranslateMessage( &msg );
//Invoke Win CallBack Function
DispatchMessage( &msg );
}
}
else
{
//------------------------------------------
// OpenGL Animation Code Goes Here
//------------------------------------------
// player controlled variables
GLfloat xtrans = -xpos;
GLfloat ytrans = -ypos;
GLfloat ztrans = -zpos;
GLfloat sceneroty = 360.0f - yrot;
//Clear previous frame color and depth enable drawing of next frame
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*Clear existing internal tansformations by loading identity matrix for entire scene*/
glLoadIdentity ();
//.........................................
// XYZ AXIS
//
// Always stays put in the same place
// since it's placed before any scene
// translations or rotations
//..........................................
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
// Entire Group of Lines Can Be Translated(moved) together
GLfloat axisPosX =0.0f;
GLfloat axisPosY = 0.0f;
GLfloat axisPosZ = -1.0f; // move them into the scene -1 unit.
glTranslatef( axisPosX , axisPosY, axisPosZ);
glColor3f(1.0,0.0,0.0); // Red
//X AXIS
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f); // Point origin
glVertex3f(0.1f, 0.0f, 0.0f); // Towards Plus + X Axis
//Y AXIS
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f); // Point origin
glVertex3f(0.0f, 0.1f, 0.0f); // Towards Plus + Y Axis
//Z AXIS
glBegin(GL_LINE_STRIP);
glVertex3f(0.0f, 0.0f, 0.0f); // Point origin
//Towards Negative - Z Axis and into scene
glVertex3f(0.03f, -0.05f, -0.1f); //(slightly off to be perceived)
glEnd();
//restore OpenGl´s matrix stack transformations to continue to translatef
glPopMatrix ();
glPushMatrix ();
// Rotate and translate all scene objects
glRotatef(sceneroty,0.0f,1.0f,0.0f);
glTranslatef(xtrans, ytrans, ztrans);
// Access OpenGl´s matrix stack to save transformations for entire scene
//.............................
// SUN
//.............................
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
/* float sunRotAnglZ = 0.0f; */
GLfloat angle;
float degree;
float sunPosX = 0.0f, sunPosY = 35.0f, sunPosZ = -100.0f;
glTranslatef(sunPosX, sunPosY,sunPosZ);
// glTranslatef(xtrans + sunPosX, ytrans + sunPosY, ztrans + sunPosZ);
/* glRotatef(sunRotAnglZ, 0.0f,0.0f, 1.0f);*/
glColor3f(0.5f,0.6f,0.0f);
glScalef(10.0f, 10.0f, 10.0f);
glHint(GL_LINE_SMOOTH, GL_NICEST);
glBegin(GL_LINES);
for (degree=0.0; degree < 360.0; degree+=3.0)
{
angle = (GLfloat)degree*3.14159f/180.0f; // change degrees to radians
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(cos(angle), sin(angle), 0.0f);
}
glEnd();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//...............................
//STARFIELD
//...............................
// Front Plane ("Group of points") can be moved together .
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
GLfloat frontStarX= 0.0f;
GLfloat frontStarY= 80.0f;
GLfloat frontStarZ = -130.0f;
// draw random points.
glHint(GL_POINT_SMOOTH, GL_NICEST);
// glTranslatef(xtrans + frontStarX , ytrans + frontStarY, ztrans + frontStarZ);
glTranslatef(frontStarX , frontStarY,frontStarZ);
glPointSize(1.0);
glColor3f(1,1,1);
glBegin(GL_POINTS);
glVertex3f ( 111.0, 160.0, -180.0 );
glVertex3f ( -115.0, 115.0, -191.0 );
glVertex3f ( 110.0, 130.0, -102.0 );
glVertex3f ( -115.0, 110.0, -183.0 );
glVertex3f ( 210.0, 140.0, -184.0 );
glVertex3f ( -310.0, 125.0, -120.0 );
glVertex3f ( 351.0, 150.0, -175.0 );
glVertex3f (- 501.0, 115.0, -182.0 );
glVertex3f ( 701.0, 145.0, -183.0 );
glVertex3f ( -701.0, 115.0, -154.0 );
glVertex3f ( 811.0, 160.0, -180.0 );
glVertex3f ( -815.0, 115.0, -191.0 );
glVertex3f ( 910.0, 230.0, -102.0 );
glVertex3f ( -915.0, 210.0, -183.0 );
glVertex3f ( 1010.0, 540.0, -184.0 );
glVertex3f ( -1010.0, 525.0, -120.0);
glVertex3f ( 1551.0, 750.0, -175.0);
glVertex3f (- 1770.0, 715.0, -182.0);
glVertex3f ( 2420.0, 945.0, -183.0);
glVertex3f ( -2420.0, 915.0, -154.0);
glEnd();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//BackPlane ("group of points") can be moved together as one.
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
GLfloat backStarX= 0.0f;
GLfloat backStarY= 80.0f;
GLfloat backStarZ = 130.0f;
// draw random points.
glHint(GL_POINT_SMOOTH, GL_NICEST);
// srand(GL_POINTS);
glTranslatef(backStarX, backStarY, backStarZ);
glPointSize(1.0);
glColor3f(1,1,1);
glBegin(GL_POINTS);
glVertex3f ( -111.0, 160.0, 180.0 );
glVertex3f ( 115.0, 115.0, 191.0 );
glVertex3f ( -110.0, 130.0, 102.0 );
glVertex3f ( 115.0, 110.0, 183.0 );
glVertex3f ( -210.0, 140.0, 184.0 );
glVertex3f ( 310.0, 125.0, 120.0 );
glVertex3f ( -351.0, 150.0, 175.0 );
glVertex3f (501.0, 15.0, 182.0 );
glVertex3f ( -701.0, 145.0, 183.0 );
glVertex3f (701.0, 115.0, 154.0 );
glVertex3f ( -811.0, 260.0, 180.0 );
glVertex3f ( 815.0, 215.0, 191.0 );
glVertex3f ( -910.0, 330.0, 102.0 );
glVertex3f ( 915.0, 310.0, 183.0 );
glVertex3f ( -1010.0, 440.0, 184.0 );
glVertex3f ( 1010.0, 425.0, 120.0 );
glVertex3f ( -1551.0, 650.0, 175.0 );
glVertex3f (1770.0, 615.0, 182.0 );
glVertex3f ( -2420.0, 845.0, 183.0 );
glVertex3f ( 2480.0, 815.0, 154.0 );
glEnd();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//.......................
//PUT GROUND IN SCENE
//........................
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
/*rotate the scene inversely to camera*/
/*setup to move ground where it will be drawn*/
glTranslatef(initGroundPosX ,initGroundPosY , initGroundPosZ );
glBegin(GL_QUADS);
glNormal3f(0.0, 1.0, 0.0);
//Each of the 4 vertices of Ground has three pos and color coordinates
//left front vertex
glColor3f(0.5f, 0.6f, 1.0f); glVertex3f(-25.0f, 0.0f,25.0f);
//right front vertex
glColor3f(1.0f, 0.4f, 0.3f); glVertex3f(25.0f, 0.0f, 25.0f);
//right back vertex
glColor3f(0.2f, 0.6f, 1.0f); glVertex3f(25.0f, 0.0f,-25.0f);
//left back vertex
glColor3f(0.6f, 0.4f, 0.7f); glVertex3f(-25.0f, 0.0f,-25.0f);
glEnd();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//.......................
//PUT PYRAMID IN SCENE
//......................
/*access OpenGl´s matrix stack to save transformations*/
glPushMatrix ();
/*Clear existing internal tansformations by loading identity matrix*/
glTranslatef(initPyramidPosX , initPyramidPosY , initPyramidPosZ );
/*Join vertex 1,2,3..1,3,4 and 1,4,5(vertice 1 is common to the rest)*/
glBegin (GL_TRIANGLE_FAN);
/*assign color and position in 3d space to each vertex thru its 3 coords*/
glColor3f (0.0f,.5f, 1.0f); glVertex3f ( 0.0f, 3.0f, 0.0f);
glColor3f (1.0f, .5f, 0.0f); glVertex3f (-3.0f,-3.0f, 3.0f);
glColor3f (1.0f, .3f, 1.0f); glVertex3f ( 3.0f,-3.0f, 3.0f);
glColor3f (.2f, 0.0f, .7f); glVertex3f ( 3.0f,-3.0f,-3.0f);
glColor3f (0.0f, 1.0f, 0.0f); glVertex3f (-3.0f,-3.0f,-3.0f);
glColor3f (.8f, .7f, 0.0f); glVertex3f (-3.0f,-3.0f, 3.0f);
glEnd ();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//........................................................
//Cube with nice mix of colors
//........................................................
glPushMatrix ();
/*move all vertices(the Cube) on axis into the screen*/
glRotatef(rotateCube,0.0f,1.0f,0.0f);
glTranslatef (cubePosInitX , cubePosInitY, cubePosInitZ );
glBegin(GL_QUADS);
// Front Face
glNormal3f( 0.0f, 0.0f, 1.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.3f,1.0f,0.5f); glVertex3f( 1.0f, -1.0f, 1.0f);
glColor3f(0.7f,0.2f,1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.2f); glVertex3f(-1.0f, 1.0f, 1.0f);
// Back Face
glNormal3f( 0.0f, 0.0f, -1.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(1.0f,0.5f,0.2f); glVertex3f(-1.0f, 1.0f, -1.0f);
glColor3f(0.3f,1.0f,0.5f); glVertex3f( 1.0f, 1.0f, -1.0f);
glColor3f(0.7f,0.2f,1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.7f,0.2f,1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glColor3f(0.3f,1.0f,0.5f);glVertex3f(-1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.2f); glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f( 1.0f, 1.0f, -1.0f);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.3f,1.0f,0.5f); glVertex3f( 1.0f, -1.0f, -1.0f);
glColor3f(0.7f,0.2f,1.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.2f); glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f( 1.0f, -1.0f, -1.0f);
glColor3f(1.0f,0.5f,0.2f);glVertex3f( 1.0f, 1.0f, -1.0f);
glColor3f(0.3f,1.0f,0.5f); glVertex3f( 1.0f, 1.0f, 1.0f);
glColor3f(0.7f,0.2f,1.0f);glVertex3f( 1.0f, -1.0f, 1.0f);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
glColor3f(0.7f,0.2f,1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glColor3f(0.3f,1.0f,0.5f); glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.2f); glVertex3f(-1.0f, 1.0f, 1.0f);
glColor3f(1.0f,0.5f,0.7f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
/*restore OpenGl´s matrix stack transformations to continue to translatef*/
glPopMatrix ();
//Restore OpenGl´s matrix stack transformations to continue to translatef entire scene
glPopMatrix ();
/*Make Scene Visible*/
SwapBuffers( hDC );
float speed = 0.05f;
//Cube rotation values
rotateCube += 0.75f ;
/*Keyboard Section for Player Controlled Translations and Rotations, Ect..*/
if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80)
{
xpos -= (float)sin(heading*piover180) * speed;
zpos -= (float)cos(heading*piover180) * speed;
if (Bob >= 359.0f)
{
Bob = 0.0f;
}
else
{
Bob += 20;
}
ypos = (float)sin(Bob * piover180)/20.0f ;
}
if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80)
{
xpos += (float)sin(heading*piover180) * speed;
zpos += (float)cos(heading*piover180) * speed;
if (Bob <= 1.0f)
{
Bob = 359.0f;
}
else
{
Bob-= 20;
}
ypos = (float)sin(Bob * piover180)/20.0f ;
}
if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80)
{
heading -= 1.0f;
yrot = heading;
}
if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80)
{
heading += 1.0f ;
yrot = heading;
}
// Control_F4 as a quick escape key sequence
if(GetKeyState(VK_CONTROL) & 0x80 && GetKeyState(VK_F4) & 0x80)
{
quit = TRUE; // set bool var quit, to true and exit
}
} //Closes Else of OpenGL Animation Loop
} // Closes While quit Is Not Equal To True
// Shutdown OpenGL
DisableOpenGL( hWnd, hDC, hRC );
/*Destroy the Window*/
if (!DestroyWindow(hWnd)) // Window Destroyed?
{
MessageBox(NULL,"Failed Attempt At Destroying Window.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // Set hWnd To NULL
}
/*Unregister the Class*/
if (!UnregisterClass("GLSample",hInstance)) // Was Class Unregistered?
{
MessageBox(NULL,"Failed Attempt At Unregistering Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // Set hInstance To NULL
}
return msg.wParam;
} // Closing Brace For WinMain
/*************************************************
* 2.Window Callback Function (Body)Definition
* Messages, user keyboard
* Event Driven
**************************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_SYSCOMMAND:
switch(lParam)
{
case SC_SCREENSAVE: //Screen saver starting?
case SC_MONITORPOWER: //PowerSave Mode?
return 0;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
// Show Mouse Pointer to be able to Select
ShowCursor(TRUE);
if (MessageBox(NULL," Sure You Want To Quit? "," C++ 3D Engine ",MB_YESNO|MB_ICONQUESTION)==IDYES)
{
PostQuitMessage(0); // set quit to TRUE
}
else
{
// Hide Mouse Pointer to Continue
ShowCursor(FALSE);
}
return 0;
}
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
// Enable OpenGL
/**************************************************************************
* 3. Enable OpenGL Function
* Pixel format description, device context and it´s Ogl render context,
***************************************************************************/
int EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC (hWnd);
/* set the pixel format for the DC */
ZeroMemory (&pfd, sizeof (pfd));
pfd.nSize = sizeof (pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
if ( (iFormat = ChoosePixelFormat(*hDC, &pfd)) == 0 )
{
MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
return FALSE;
}
if (SetPixelFormat(*hDC, iFormat, &pfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
return FALSE;
}
/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
/* make render context current with current device context*/
wglMakeCurrent( *hDC, *hRC );
return 0;
}
// Disable OpenGL
/**************************************************
* 4. Disable OpenGL Function
*
***************************************************/
int DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
// Restore default desktop mode with mouse pointer
ChangeDisplaySettings(NULL,0);
// Show Mouse Pointer
ShowCursor(TRUE);
/*If All Above O.K Return True*/
return TRUE;
}