www.pudn.com > 13_184353_cubemap.rar > main.cpp
/* * This Code Was Created By Jeff Molofee 2000 * A HUGE Thanks To Fredric Echols For Cleaning Up * And Optimizing This 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 // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #include // Header File For The Glaux Library #include "GLext.h" #include "3DS.h" #include "Camera.h" #include #include //Let us use CG Language #include #include 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 int fps; CCamera cam; float eyePosition[3]; float updirection[3]; t3DModel gundam; int state(0); //refer to render state; GLuint base; // Base Display List For The Font Set char* brand=NULL; char* vendor=NULL; char* version=NULL; float last_time(0); //texture for each face GLuint cubeface[6]; //texture for cubemap GLuint cubemap; //Variables for CG CGprofile g_CGprofile_vertex; CGprofile g_CGprofile_pixel; CGcontext g_CGcontext; //reflection effect program CGprogram g_CGreflection_vertex; CGprogram g_CGreflection_pixel; CGprogram g_CGrefraction_vertex; CGprogram g_CGrefraction_pixel; CGprogram g_CGdispersion_vertex; CGprogram g_CGdispersion_pixel; void InitCG() { // // Search for a valid vertex shader profile in this order: // // CG_PROFILE_ARBVP1 - GL_ARB_vertex_program // CG_PROFILE_VP40 - GL_ARB_vertex_program + GL_NV_vertex_program3 // if( cgGLIsProfileSupported(CG_PROFILE_ARBVP1) ) g_CGprofile_vertex = CG_PROFILE_ARBVP1; else if( cgGLIsProfileSupported(CG_PROFILE_VP40) ) g_CGprofile_vertex = CG_PROFILE_VP40; else { MessageBox( NULL,"Failed to initialize vertex shader! Hardware doesn't " "support any of the required vertex shading extensions!", "ERROR",MB_OK|MB_ICONEXCLAMATION ); return; } // // Search for a valid pixel shader profile in this order: // // CG_PROFILE_ARBFP1 - GL_ARB_fragment_program // CG_PROFILE_FP30 - GL_NV_fragment_program // CG_PROFILE_FP20 - NV_texture_shader & NV_register_combiners // if( cgGLIsProfileSupported(CG_PROFILE_ARBFP1) ) g_CGprofile_pixel = CG_PROFILE_ARBFP1; else if( cgGLIsProfileSupported(CG_PROFILE_FP30) ) g_CGprofile_pixel = CG_PROFILE_FP30; else if( cgGLIsProfileSupported(CG_PROFILE_FP20) ) g_CGprofile_pixel = CG_PROFILE_FP20; else { MessageBox( NULL,"Failed to initialize pixel shader! Hardware doesn't " "support any of the required pixel shading extensions!", "ERROR",MB_OK|MB_ICONEXCLAMATION ); return; } // Create the context... g_CGcontext = cgCreateContext(); // // Create the vertex and pixel shader... // g_CGreflection_vertex = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "vertex_reflection.cg", g_CGprofile_vertex, NULL, NULL ); g_CGreflection_pixel = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "pixel_reflection.cg", g_CGprofile_pixel, NULL, NULL ); g_CGrefraction_vertex = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "vertex_refraction.cg", g_CGprofile_vertex, NULL, NULL ); g_CGrefraction_pixel = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "pixel_refraction.cg", g_CGprofile_pixel, NULL, NULL ); g_CGdispersion_vertex = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "vertex_dispersion.cg", g_CGprofile_vertex, NULL, NULL ); g_CGdispersion_pixel = cgCreateProgramFromFile( g_CGcontext, CG_SOURCE, "pixel_dispersion.cg", g_CGprofile_pixel, NULL, NULL ); // // Load the programs using Cg's expanded interface... // cgGLLoadProgram( g_CGreflection_vertex ); cgGLLoadProgram( g_CGreflection_pixel ); cgGLLoadProgram( g_CGrefraction_vertex ); cgGLLoadProgram( g_CGrefraction_pixel ); cgGLLoadProgram( g_CGdispersion_vertex ); cgGLLoadProgram( g_CGdispersion_pixel ); // // Bind some parameters by name so we can set them later... // } //画这个模型 void DrawModel(t3DModel& Model) { // 遍历模型中所有的对象 for(int i = 0; i < Model.numOfObjects; i++) { // 如果对象的大小小于0,则退出 if(Model.pObject.size() <= 0) break; // 获得当前显示的对象 t3DObject *pObject = &Model.pObject[i]; // 判断该对象是否有纹理映射 if(pObject->bHasTexture) { // 打开纹理映射 glEnable(GL_TEXTURE_2D); glColor3ub(255, 255, 255); glBindTexture(GL_TEXTURE_2D, Model.texture[pObject->materialID]); } else { // 关闭纹理映射 glDisable(GL_TEXTURE_2D); glColor3ub(255, 255, 255); } // 开始以g_ViewMode模式绘制 glBegin(GL_TRIANGLES); // 遍历所有的面 for(int j = 0; j < pObject->numOfFaces; j++) { // 遍历三角形的所有点 for(int whichVertex = 0; whichVertex < 3; whichVertex++) { // 获得面对每个点的索引 int index = pObject->pFaces[j].vertIndex[whichVertex]; // 给出法向量 glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z); // 如果对象具有纹理 if(pObject->bHasTexture) { // 确定是否有UVW纹理坐标 if(pObject->pTexVerts) { glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y); } } else { if(Model.pMaterials.size() && pObject->materialID >= 0) { BYTE *pColor = Model.pMaterials[pObject->materialID].color; glColor3ub(pColor[0], pColor[1], pColor[2]); } } glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z); } } glEnd(); // 绘制结束 } } //--------------------------------------------------------------------------- // get the millseconds from the demo start - time line //--------------------------------------------------------------------------- float GetTime() { static bool init = false; static bool hires = false; static __int64 freq = 1; if(!init) { hires = !QueryPerformanceFrequency((LARGE_INTEGER *)&freq); if(!hires) freq = 1000; init = true; } __int64 now; if(hires) QueryPerformanceCounter((LARGE_INTEGER *)&now); else now = GetTickCount(); return (float)((double)now / (double)freq); } GLvoid BuildFont(GLvoid) // Build Our Bitmap Font { HFONT font; // Windows Font ID HFONT oldfont; // Used For Good House Keeping base = glGenLists(96); // Storage For 96 Characters font = CreateFont( -15, // Height Of Font 0, // Width Of Font 0, // Angle Of Escapement 0, // Orientation Angle FW_BOLD, // Font Weight FALSE, // Italic FALSE, // Underline FALSE, // Strikeout ANSI_CHARSET, // Character Set Identifier OUT_TT_PRECIS, // Output Precision CLIP_DEFAULT_PRECIS, // Clipping Precision ANTIALIASED_QUALITY, // Output Quality FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch "Arial"); // Font Name oldfont = (HFONT)SelectObject(hDC, font); // Selects The Font We Want wglUseFontBitmaps(hDC, 32, 96, base); // Builds 96 Characters Starting At Character 32 SelectObject(hDC, oldfont); // Selects The Font We Want DeleteObject(font); // Delete The Font } GLvoid KillFont(GLvoid) // Delete The Font List { glDeleteLists(base, 96); // Delete All 96 Characters } GLvoid glPrint(const char *fmt, ...) // Custom GL "Print" Routine { char text[256]; // Holds Our String va_list ap; // Pointer To List Of Arguments if (fmt == NULL) // If There's No Text return; // Do Nothing va_start(ap, fmt); // Parses The String For Variables vsprintf(text, fmt, ap); // And Converts Symbols To Actual Numbers va_end(ap); // Results Are Stored In Text glPushAttrib(GL_LIST_BIT); // Pushes The Display List Bits glListBase(base - 32); // Sets The Base Character to 32 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // Draws The Display List Text glPopAttrib(); // Pops The Display List Bits } 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 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc 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,99999.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix } BOOL LoadCubeMap(GLenum face, LPSTR szPathName) { HDC hdcTemp; // The DC To Hold Our Bitmap HBITMAP hbmpTemp; // Holds The Bitmap Temporarily IPicture *pPicture; // IPicture Interface OLECHAR wszPath[MAX_PATH+1]; // Full Path To Picture (WCHAR) char szPath[MAX_PATH+1]; // Full Path To Picture long lWidth; // Width In Logical Units long lHeight; // Height In Logical Units long lWidthPixels; // Width In Pixels long lHeightPixels; // Height In Pixels GLint glMaxTexDim ; // Holds Maximum Texture Size if (strstr(szPathName, "http://")) // If PathName Contains http:// Then... { strcpy(szPath, szPathName); // Append The PathName To szPath } else // Otherwise... We Are Loading From A File { GetCurrentDirectory(MAX_PATH, szPath); // Get Our Working Directory strcat(szPath, "\\"); // Append "\" After The Working Directory strcat(szPath, szPathName); // Append The PathName } MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); // Convert From ASCII To Unicode HRESULT hr = OleLoadPicturePath(wszPath, 0, 0, 0, IID_IPicture, (void**)&pPicture); if(FAILED(hr)) // If Loading Failed return FALSE; // Return False hdcTemp = CreateCompatibleDC(GetDC(0)); // Create The Windows Compatible Device Context if(!hdcTemp) // Did Creation Fail? { pPicture->Release(); // Decrements IPicture Reference Count return FALSE; // Return False (Failure) } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTexDim); // Get Maximum Texture Size Supported pPicture->get_Width(&lWidth); // Get IPicture Width (Convert To Pixels) lWidthPixels = MulDiv(lWidth, GetDeviceCaps(hdcTemp, LOGPIXELSX), 2540); pPicture->get_Height(&lHeight); // Get IPicture Height (Convert To Pixels) lHeightPixels = MulDiv(lHeight, GetDeviceCaps(hdcTemp, LOGPIXELSY), 2540); // Resize Image To Closest Power Of Two if (lWidthPixels <= glMaxTexDim) // Is Image Width Less Than Or Equal To Cards Limit lWidthPixels = 1 << (int)floor((log((double)lWidthPixels)/log(2.0f)) + 0.5f); else // Otherwise Set Width To "Max Power Of Two" That The Card Can Handle lWidthPixels = glMaxTexDim; if (lHeightPixels <= glMaxTexDim) // Is Image Height Greater Than Cards Limit lHeightPixels = 1 << (int)floor((log((double)lHeightPixels)/log(2.0f)) + 0.5f); else // Otherwise Set Height To "Max Power Of Two" That The Card Can Handle lHeightPixels = glMaxTexDim; // Create A Temporary Bitmap BITMAPINFO bi = {0}; // The Type Of Bitmap We Request DWORD *pBits = 0; // Pointer To The Bitmap Bits bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); // Set Structure Size bi.bmiHeader.biBitCount = 32; // 32 Bit bi.bmiHeader.biWidth = lWidthPixels; // Power Of Two Width bi.bmiHeader.biHeight = lHeightPixels; // Make Image Top Up (Positive Y-Axis) bi.bmiHeader.biCompression = BI_RGB; // RGB Encoding bi.bmiHeader.biPlanes = 1; // 1 Bitplane // Creating A Bitmap This Way Allows Us To Specify Color Depth And Gives Us Imediate Access To The Bits hbmpTemp = CreateDIBSection(hdcTemp, &bi, DIB_RGB_COLORS, (void**)&pBits, 0, 0); if(!hbmpTemp) // Did Creation Fail? { DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count return FALSE; // Return False (Failure) } SelectObject(hdcTemp, hbmpTemp); // Select Handle To Our Temp DC And Our Temp Bitmap Object // Render The IPicture On To The Bitmap pPicture->Render(hdcTemp, 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0); // Convert From BGR To RGB Format And Add An Alpha Value Of 255 for(long i = 0; i < lWidthPixels * lHeightPixels; i++) // Loop Through All Of The Pixels { BYTE* pPixel = (BYTE*)(&pBits[i]); // Grab The Current Pixel BYTE temp = pPixel[0]; // Store 1st Color In Temp Variable (Blue) pPixel[0] = pPixel[2]; // Move Red Value To Correct Position (1st) pPixel[2] = temp; // Move Temp Value To Correct Blue Position (3rd) // This Will Make Any Black Pixels, Completely Transparent (You Can Hardcode The Value If You Wish) if ((pPixel[0]==0) && (pPixel[1]==0) && (pPixel[2]==0)) // Is Pixel Completely Black pPixel[3] = 0; // Set The Alpha Value To 0 else // Otherwise pPixel[3] = 255; // Set The Alpha Value To 255 } // glGenTextures(1, &texid); // Create The Texture // Typical Texture Generation Using Data From The Bitmap // glBindTexture(GL_TEXTURE_2D, texid); // Bind To The Texture ID // glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want) // glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // (Modify This For The Type Of Filtering You Want) // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits); // (Modify This If You Want Mipmaps) glTexImage2D(face, 0, GL_RGBA, lWidthPixels, lHeightPixels, 0, GL_RGBA, GL_UNSIGNED_BYTE, pBits); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); DeleteObject(hbmpTemp); // Delete The Object DeleteDC(hdcTemp); // Delete The Device Context pPicture->Release(); // Decrements IPicture Reference Count } void LoadTextures() { char Extension_Name[] = "GL_EXT_texture_cube_map"; // Allocate Memory For Our Extension String char* glextstring=(char *)malloc(strlen((char *)glGetString(GL_EXTENSIONS))+1); strcpy (glextstring,(char *)glGetString(GL_EXTENSIONS)); // Grab The Extension List, Store In glextstring if (!strstr(glextstring,Extension_Name)) // Check To See If The Extension Is Supported { MessageBox(NULL, "Your renderer cannot support GL_EXT_texture_cube_map!", "Error", MB_OK); exit(0); // If Not, Return FALSE } free(glextstring); // Free Allocated Memory glGenTextures(1, &cubemap); glBindTexture(GL_TEXTURE_CUBE_MAP_EXT, cubemap); LoadCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, "lobbyxpos.jpg"); LoadCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, "lobbyxneg.jpg"); LoadCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, "lobbyypos.jpg"); LoadCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, "lobbyyneg.jpg"); LoadCubeMap(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, "lobbyzpos.jpg"); LoadCubeMap(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, "lobbyzneg.jpg"); CLoad3DS* loader=new(CLoad3DS); loader->BuildTexture("lobbyxpos.jpg", cubeface[0]); loader->BuildTexture("lobbyxneg.jpg", cubeface[1]); loader->BuildTexture("lobbyypos.jpg", cubeface[2]); loader->BuildTexture("lobbyyneg.jpg", cubeface[3]); loader->BuildTexture("lobbyzpos.jpg", cubeface[4]); loader->BuildTexture("lobbyzneg.jpg", cubeface[5]); delete loader; } void CubeBox() { glDisable(GL_LIGHTING); glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, cubeface[0]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(1000, 1000, 1000); glTexCoord2i(0, 0); glVertex3i(1000, -1000, 1000); glTexCoord2i(1, 0); glVertex3i(1000, -1000, -1000); glTexCoord2i(1, 1); glVertex3i(1000, 1000, -1000); glEnd(); glBindTexture(GL_TEXTURE_2D, cubeface[1]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(-1000, 1000, -1000); glTexCoord2i(0, 0); glVertex3i(-1000, -1000, -1000); glTexCoord2i(1, 0); glVertex3i(-1000, -1000, 1000); glTexCoord2i(1, 1); glVertex3i(-1000, 1000, 1000); glEnd(); glBindTexture(GL_TEXTURE_2D, cubeface[2]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(-1000, 1000, -1000); glTexCoord2i(0, 0); glVertex3i(-1000, 1000, 1000); glTexCoord2i(1, 0); glVertex3i(1000, 1000,1000); glTexCoord2i(1, 1); glVertex3i(1000, 1000, -1000); glEnd(); glBindTexture(GL_TEXTURE_2D, cubeface[3]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(-1000, -1000, 1000); glTexCoord2i(0, 0); glVertex3i(-1000, -1000, -1000); glTexCoord2i(1, 0); glVertex3i(1000, -1000,-1000); glTexCoord2i(1, 1); glVertex3i(1000, -1000, 1000); glEnd(); glBindTexture(GL_TEXTURE_2D, cubeface[4]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(-1000, 1000, 1000); glTexCoord2i(0, 0); glVertex3i(-1000,-1000, 1000); glTexCoord2i(1, 0); glVertex3i(1000, -1000, 1000); glTexCoord2i(1, 1); glVertex3i(1000, 1000, 1000); glEnd(); glBindTexture(GL_TEXTURE_2D, cubeface[5]); glBegin(GL_QUADS); glTexCoord2i(0, 1); glVertex3i(1000, 1000, -1000); glTexCoord2i(0, 0); glVertex3i(1000, -1000, -1000); glTexCoord2i(1, 0); glVertex3i(-1000, -1000, -1000); glTexCoord2i(1, 1); glVertex3i(-1000, 1000, -1000); glEnd(); glDisable(GL_TEXTURE_2D); } void EyeMove() { static float angle1=0.0f; eyePosition[0]=600.0f*sin(angle1); eyePosition[1]=600.0f*sin(angle1/4.0f); eyePosition[2]=600.0f*cos(angle1); angle1+=0.01f; } GLuint model; void Scene(); int InitGL(GLvoid) // All Setup For OpenGL Goes Here { //get the info of your renderer brand=(char*)glGetString(GL_RENDERER); vendor=(char*)glGetString(GL_VENDOR); version=(char*)glGetString(GL_VERSION); glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations BuildFont(); // cam.PositionCamera(0.0f, 0.0f, 800.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); LoadTextures(); CLoad3DS* loader=new(CLoad3DS); loader->Import3DS(&gundam, "GUNDAM91.3DS"); delete loader; model=glGenLists(1); glNewList(model, GL_COMPILE); DrawModel(gundam); glEndList(); InitCG(); return TRUE; // Initialization Went OK } void Dispersion() { //cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGreflection_vertex, "modelViewProj"), CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGdispersion_vertex, "modelToWorld"), CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY ); // Identify the texture to use cgGLSetTextureParameter(cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap0"), cubemap ); cgGLSetTextureParameter(cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap1"), cubemap ); cgGLSetTextureParameter(cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap2"), cubemap ); cgGLSetTextureParameter(cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap3"), cubemap ); cgGLSetParameter3fv(cgGetNamedParameter(g_CGdispersion_vertex, "eyePositionW"), eyePosition); cgGLBindProgram( g_CGdispersion_vertex ); cgGLEnableProfile( g_CGprofile_vertex ); cgGLBindProgram( g_CGdispersion_pixel ); cgGLEnableProfile( g_CGprofile_pixel ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap0") ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap1") ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap2") ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap3") ); glCallList(model); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap0") ); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap1") ); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap2") ); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGdispersion_pixel, "environmentMap3") ); cgGLDisableProfile( g_CGprofile_vertex ); cgGLDisableProfile( g_CGprofile_pixel ); } void Refraction() { //cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGreflection_vertex, "modelViewProj"), CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGrefraction_vertex, "modelToWorld"), CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY ); // Identify the texture to use cgGLSetTextureParameter(cgGetNamedParameter(g_CGrefraction_pixel, "environmentMap"), cubemap ); cgGLSetParameter3fv(cgGetNamedParameter(g_CGrefraction_vertex, "eyePositionW"), eyePosition); cgGLBindProgram( g_CGrefraction_vertex ); cgGLEnableProfile( g_CGprofile_vertex ); cgGLBindProgram( g_CGrefraction_pixel ); cgGLEnableProfile( g_CGprofile_pixel ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGrefraction_pixel, "environmentMap") ); glCallList(model); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGrefraction_pixel, "environmentMap") ); cgGLDisableProfile( g_CGprofile_vertex ); cgGLDisableProfile( g_CGprofile_pixel ); } void Reflection() { //cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGreflection_vertex, "modelViewProj"), CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY); cgGLSetStateMatrixParameter(cgGetNamedParameter(g_CGreflection_vertex, "modelToWorld"), CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY ); // Identify the texture to use cgGLSetTextureParameter(cgGetNamedParameter(g_CGreflection_pixel, "environmentMap"), cubemap ); cgGLSetParameter3fv(cgGetNamedParameter(g_CGreflection_vertex, "eyePositionW"), eyePosition); cgGLBindProgram( g_CGreflection_vertex ); cgGLEnableProfile( g_CGprofile_vertex ); cgGLBindProgram( g_CGreflection_pixel ); cgGLEnableProfile( g_CGprofile_pixel ); cgGLEnableTextureParameter( cgGetNamedParameter(g_CGreflection_pixel, "environmentMap") ); glCallList(model); cgGLDisableTextureParameter( cgGetNamedParameter(g_CGreflection_pixel, "environmentMap") ); cgGLDisableProfile( g_CGprofile_vertex ); cgGLDisableProfile( g_CGprofile_pixel ); } void Scene() { glCallList(model); } int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing { static int counter=0; if(fps==0) fps=72; if(GetTime()-last_time>=1.0f) { fps=counter; counter=0; last_time=GetTime(); } counter++; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer glLoadIdentity(); // Reset The Current Modelview Matrix EyeMove(); gluLookAt(eyePosition[0], eyePosition[1], eyePosition[2], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); // cam.SetViewByMouse(); //cam.CheckForMovement(); //cam.Update(); //cam.Look(); CubeBox(); if(state==0) Reflection(); if(state==1) Refraction(); if(state==2) Dispersion(); glLoadIdentity(); glColor3f(1.0f, 1.0f, 1.0f); glTranslatef(0.0f,0.0f,-1.0f); // Move One Unit Into The Screen glRasterPos2f(-0.52f, 0.36f); glPrint("Enviroment mapping demo"); // Print GL Text To The Screen glRasterPos2f(-0.52f, 0.33f); glPrint("1 - reflection effect"); glRasterPos2f(-0.52f, 0.30f); glPrint("2 - refraction effect"); glRasterPos2f(-0.52f, 0.27f); glPrint("3 - dispersion effect"); glRasterPos2f(-0.52f, -0.30f); glPrint("Renderer:%s", brand); glRasterPos2f(-0.52f, -0.33f); glPrint("Vendor:%s", vendor); glRasterPos2f(-0.52f, -0.36f); glPrint("Version:%s", version); glRasterPos2f(0.38f, -0.37f); glPrint("FPS:%d", fps); if(state==0) { glRasterPos2f(0.10f, 0.36f); glPrint("REFLECTION EFFECT"); } if(state==1) { glRasterPos2f(0.10f, 0.36f); glPrint("REFRACTION EFFECT"); } if(state==2) { glRasterPos2f(0.10f, 0.36f); glPrint("DISPERSION EFFECT"); } return TRUE; // Everything Went OK } GLvoid KillGLWindow(GLvoid) // Properly Kill The Window { cgDestroyProgram(g_CGreflection_vertex); cgDestroyProgram(g_CGreflection_pixel); cgDestroyProgram(g_CGrefraction_vertex); cgDestroyProgram(g_CGrefraction_pixel); cgDestroyProgram(g_CGdispersion_vertex); cgDestroyProgram(g_CGdispersion_pixel); cgDestroyContext(g_CGcontext); KillFont(); 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("www.azure.com",640,480,32,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) // Program Active? { if (keys[VK_ESCAPE]) // Was ESC Pressed? { done=TRUE; // ESC Signalled A Quit } else // Not Time To Quit, Update Screen { DrawGLScene(); // Draw The Scene SwapBuffers(hDC); // Swap Buffers (Double Buffering) } if (keys['1']) state=0; if (keys['2']) state=1; if (keys['3']) state=2; } } } // Shutdown KillGLWindow(); // Kill The Window return (msg.wParam); // Exit The Program }