commit 15e384194c5d6d2d14249589b5c9133ada7dfab6 Author: a dinosaur Date: Mon Aug 14 03:55:22 2023 +1000 party like it's 1999 diff --git a/Data/Mud.bmp b/Data/Mud.bmp new file mode 100644 index 0000000..9b10897 Binary files /dev/null and b/Data/Mud.bmp differ diff --git a/Data/World.txt b/Data/World.txt new file mode 100644 index 0000000..767385e --- /dev/null +++ b/Data/World.txt @@ -0,0 +1,160 @@ + +NUMPOLLIES 36 + +// Floor 1 +-3.0 0.0 -3.0 0.0 6.0 +-3.0 0.0 3.0 0.0 0.0 + 3.0 0.0 3.0 6.0 0.0 + +-3.0 0.0 -3.0 0.0 6.0 + 3.0 0.0 -3.0 6.0 6.0 + 3.0 0.0 3.0 6.0 0.0 + +// Ceiling 1 +-3.0 1.0 -3.0 0.0 6.0 +-3.0 1.0 3.0 0.0 0.0 + 3.0 1.0 3.0 6.0 0.0 +-3.0 1.0 -3.0 0.0 6.0 + 3.0 1.0 -3.0 6.0 6.0 + 3.0 1.0 3.0 6.0 0.0 + +// A1 + +-2.0 1.0 -2.0 0.0 1.0 +-2.0 0.0 -2.0 0.0 0.0 +-0.5 0.0 -2.0 1.5 0.0 +-2.0 1.0 -2.0 0.0 1.0 +-0.5 1.0 -2.0 1.5 1.0 +-0.5 0.0 -2.0 1.5 0.0 + +// A2 + + 2.0 1.0 -2.0 2.0 1.0 + 2.0 0.0 -2.0 2.0 0.0 + 0.5 0.0 -2.0 0.5 0.0 + 2.0 1.0 -2.0 2.0 1.0 + 0.5 1.0 -2.0 0.5 1.0 + 0.5 0.0 -2.0 0.5 0.0 + +// B1 + +-2.0 1.0 2.0 2.0 1.0 +-2.0 0.0 2.0 2.0 0.0 +-0.5 0.0 2.0 0.5 0.0 +-2.0 1.0 2.0 2.0 1.0 +-0.5 1.0 2.0 0.5 1.0 +-0.5 0.0 2.0 0.5 0.0 + +// B2 + + 2.0 1.0 2.0 2.0 1.0 + 2.0 0.0 2.0 2.0 0.0 + 0.5 0.0 2.0 0.5 0.0 + 2.0 1.0 2.0 2.0 1.0 + 0.5 1.0 2.0 0.5 1.0 + 0.5 0.0 2.0 0.5 0.0 + +// C1 + +-2.0 1.0 -2.0 0.0 1.0 +-2.0 0.0 -2.0 0.0 0.0 +-2.0 0.0 -0.5 1.5 0.0 +-2.0 1.0 -2.0 0.0 1.0 +-2.0 1.0 -0.5 1.5 1.0 +-2.0 0.0 -0.5 1.5 0.0 + +// C2 + +-2.0 1.0 2.0 2.0 1.0 +-2.0 0.0 2.0 2.0 0.0 +-2.0 0.0 0.5 0.5 0.0 +-2.0 1.0 2.0 2.0 1.0 +-2.0 1.0 0.5 0.5 1.0 +-2.0 0.0 0.5 0.5 0.0 + +// D1 + +2.0 1.0 -2.0 0.0 1.0 +2.0 0.0 -2.0 0.0 0.0 +2.0 0.0 -0.5 1.5 0.0 +2.0 1.0 -2.0 0.0 1.0 +2.0 1.0 -0.5 1.5 1.0 +2.0 0.0 -0.5 1.5 0.0 + +// D2 + +2.0 1.0 2.0 2.0 1.0 +2.0 0.0 2.0 2.0 0.0 +2.0 0.0 0.5 0.5 0.0 +2.0 1.0 2.0 2.0 1.0 +2.0 1.0 0.5 0.5 1.0 +2.0 0.0 0.5 0.5 0.0 + +// Upper hallway - L +-0.5 1.0 -3.0 0.0 1.0 +-0.5 0.0 -3.0 0.0 0.0 +-0.5 0.0 -2.0 1.0 0.0 +-0.5 1.0 -3.0 0.0 1.0 +-0.5 1.0 -2.0 1.0 1.0 +-0.5 0.0 -2.0 1.0 0.0 + +// Upper hallway - R +0.5 1.0 -3.0 0.0 1.0 +0.5 0.0 -3.0 0.0 0.0 +0.5 0.0 -2.0 1.0 0.0 +0.5 1.0 -3.0 0.0 1.0 +0.5 1.0 -2.0 1.0 1.0 +0.5 0.0 -2.0 1.0 0.0 + +// Lower hallway - L +-0.5 1.0 3.0 0.0 1.0 +-0.5 0.0 3.0 0.0 0.0 +-0.5 0.0 2.0 1.0 0.0 +-0.5 1.0 3.0 0.0 1.0 +-0.5 1.0 2.0 1.0 1.0 +-0.5 0.0 2.0 1.0 0.0 + +// Lower hallway - R +0.5 1.0 3.0 0.0 1.0 +0.5 0.0 3.0 0.0 0.0 +0.5 0.0 2.0 1.0 0.0 +0.5 1.0 3.0 0.0 1.0 +0.5 1.0 2.0 1.0 1.0 +0.5 0.0 2.0 1.0 0.0 + + +// Left hallway - Lw + +-3.0 1.0 0.5 1.0 1.0 +-3.0 0.0 0.5 1.0 0.0 +-2.0 0.0 0.5 0.0 0.0 +-3.0 1.0 0.5 1.0 1.0 +-2.0 1.0 0.5 0.0 1.0 +-2.0 0.0 0.5 0.0 0.0 + +// Left hallway - Hi + +-3.0 1.0 -0.5 1.0 1.0 +-3.0 0.0 -0.5 1.0 0.0 +-2.0 0.0 -0.5 0.0 0.0 +-3.0 1.0 -0.5 1.0 1.0 +-2.0 1.0 -0.5 0.0 1.0 +-2.0 0.0 -0.5 0.0 0.0 + +// Right hallway - Lw + +3.0 1.0 0.5 1.0 1.0 +3.0 0.0 0.5 1.0 0.0 +2.0 0.0 0.5 0.0 0.0 +3.0 1.0 0.5 1.0 1.0 +2.0 1.0 0.5 0.0 1.0 +2.0 0.0 0.5 0.0 0.0 + +// Right hallway - Hi + +3.0 1.0 -0.5 1.0 1.0 +3.0 0.0 -0.5 1.0 0.0 +2.0 0.0 -0.5 0.0 0.0 +3.0 1.0 -0.5 1.0 1.0 +2.0 1.0 -0.5 0.0 1.0 +2.0 0.0 -0.5 0.0 0.0 \ No newline at end of file diff --git a/Lesson10.cpp b/Lesson10.cpp new file mode 100644 index 0000000..1864fc4 --- /dev/null +++ b/Lesson10.cpp @@ -0,0 +1,691 @@ +/* + * This Code Was Created By Lionel Brits & Jeff Molofee 2000 + * A HUGE Thanks To Fredric Echols For Cleaning Up + * And Optimizing The Base Code, Making It More Flexible! + * If You've Found This Code Useful, Please Let Me Know. + * Visit My Site At nehe.gamedev.net + */ + +#include // Header File For Windows +#include // Math Library Header File +#include // Header File For Standard Input/Output +#include // Header File For The OpenGL32 Library +#include // Header File For The GLu32 Library +#include // Header File For The Glaux Library + +HDC hDC=NULL; // Private GDI Device Context +HGLRC hRC=NULL; // Permanent Rendering Context +HWND hWnd=NULL; // Holds Our Window Handle +HINSTANCE hInstance; // Holds The Instance Of The Application + +bool keys[256]; // Array Used For The Keyboard Routine +bool active=TRUE; // Window Active Flag Set To TRUE By Default +bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default +bool blend; // Blending ON/OFF +bool bp; // B Pressed? +bool fp; // F Pressed? + +const float piover180 = 0.0174532925f; +float heading; +float xpos; +float zpos; + +GLfloat yrot; // Y Rotation +GLfloat walkbias = 0; +GLfloat walkbiasangle = 0; +GLfloat lookupdown = 0.0f; +GLfloat z=0.0f; // Depth Into The Screen + +GLuint filter; // Which Filter To Use +GLuint texture[3]; // Storage For 3 Textures + +typedef struct tagVERTEX +{ + float x, y, z; + float u, v; +} VERTEX; + +typedef struct tagTRIANGLE +{ + VERTEX vertex[3]; +} TRIANGLE; + +typedef struct tagSECTOR +{ + int numtriangles; + TRIANGLE* triangle; +} SECTOR; + +SECTOR sector1; // Our Model Goes Here: + +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc + +void readstr(FILE *f,char *string) +{ + do + { + fgets(string, 255, f); + } while ((string[0] == '/') || (string[0] == '\n')); + return; +} + +void SetupWorld() +{ + float x, y, z, u, v; + int numtriangles; + FILE *filein; + char oneline[255]; + filein = fopen("data/world.txt", "rt"); // File To Load World Data From + + readstr(filein,oneline); + sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); + + sector1.triangle = new TRIANGLE[numtriangles]; + sector1.numtriangles = numtriangles; + for (int loop = 0; loop < numtriangles; loop++) + { + for (int vert = 0; vert < 3; vert++) + { + readstr(filein,oneline); + sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); + sector1.triangle[loop].vertex[vert].x = x; + sector1.triangle[loop].vertex[vert].y = y; + sector1.triangle[loop].vertex[vert].z = z; + sector1.triangle[loop].vertex[vert].u = u; + sector1.triangle[loop].vertex[vert].v = v; + } + } + fclose(filein); + return; +} + +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 +} + +int LoadGLTextures() // Load Bitmaps And Convert To Textures +{ + int Status=FALSE; // Status Indicator + + AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture + + memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL + + // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit + if (TextureImage[0]=LoadBMP("Data/Mud.bmp")) + { + Status=TRUE; // Set The Status To TRUE + + glGenTextures(3, &texture[0]); // Create Three Textures + + // Create Nearest Filtered Texture + glBindTexture(GL_TEXTURE_2D, texture[0]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); + + // Create Linear Filtered Texture + glBindTexture(GL_TEXTURE_2D, texture[1]); + 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[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); + + // Create MipMapped Texture + glBindTexture(GL_TEXTURE_2D, texture[2]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); + } + if (TextureImage[0]) // If Texture Exists + { + if (TextureImage[0]->data) // If Texture Image Exists + { + free(TextureImage[0]->data); // Free The Texture Image Memory + } + + free(TextureImage[0]); // Free The Image Structure + } + + return Status; // Return The Status +} + +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 +} + +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 + glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency + 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_LESS); // The Type Of Depth Test To Do + 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 + + SetupWorld(); + + return TRUE; // Initialization Went OK +} + +int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer + glLoadIdentity(); // Reset The View + + GLfloat x_m, y_m, z_m, u_m, v_m; + GLfloat xtrans = -xpos; + GLfloat ztrans = -zpos; + GLfloat ytrans = -walkbias-0.25f; + GLfloat sceneroty = 360.0f - yrot; + + int numtriangles; + + glRotatef(lookupdown,1.0f,0,0); + glRotatef(sceneroty,0,1.0f,0); + + glTranslatef(xtrans, ytrans, ztrans); + glBindTexture(GL_TEXTURE_2D, texture[filter]); + + numtriangles = sector1.numtriangles; + + // Process Each Triangle + for (int loop_m = 0; loop_m < numtriangles; loop_m++) + { + glBegin(GL_TRIANGLES); + glNormal3f( 0.0f, 0.0f, 1.0f); + x_m = sector1.triangle[loop_m].vertex[0].x; + y_m = sector1.triangle[loop_m].vertex[0].y; + z_m = sector1.triangle[loop_m].vertex[0].z; + u_m = sector1.triangle[loop_m].vertex[0].u; + v_m = sector1.triangle[loop_m].vertex[0].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + + x_m = sector1.triangle[loop_m].vertex[1].x; + y_m = sector1.triangle[loop_m].vertex[1].y; + z_m = sector1.triangle[loop_m].vertex[1].z; + u_m = sector1.triangle[loop_m].vertex[1].u; + v_m = sector1.triangle[loop_m].vertex[1].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + + x_m = sector1.triangle[loop_m].vertex[2].x; + y_m = sector1.triangle[loop_m].vertex[2].y; + z_m = sector1.triangle[loop_m].vertex[2].z; + u_m = sector1.triangle[loop_m].vertex[2].u; + v_m = sector1.triangle[loop_m].vertex[2].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + glEnd(); + } + return TRUE; // Everything Went OK +} + +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; // Set RC To NULL + } + + if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC + { + MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hDC=NULL; // Set DC To NULL + } + + if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window? + { + MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hWnd=NULL; // Set hWnd To NULL + } + + if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class + { + MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + hInstance=NULL; // Set hInstance To NULL + } +} + +/* This Code Creates Our OpenGL Window. Parameters Are: * + * title - Title To Appear At The Top Of The Window * + * width - Width Of The GL Window Or Fullscreen Mode * + * height - Height Of The GL Window Or Fullscreen Mode * + * bits - Number Of Bits To Use For Color (8/16/24/32) * + * fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */ + +BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) +{ + GLuint PixelFormat; // Holds The Results After Searching For A Match + WNDCLASS wc; // Windows Class Structure + DWORD dwExStyle; // Window Extended Style + DWORD dwStyle; // Window Style + RECT WindowRect; // Grabs 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 = GetModuleHandle(NULL); // Grab An Instance For Our Window + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window. + wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages + wc.cbClsExtra = 0; // No Extra Window Data + wc.cbWndExtra = 0; // No Extra Window Data + wc.hInstance = hInstance; // Set The Instance + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon + wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer + wc.hbrBackground = NULL; // No Background Required For GL + wc.lpszMenuName = NULL; // We Don't Want A Menu + wc.lpszClassName = "OpenGL"; // Set The Class Name + + if (!RegisterClass(&wc)) // Attempt To Register The Window Class + { + MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + if (fullscreen) // Attempt Fullscreen Mode? + { + 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 Use Windowed Mode. + if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + { + fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE + } + else + { + // Pop Up A Message Box Letting User Know The Program Is Closing. + MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP); + return FALSE; // Return FALSE + } + } + } + + if (fullscreen) // Are We Still In Fullscreen Mode? + { + dwExStyle=WS_EX_APPWINDOW; // Window Extended Style + dwStyle=WS_POPUP; // Windows Style + ShowCursor(FALSE); // Hide Mouse Pointer + } + else + { + dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style + dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style + } + + AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size + + // Create The Window + if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window + "OpenGL", // Class Name + title, // Window Title + dwStyle | // Defined Window Style + WS_CLIPSIBLINGS | // Required Window Style + WS_CLIPCHILDREN, // Required Window Style + 0, 0, // Window Position + WindowRect.right-WindowRect.left, // Calculate Window Width + WindowRect.bottom-WindowRect.top, // Calculate Window Height + NULL, // No Parent Window + NULL, // No Menu + hInstance, // Instance + NULL))) // Dont Pass Anything To WM_CREATE + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be + { + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + bits, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // No Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 16, // 16Bit Z-Buffer (Depth Buffer) + 0, // No Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored + }; + + if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context? + { + KillGLWindow(); // Reset The Display + MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + return FALSE; // Return FALSE + } + + 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(hWnd,SW_SHOW); // Show The Window + SetForegroundWindow(hWnd); // Slightly Higher Priority + SetFocus(hWnd); // Sets Keyboard Focus To The Window + ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen + + 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 +} + +LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window + UINT uMsg, // Message For This Window + WPARAM wParam, // Additional Message Information + LPARAM lParam) // Additional Message Information +{ + switch (uMsg) // Check For Windows Messages + { + case WM_ACTIVATE: // Watch For Window Activate Message + { + if (!HIWORD(wParam)) // Check Minimization State + { + active=TRUE; // Program Is Active + } + else + { + active=FALSE; // Program Is No Longer Active + } + + return 0; // Return To The Message Loop + } + + case WM_SYSCOMMAND: // Intercept System Commands + { + switch (wParam) // Check System Calls + { + case SC_SCREENSAVE: // Screensaver Trying To Start? + case SC_MONITORPOWER: // Monitor Trying To Enter Powersave? + return 0; // Prevent From Happening + } + break; // Exit + } + + case WM_CLOSE: // Did We Receive A Close Message? + { + PostQuitMessage(0); // Send A Quit Message + return 0; // Jump Back + } + + case WM_KEYDOWN: // Is A Key Being Held Down? + { + keys[wParam] = TRUE; // If So, Mark It As TRUE + return 0; // Jump Back + } + + case WM_KEYUP: // Has A Key Been Released? + { + keys[wParam] = FALSE; // If So, Mark It As FALSE + return 0; // Jump Back + } + + 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); +} + +int WINAPI WinMain( HINSTANCE hInstance, // Instance + HINSTANCE hPrevInstance, // Previous Instance + LPSTR lpCmdLine, // Command Line Parameters + int nCmdShow) // Window Show State +{ + MSG msg; // Windows Message Structure + BOOL done=FALSE; // Bool Variable To Exit Loop + + // Ask The User Which Screen Mode They Prefer + if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) + { + fullscreen=FALSE; // Windowed Mode + } + + // Create Our OpenGL Window + if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial",640,480,16,fullscreen)) + { + return 0; // Quit If Window Was Not Created + } + + while(!done) // Loop That Runs While done=FALSE + { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? + { + if (msg.message==WM_QUIT) // Have We Received A Quit Message? + { + done=TRUE; // If So done=TRUE + } + else // If Not, Deal With Window Messages + { + TranslateMessage(&msg); // Translate The Message + DispatchMessage(&msg); // Dispatch The Message + } + } + else // If There Are No Messages + { + // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() + if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received? + { + done=TRUE; // ESC or DrawGLScene Signalled A Quit + } + else // Not Time To Quit, Update Screen + { + SwapBuffers(hDC); // Swap Buffers (Double Buffering) + if (keys['B'] && !bp) + { + bp=TRUE; + blend=!blend; + if (!blend) + { + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } + else + { + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } + } + if (!keys['B']) + { + bp=FALSE; + } + + if (keys['F'] && !fp) + { + fp=TRUE; + filter+=1; + if (filter>2) + { + filter=0; + } + } + if (!keys['F']) + { + fp=FALSE; + } + + if (keys[VK_PRIOR]) + { + z-=0.02f; + } + + if (keys[VK_NEXT]) + { + z+=0.02f; + } + + if (keys[VK_UP]) + { + + xpos -= (float)sin(heading*piover180) * 0.05f; + zpos -= (float)cos(heading*piover180) * 0.05f; + if (walkbiasangle >= 359.0f) + { + walkbiasangle = 0.0f; + } + else + { + walkbiasangle+= 10; + } + walkbias = (float)sin(walkbiasangle * piover180)/20.0f; + } + + if (keys[VK_DOWN]) + { + xpos += (float)sin(heading*piover180) * 0.05f; + zpos += (float)cos(heading*piover180) * 0.05f; + if (walkbiasangle <= 1.0f) + { + walkbiasangle = 359.0f; + } + else + { + walkbiasangle-= 10; + } + walkbias = (float)sin(walkbiasangle * piover180)/20.0f; + } + + if (keys[VK_RIGHT]) + { + heading -= 1.0f; + yrot = heading; + } + + if (keys[VK_LEFT]) + { + heading += 1.0f; + yrot = heading; + } + + if (keys[VK_PRIOR]) + { + lookupdown-= 1.0f; + } + + if (keys[VK_NEXT]) + { + lookupdown+= 1.0f; + } + + if (keys[VK_F1]) // Is F1 Being Pressed? + { + keys[VK_F1]=FALSE; // If So Make Key FALSE + KillGLWindow(); // Kill Our Current Window + fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode + // Recreate Our OpenGL Window + if (!CreateGLWindow("Lionel Brits & NeHe's 3D World Tutorial",640,480,16,fullscreen)) + { + return 0; // Quit If Window Was Not Created + } + } + } + } + } + + // Shutdown + KillGLWindow(); // Kill The Window + return (msg.wParam); // Exit The Program +} diff --git a/Lesson10.dsp b/Lesson10.dsp new file mode 100644 index 0000000..855997e --- /dev/null +++ b/Lesson10.dsp @@ -0,0 +1,107 @@ +# Microsoft Developer Studio Project File - Name="lesson10" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=lesson10 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lesson10.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lesson10.mak" CFG="lesson10 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lesson10 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "lesson10 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lesson10 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "lesson10 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lesson10 - Win32 Release" +# Name "lesson10 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\lesson10.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/Lesson10.dsw b/Lesson10.dsw new file mode 100644 index 0000000..522cb9f --- /dev/null +++ b/Lesson10.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lesson10"=.\lesson10.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Lesson10.exe b/Lesson10.exe new file mode 100644 index 0000000..0c43faa Binary files /dev/null and b/Lesson10.exe differ diff --git a/NeHe's Readme.txt b/NeHe's Readme.txt new file mode 100644 index 0000000..9148fc7 --- /dev/null +++ b/NeHe's Readme.txt @@ -0,0 +1,16 @@ +========================================================================== + OpenGL Lesson 10: Loading And Moving Through A 3D World +========================================================================== + + Authors Name: Lionel Brits + + Disclaimer: + + This program may crash your system or run poorly depending on your + hardware. The program and code contained in this archive was scanned + for virii and has passed all test before it was put online. If you + use this code in project of your own, send a shout out to the author! + +========================================================================== + NeHe Productions 1997-2004 +==========================================================================