////////////////////////////////////////////////////////////////// // This function does any needed initialization on the rendering // context. void SetupRC() { int iSphere; // Calculate shadow matrix M3DVector3f vPoints[3] = {{ 0.0f, -0.4f, 0.0f }, { 10.0f, -0.4f, 0.0f }, { 5.0f, -0.4f, -5.0f }}; // Grayish background glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]); // Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Get the plane equation from three points on the ground M3DVector4f vPlaneEquation; m3dGetPlaneEquation(vPlaneEquation, vPoints[0], vPoints[1], vPoints[2]); // Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(mShadowMatrix, vPlaneEquation, fLightPos); // Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); // Randomly place the sphere inhabitants for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++) { spheres[iSphere].SetOrigin((float)((rand() % 400) - 200) * 0.1f, 0.0f, (float)((rand() % 400) - 200) * 0.1f); } glEnable(GL_MULTISAMPLE); // This is actually on by default }
// Called to draw scene void RenderScene(void) { M3DMatrix44f mCubeTransform; M3DVector4f pPlane; // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); glPushMatrix(); // Draw plane that the cube rests on glDisable(GL_LIGHTING); if(nStep == 5) { glColor3ub(255,255,255); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures[0]); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-100.0f, -25.3f, -100.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-100.0f, -25.3f, 100.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(100.0f, -25.3f, 100.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(100.0f, -25.3f, -100.0f); glEnd(); } else { glColor3f(0.0f, 0.0f, 0.90f); // Blue glBegin(GL_QUADS); glVertex3f(-100.0f, -25.3f, -100.0f); glVertex3f(-100.0f, -25.3f, 100.0f); glVertex3f(100.0f, -25.3f, 100.0f); glVertex3f(100.0f, -25.3f, -100.0f); glEnd(); } // Set drawing color to Red glColor3f(1.0f, 0.0f, 0.0f); // Enable, disable lighting if(nStep > 2) { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_COLOR_MATERIAL); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glMaterialfv(GL_FRONT, GL_SPECULAR,lightSpecular); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColor); glMateriali(GL_FRONT, GL_SHININESS,128); } // Move the cube slightly forward and to the left glTranslatef(-10.0f, 0.0f, 10.0f); switch(nStep) { // Just draw the wire framed cube case 0: glutWireCube(50.0f); break; // Same wire cube with hidden line removal simulated case 1: // Front Face (before rotation) glBegin(GL_LINES); glVertex3f(25.0f,25.0f,25.0f); glVertex3f(25.0f,-25.0f,25.0f); glVertex3f(25.0f,-25.0f,25.0f); glVertex3f(-25.0f,-25.0f,25.0f); glVertex3f(-25.0f,-25.0f,25.0f); glVertex3f(-25.0f,25.0f,25.0f); glVertex3f(-25.0f,25.0f,25.0f); glVertex3f(25.0f,25.0f,25.0f); glEnd(); // Top of cube glBegin(GL_LINES); // Front Face glVertex3f(25.0f,25.0f,25.0f); glVertex3f(25.0f,25.0f,-25.0f); glVertex3f(25.0f,25.0f,-25.0f); glVertex3f(-25.0f,25.0f,-25.0f); glVertex3f(-25.0f,25.0f,-25.0f); glVertex3f(-25.0f,25.0f,25.0f); glVertex3f(-25.0f,25.0f,25.0f); glVertex3f(25.0f,25.0f,25.0f); glEnd(); // Last two segments for effect glBegin(GL_LINES); glVertex3f(25.0f,25.0f,-25.0f); glVertex3f(25.0f,-25.0f,-25.0f); glVertex3f(25.0f,-25.0f,-25.0f); glVertex3f(25.0f,-25.0f,25.0f); glEnd(); break; // Uniform colored surface, looks 2D and goofey case 2: glutSolidCube(50.0f); break; case 3: glutSolidCube(50.0f); break; // Draw a shadow with some lighting case 4: glGetFloatv(GL_MODELVIEW_MATRIX, mCubeTransform); glutSolidCube(50.0f); glPopMatrix(); // Disable lighting, we'll just draw the shadow as black glDisable(GL_LIGHTING); glPushMatrix(); m3dGetPlaneEquation(pPlane, ground[0], ground[1], ground[2]); m3dMakePlanarShadowMatrix(mCubeTransform, pPlane, vLightPos); //MakeShadowMatrix(ground, lightpos, cubeXform); glMultMatrixf(mCubeTransform); glTranslatef(-10.0f, 0.0f, 10.0f); // Set drawing color to Black glColor3f(0.0f, 0.0f, 0.0f); glutSolidCube(50.0f); break; case 5: glColor3ub(255,255,255); glGetFloatv(GL_MODELVIEW_MATRIX, mCubeTransform); // Front Face (before rotation) glBindTexture(GL_TEXTURE_2D, textures[1]); glBegin(GL_QUADS); glTexCoord2f(1.0f, 1.0f); glVertex3f(25.0f,25.0f,25.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(25.0f,-25.0f,25.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-25.0f,-25.0f,25.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-25.0f,25.0f,25.0f); glEnd(); // Top of cube glBindTexture(GL_TEXTURE_2D, textures[2]); glBegin(GL_QUADS); // Front Face glTexCoord2f(0.0f, 0.0f); glVertex3f(25.0f,25.0f,25.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(25.0f,25.0f,-25.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(-25.0f,25.0f,-25.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-25.0f,25.0f,25.0f); glEnd(); // Last two segments for effect glBindTexture(GL_TEXTURE_2D, textures[3]); glBegin(GL_QUADS); glTexCoord2f(1.0f, 1.0f); glVertex3f(25.0f,25.0f,-25.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(25.0f,-25.0f,-25.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(25.0f,-25.0f,25.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(25.0f,25.0f,25.0f); glEnd(); glPopMatrix(); // Disable lighting, we'll just draw the shadow as black glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glPushMatrix(); m3dGetPlaneEquation(pPlane, ground[0], ground[1], ground[2]); m3dMakePlanarShadowMatrix(mCubeTransform, pPlane, vLightPos); glMultMatrixf(mCubeTransform); glTranslatef(-10.0f, 0.0f, 10.0f); // Set drawing color to Black glColor3f(0.0f, 0.0f, 0.0f); glutSolidCube(50.0f); break; } glPopMatrix(); // Flush drawing commands glutSwapBuffers(); }
/////////////////////////////////////////////////////////////////////////////// // Setup. Create font/bitmaps, load textures, create display lists void SetupRC(HDC hDC) { M3DVector3f vPoints[3] = {{ 0.0f, -0.4f, 0.0f }, { 10.0f, -0.4f, 0.0f }, { 5.0f, -0.4f, -5.0f } }; int iSphere; int i; // Setup the Font characteristics HFONT hFont; LOGFONT logfont; logfont.lfHeight = -20; logfont.lfWidth = 0; logfont.lfEscapement = 0; logfont.lfOrientation = 0; logfont.lfWeight = FW_BOLD; logfont.lfItalic = FALSE; logfont.lfUnderline = FALSE; logfont.lfStrikeOut = FALSE; logfont.lfCharSet = ANSI_CHARSET; logfont.lfOutPrecision = OUT_DEFAULT_PRECIS; logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logfont.lfQuality = DEFAULT_QUALITY; logfont.lfPitchAndFamily = DEFAULT_PITCH; strcpy(logfont.lfFaceName,"Arial"); // Create the font and display list hFont = CreateFontIndirect(&logfont); SelectObject (hDC, hFont); //Create display lists for glyphs 0 through 128 nFontList = glGenLists(128); wglUseFontBitmaps(hDC, 0, 128, nFontList); DeleteObject(hFont); // Don't need original font anymore // Grayish background glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]); // Clear stencil buffer with zero, increment by one whenever anybody // draws into it. When stencil function is enabled, only write where // stencil value is zero. This prevents the transparent shadow from drawing // over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR); glClearStencil(0); glStencilFunc(GL_EQUAL, 0x0, 0x01); // Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Calculate shadow matrix M3DVector4f pPlane; m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]); m3dMakePlanarShadowMatrix(mShadowMatrix, pPlane, fLightPos); // Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); // Randomly place the sphere inhabitants for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++) { // Pick a random location between -20 and 20 at .1 increments spheres[iSphere].SetOrigin((float)((rand() % 400) - 200) * 0.1f, 0.0f, (float)((rand() % 400) - 200) * 0.1f); } // Set up texture maps glEnable(GL_TEXTURE_2D); glGenTextures(NUM_TEXTURES, textureObjects); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // Load teach texture for(i = 0; i < NUM_TEXTURES; i++) { GLbyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; glBindTexture(GL_TEXTURE_2D, textureObjects[i]); // Load this texture map pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat); gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); free(pBytes); // Trilinear mipmapping glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } // Get window position function pointer if it exists glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress("glWindowPos2i"); // Get swap interval function pointer if it exists wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); if(wglSwapIntervalEXT != NULL && startupOptions.bVerticalSync == TRUE) wglSwapIntervalEXT(1); // If multisampling was available and was selected, enable if(startupOptions.bFSAA == TRUE && startupOptions.nPixelFormatMS != 0) glEnable(GL_MULTISAMPLE_ARB); // If sepearate specular color is available, make torus shiney if(gltIsExtSupported("GL_EXT_separate_specular_color")) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); // Initialize the timers QueryPerformanceFrequency(&CounterFrequency); QueryPerformanceCounter(&FPSCount); CameraTimer = FPSCount; // Build display lists for the torus and spheres // (You could do one for the ground as well) lTorusList = glGenLists(2); lSphereList = lTorusList + 1; glNewList(lTorusList, GL_COMPILE); gltDrawTorus(0.35f, 0.15f, 61, 37); glEndList(); glNewList(lSphereList, GL_COMPILE); gltDrawSphere(0.3f, 31, 16); glEndList(); }
////////////////////////////////////////////////////////////////// // This function does any needed initialization on the rendering // context. void SetupRC() { M3DVector3f vPoints[3] = {{ 0.0f, -0.4f, 0.0f }, { 10.0f, -0.4f, 0.0f }, { 5.0f, -0.4f, -5.0f }}; int iSphere; int i; // Grayish background glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]); // Clear stencil buffer with zero, increment by one whenever anybody // draws into it. When stencil function is enabled, only write where // stencil value is zero. This prevents the transparent shadow from drawing // over itself glStencilOp(GL_INCR, GL_INCR, GL_INCR); glClearStencil(0); glStencilFunc(GL_EQUAL, 0x0, 0x01); // Cull backs of polygons glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_MULTISAMPLE_ARB); // Setup light parameters glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Calculate shadow matrix M3DVector4f pPlane; m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]); m3dMakePlanarShadowMatrix(mShadowMatrix, pPlane, fLightPos); // Mostly use material tracking glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMaterialfv(GL_FRONT, GL_SPECULAR, fBrightLight); glMateriali(GL_FRONT, GL_SHININESS, 128); // Randomly place the sphere inhabitants for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++) { // Pick a random location between -20 and 20 at .1 increments spheres[iSphere].SetOrigin(((float)((rand() % 400) - 200) * 0.1f), 0.0, (float)((rand() % 400) - 200) * 0.1f); } // Set up texture maps glEnable(GL_TEXTURE_2D); glGenTextures(NUM_TEXTURES, textureObjects); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); for(i = 0; i < NUM_TEXTURES; i++) { GLbyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; glBindTexture(GL_TEXTURE_2D, textureObjects[i]); // Load this texture map pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat); gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes); free(pBytes); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } }