3dWorld.cpp
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:30k
源码类别:
OpenGL
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // 3DWorld.cpp : implementation file
- //
- // glOOP (OpenGL Object Oriented Programming library)
- // Copyright (c) Craig Fahrnbach 1997, 1998
- //
- // OpenGL is a registered trademark of Silicon Graphics
- //
- //
- // This program is provided for educational and personal use only and
- // is provided without guarantee or warrantee expressed or implied.
- //
- // Commercial use is strickly prohibited without written permission
- // from ImageWare Development.
- //
- // This program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "math.h"
- #include "glOOP.h"
- #include "3dObjectDialog.h"
- #include "3dBackgroundDialog.h"
- #include "AnimationDialog.h"
- #include "MyFileIO.h"
- #include <stdio.h>
- #include <wingdi.h>
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld
- //IMPLEMENT_DYNAMIC(C3dWorld, CObject)
- IMPLEMENT_SERIAL(C3dWorld, CObject, 0)
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld construction
- C3dWorld::C3dWorld()
- {
- // Create a Grid class
- m_pGrid = C3dGrid::Create(0.0f); // use defaults
- ASSERT(m_pGrid);
- // Create a Axis class
- m_pAxis = C3dAxis::Create();
- ASSERT(m_pAxis);
- // Create a BoundingBox
- m_pBoundingBox = new C3dBoundingBox;
- ASSERT(m_pBoundingBox);
- // Create our default colors
- CreateDefColors(&m_ColorList);
- m_szColorFile = "Default.clr";
- // Create our default materials
- CreateDefMaterials(&m_MaterialList);
- m_szMatlFile = "Default.mtl";
- m_pSelectedObj = NULL;
- m_pSelectedPnt = NULL;
- m_iBMImage = -1;
- // Assign Default values to member variables
- m_szName.GetBuffer(128); // allocate 128 bytes min.
- m_szName = _T("");
- m_bAnimate = FALSE;
- m_bFly = FALSE;
- m_bDisplayAxis = TRUE;
- m_bDisplayGrid = TRUE;
- m_bDisplayPoints = FALSE;
- m_iRenderMode = RENDER_SMOOTH;
- m_bCullFaces = FALSE;
- m_bFogEnable = FALSE;
- m_pBkgndTexture = NULL;
- // Assign Default values to member attributes
- m_BackgroundColor.SetColor4f(0.0f, 0.0f, 0.0f, 1.0f); // black
- m_BackgroundColor.m_szName = _T("Black");
- // Set our default fog color to that of our background
- m_Fog.m_Color.SetColor3fv(&m_BackgroundColor);
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld Destructor
- C3dWorld::~C3dWorld()
- {
- }
- void C3dWorld::DeleteWorld()
- {
- // Delete the Objects attached to the world
- m_ObjectList.DeleteAll();
- // Delete the Colors attached to the world
- m_ColorList.DeleteAll();
- // Delete the Materials attached to the world
- m_MaterialList.DeleteAll();
- // Delete the C3dGrid attached to the world
- if(m_pGrid) {
- delete m_pGrid;
- m_pGrid = NULL;
- }
- // Delete the C3dAxis attached to the world
- if(m_pAxis) {
- delete m_pAxis;
- m_pAxis = NULL;
- }
- // Delete the background texture map
- if(m_pBkgndTexture) {
- delete m_pBkgndTexture;
- m_pBkgndTexture = NULL;
- }
- // Delete the BoundingBox attached to the world
- if(m_pBoundingBox) {
- delete m_pBoundingBox;
- m_pBoundingBox = NULL;
- }
- // Delete all points in PointList
- m_PointList.DeleteAll();
- // Delete the world...
- delete this;
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld static function implimentation
- C3dWorld* C3dWorld::CreateWorld()
- {
- // Create the World class
- C3dWorld* pWorld = new C3dWorld;
- ASSERT(pWorld);
- return pWorld;
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld serialization
- void C3dWorld::Serialize(CArchive& ar, C3dCamera* pCamera)
- {
- CString szBuffer;
- CString szName;
- CString szFileName;
- CString szIndentSave;
- HCURSOR m_hcurSave;
- StartWait(); // Display hourglass cursor
- if (ar.IsStoring())
- {
- // Store, or save the World data...
- try
- {
- // Save the file version information
- ar.WriteString(szFileVersion);
- // Save the file header information
- ar.WriteString(szWorldFileHeader);
- ar.WriteString(szIWDFileHeader);
- // Save Include file information
- szBuffer.Format("#include < %s > //Our Worlds Materialsnn", m_szMatlFile);
- ar.WriteString(szBuffer);
- // Store, or save the Camera data...
- pCamera->Serialize(ar, iFileVersion);
- // Save the World information
- szBuffer.Format("C3dWorld {n");
- ar.WriteString(szBuffer);
- szBuffer.Format("tName < %s >n", m_szName);
- ar.WriteString(szBuffer);
- szBuffer.Format("tDisplayAxis < %d >n", m_bDisplayAxis);
- ar.WriteString(szBuffer);
- szBuffer.Format("tDisplayGrid < %d >n", m_bDisplayGrid);
- ar.WriteString(szBuffer);
- szBuffer.Format("tDisplayMode < %d >n", m_iRenderMode);
- ar.WriteString(szBuffer);
- szBuffer.Format("tAnimateWorld < %d >n", m_bAnimate);
- ar.WriteString(szBuffer);
- // Save the fog information
- szBuffer.Format("tEnable Fog < %d >n", m_bFogEnable);
- ar.WriteString(szBuffer);
- m_Fog.Serialize(ar, iFileVersion);
- // Save background color
- szBuffer.Format("tBackground Color:n");
- ar.WriteString(szBuffer);
- szIndentSave = szIndent; // Save the indent level
- szIndent += _T("t"); // Add tab
- m_BackgroundColor.Serialize(ar, iFileVersion);
- szIndent = szIndentSave; // Restore indention
- // If there is a background texture attached save the file
- // file name and serialize
- if(m_pBkgndTexture)
- {
- szName = m_pBkgndTexture->m_szFileName;
- szBuffer.Format("%stTexture Map < %s >n", szIndent, szName);
- ar.WriteString(szBuffer);
- // Save the current indention and indent
- // all CAnimation class procedures
- szIndentSave = szIndent;
- szIndent += _T("tt"); // Add tabs
- // Serialize the texturemap
- m_pBkgndTexture->Serialize(ar, iFileVersion);
- // Restore indent position
- szIndent = szIndentSave; // restore indent
- }
- else
- {
- szName = "None";
- szBuffer.Format("%stTexture Map < %s >n", szIndent, szName);
- ar.WriteString(szBuffer);
- }
- // Save any CAnimation derived class procedure(s)
- m_AnimList.Serialize(ar, iFileVersion);
- szBuffer.Format("}nn"); // end of world def
- ar.WriteString(szBuffer);
- // Store, or save the Object data...
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos) {
- pObject = m_ObjectList.GetAt(objectPos);
- pObject->Serialize(ar, iFileVersion);
- pObject = m_ObjectList.GetNext(objectPos);
- }
- }
- catch (CFileException exception) {
- // Catch any exceptions that may be thrown and
- // display for the user...
- DisplayFileIOException(&exception);
- }
- }
- else
- {
- float fVersion;
- int iVersion;
- pMatlList = &m_MaterialList;
- // Load or Read the World member variables
- try
- {
- // Read the version number
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "// Version: %fn", &fVersion);
- iVersion = Roundf(fVersion*100);
- if(iVersion < 101)
- iVersion = 101; // File had no version number, so assign default
- do
- {
- // Look for Inculde Files..
- CString sztemp;
- sztemp = szBuffer.Left(8);
- if(sztemp.Compare("#include") == 0) {
- // locate the position of the brackets
- int begin = szBuffer.Find("<");
- int end = szBuffer.Find(">");
- if(end > begin) {
- // extract the file name from within the barckets
- m_szMatlFile = szBuffer.Mid(begin+1, (end-begin)-1);
- m_szMatlFile.TrimLeft(); // trim leading spaces
- m_szMatlFile.TrimRight(); // trim tailing spaces
- m_MaterialList.LoadMaterials(m_szMatlFile);
- }
- }
- // Look for the Camera header...
- if(szBuffer.Compare("C3dCamera {") == 0)
- // Load the Camera data...
- pCamera->Serialize(ar, iVersion);
- // Look for the World header...
- if(szBuffer.Compare("C3dWorld {") == 0)
- break;
- } while(ar.ReadString(szBuffer));
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tName < %s >n", m_szName);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tDisplayAxis < %d >n", &m_bDisplayAxis);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tDisplayGrid < %d >n", &m_bDisplayGrid);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tDisplayMode < %d >n", &m_iRenderMode);
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tAnimateWorld < %d >n", &m_bAnimate);
- if(iVersion > 130)
- {
- // Version 1.4 added serialization of background fog
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "tEnable Fog < %d >n", &m_bFogEnable);
- m_Fog.Serialize(ar, iVersion);
- }
- // Load the background color
- while(ar.ReadString(szBuffer))
- {
- szBuffer.TrimLeft(); // Remove leading white spaces
- // Look for the Color header...
- if(szBuffer.Compare("C3dColor {") == 0)
- {
- m_BackgroundColor.Serialize(ar, iVersion);
- break;
- }
- }
- if(iVersion > 102)
- {
- CString szTemp;
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- szTemp = szBuffer.Left(11);
- if(szTemp.Compare("Texture Map") == 0)
- {
- // locate the position of the brackets
- int begin = szBuffer.Find("<");
- int end = szBuffer.Find(">");
- if(end > begin)
- {
- // extract the texture file name from within the barckets
- szName = szBuffer.Mid(begin+1, (end-begin)-1);
- szName.TrimLeft(); // trim leading spaces
- szName.TrimRight(); // trim tailing spaces
- if(szName.Compare("None") !=0)
- {
- AddTexture(szName.GetBuffer(128));
- if(m_pBkgndTexture)
- m_pBkgndTexture->Serialize(ar, iVersion);
- }
- }
- }
- // Load any CAnimation derived class procedure(s)
- m_AnimList.Serialize(ar, iVersion);
- }
- ar.ReadString(szBuffer);
- sscanf(szBuffer, "}nn"); // end of world def
- // Load all Lights and Objects...
- while(ar.ReadString(szBuffer)) {
- C3dObject* pLight = NULL;
- C3dObject* pObject = NULL;
- szBuffer.TrimLeft(); // Remove leading white spaces
- pLight = C3dObject::IsLightClass(&szBuffer);
- if(pLight) {
- pLight->Serialize(ar, iVersion);
- AddObject(pLight, NULL);
- }
- pObject = C3dObject::IsShapeClass(&szBuffer);
- if(pObject) {
- pObject->Serialize(ar, iVersion);
- AddObject(pObject, NULL);
- }
- }
- }
- catch (CFileException exception) {
- // Catch any exceptions that may be thrown and
- // display for the user...
- DisplayFileIOException(&exception);
- }
- }
- EndWait(); // Remove hourglass cursor
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dWorld function implimentation
- void C3dWorld::AddAnimationPages(C3dWorld* pWorld, LPVOID pSht)
- {
- CAnimPropSheet* pSheet = (CAnimPropSheet*)pSht;
- ASSERT(pSheet);
- // Load all animation pages for this world
- CAnimation* pAnimation = NULL;
- // walk the list
- POSITION Pos = m_AnimList.GetHeadPosition();
- while (Pos) {
- pAnimation = m_AnimList.GetAt(Pos);
- pAnimation->AddAnimationPage(pSht, NULL, NULL, this);
- pAnimation = m_AnimList.GetNext(Pos);
- }
- }
- int C3dWorld::EditAnimation(CWnd* pParentWnd, C3dWorld* pWorld)
- {
- char szName[80];
- sprintf(szName, "Edit Animation Attributes of 3dWorld");
- CAnimPropSheet* pAnimPropSheet = new CAnimPropSheet(szName, pParentWnd, NULL, NULL, this);
- // Create and display the modal dialog box
- return( pAnimPropSheet->DoModal() );
- }
- void C3dWorld::Animate(C3dCamera* pCamera, double time)
- {
- // Animate the world based on its animation procedures
- CAnimation* pAnimation = NULL;
- // walk the list
- POSITION Pos = m_AnimList.GetHeadPosition();
- while (Pos) {
- pAnimation = m_AnimList.GetAt(Pos);
- pAnimation->AnimateWorld(this, time);
- pAnimation = m_AnimList.GetNext(Pos);
- }
- // Animate the camera
- if(pCamera)
- pCamera->Animate(time);
- // Animate all lights attached to this world..
- C3dObject* pLight = NULL;
- // walk the list
- POSITION lightPos = m_LightList.GetHeadPosition();
- while (lightPos) {
- pLight = m_LightList.GetAt(lightPos);
- pLight->Animate(time);
- pLight = m_LightList.GetNext(lightPos);
- }
- // Animate all objects attached to this world..
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos) {
- pObject = m_ObjectList.GetAt(objectPos);
- pObject->Animate(time);
- pObject = m_ObjectList.GetNext(objectPos);
- }
- }
- void C3dWorld::ResetAnimation(C3dCamera* pCamera)
- {
- // Reset the camera
- if(pCamera)
- pCamera->ResetAnimation();
- // Reset all lights attached to this world..
- C3dObject* pLight = NULL;
- // walk the list
- POSITION lightPos = m_LightList.GetHeadPosition();
- while (lightPos) {
- pLight = m_LightList.GetAt(lightPos);
- pLight->ResetAnimation();
- pLight = m_LightList.GetNext(lightPos);
- }
- // Reset all objects attached to this world..
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos) {
- pObject = m_ObjectList.GetAt(objectPos);
- pObject->ResetAnimation();
- pObject = m_ObjectList.GetNext(objectPos);
- }
- }
- void C3dWorld::DisplayWorld(HDC hDC, C3dCamera* pCamera, double dTime)
- {
- static double dLastTime = 0.0;
- // Setup our rendering context
- SetupRC();
- if(dTime != dLastTime)
- {
- Animate(pCamera, dTime);
- dLastTime = dTime;
- }
- // Render the 3dWorld scene
- RenderScene(pCamera);
- // Swap our scene to the front
- SwapBuffers(hDC);
- }
- void C3dWorld::SetupRC(void)
- {
- GLenum err; // Used for retrieving OpenGL errors
- static GLfloat factor = -1.0f;
- static GLfloat units = -1.0f;
- // Set the background color
- glClearColor((GLclampf)m_BackgroundColor.m_fColor[0],
- (GLclampf)m_BackgroundColor.m_fColor[1],
- (GLclampf)m_BackgroundColor.m_fColor[2],
- (GLclampf)m_BackgroundColor.m_fColor[3]);
- // If we have a palette, enable dithering of color before
- // writing to the color buffer
- if(the3dEngine.GetPalette())
- glEnable(GL_DITHER);
- // Enable color material
- glEnable(GL_COLOR_MATERIAL);
- if(m_bCullFaces)
- glEnable(GL_CULL_FACE);
- else
- glDisable(GL_CULL_FACE);
- // Set the rendering mode
- if(m_iRenderMode == RENDER_FLAT)
- {
- glShadeModel(GL_FLAT);
- glDisable(GL_POLYGON_OFFSET_LINE);
- }
- else if(m_iRenderMode == RENDER_SMOOTH)
- {
- glShadeModel(GL_SMOOTH);
- glDisable(GL_POLYGON_OFFSET_LINE);
- }
- else if(m_iRenderMode == RENDER_OUTLINE)
- {
- // glShadeModel(GL_SMOOTH);
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- glEnable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(factor, units);
- }
- // Tell OpenGL to draw into the BACK buffer. When we are
- // finished, we will swap to the front.
- glDrawBuffer(GL_BACK);
- // Enable Pixel depth testing.
- glEnable(GL_DEPTH_TEST);
- glFrontFace(GL_CCW); // Counter clock-wise polygons face out
- // Enable lighting
- glEnable(GL_LIGHTING);
- // We want specular reflections to take the direction of our
- // cameras' position
- glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0f);
- // Perform error checking routine
- #if(_DEBUG)
- do
- {
- err = glGetError();
- if (err != GL_NO_ERROR)
- TRACE("Error in C3dWorld::SetupRC: %sn", gluErrorString(err));
- }while(err != GL_NO_ERROR);
- #endif
- }
- void C3dWorld::RenderScene(C3dCamera* pCamera)
- {
- GLenum err; // Used for retrieving OpenGL errors
- // Clear the buffers
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- // Set the matrix mode to MODELVIEW and load
- // the identity matrix
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- // Set our camera position and save its transformation matrix
- pCamera->PositionCamera();
- // Set our Fog parameters
- if(m_bFogEnable)
- m_Fog.SetAttributes();
- else
- glDisable(GL_FOG);
- // Initialize all lights attached to this world
- InitializeLights(pCamera);
- if(m_pBkgndTexture)
- // Display the background image
- DisplayBackgroundImage(pCamera);
- // Initialize the names stack
- glInitNames();
- glPushName(0);
- if(m_bDisplayAxis)
- // Display the World X, Y, Z Origin Axis
- m_pAxis->Display( 3.0f, // Axis length
- 0.1f, // Axis diameter
- 0.5f, // Arrow length
- 0.25f,// Arrow diameter
- 10, // Number of slices around dia.
- 2, // Number of Stacks about length
- NULL, // X-Axis Color (Use Defaults..)
- NULL, // Y-Axis Color
- NULL, // Z-Axis Color
- TRUE);// Display as Solid
- if(m_bDisplayGrid)
- m_pGrid->Display(this, pCamera);
- if(!m_PointList.IsEmpty())
- // Display all points in our list..
- m_PointList.Display(this, pCamera, TRUE);
- // Perform error checking routine
- #if(_DEBUG)
- do
- {
- err = glGetError();
- if (err != GL_NO_ERROR)
- TRACE("Error in C3dWorld::RenderScene: %sn", gluErrorString(err));
- }while(err != GL_NO_ERROR);
- #endif
- // Display all objects attached to this world..
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos)
- {
- pObject = m_ObjectList.GetAt(objectPos);
- pObject->DisplayObject(this, pCamera);
- // Perform error checking routine
- #if(_DEBUG)
- do
- {
- err = glGetError();
- if (err != GL_NO_ERROR)
- TRACE("Error in C3dWorld::RenderScene displaying object %s: %sn", pObject->m_szName, gluErrorString(err));
- }while(err != GL_NO_ERROR);
- #endif
- pObject = m_ObjectList.GetNext(objectPos);
- }
- glFlush(); // Flush any reminant commands from the buffer..
- }
- void C3dWorld::InitializeLights(C3dCamera* pCamera)
- {
- GLenum err; // Used for retrieving OpenGL errors
- // Initialize all lights attached to this world..
- C3dObject* pLightObj = NULL;
- C3dObjectLight* pLight = NULL;
- GLenum lightNum = GL_LIGHT0;
- // walk the list
- POSITION lightPos = m_LightList.GetHeadPosition();
- while (lightPos)
- {
- pLightObj = m_LightList.GetAt(lightPos);
- pLight = (C3dObjectLight*)pLightObj;
- pLight->EnableLight(lightNum, this, pCamera);
- // Perform error checking routine
- #if(_DEBUG)
- do
- {
- err = glGetError();
- if (err != GL_NO_ERROR)
- TRACE("Error in C3dWorld::RenderScene displaying light %s: %sn", pLight->m_szName, gluErrorString(err));
- }while(err != GL_NO_ERROR);
- #endif
- ++lightNum;
- pLightObj = m_LightList.GetNext(lightPos);
- }
- }
- void C3dWorld::DisplayBackgroundImage(C3dCamera* pCamera)
- {
- GLfloat x, y, z;
- // Ensure that we have a background image
- if(!m_pBkgndTexture)
- return;
- // Do we blend the background image
- if(m_pBkgndTexture->m_iEnvmode == GL_BLEND)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
- else
- // Disable blend function
- glDisable(GL_BLEND);
- if(m_pBkgndTexture->m_pBits)
- // Apply the Dib Image to our shape..
- m_pBkgndTexture->SetTexture();
- // Calculate the size of the image
- z = pCamera->m_fFar;
- y = tan(Radiansf(pCamera->m_fFovY/2))*z;
- x = y*((GLfloat)pCamera->m_iScreenWidth/(GLfloat)pCamera->m_iScreenHeight);
- // Save our current modelview matrix and load the identity matrix
- glPushMatrix();
- glLoadIdentity();
- // Map the texture coordinates onto the background 'Plane'
- glBegin(GL_POLYGON);
- glNormal3d(0.0, 0.0, 1.0);
- glTexCoord2d(1, 0.0);
- glVertex3d(x, -y, -z);
- glTexCoord2d(1, 1);
- glVertex3d(x, y, -z);
- glTexCoord2d(0.0, 1);
- glVertex3d(-x, y, -z);
- glTexCoord2d(0.0, 0.0);
- glVertex3d(-x, -y, -z);
- glEnd();
- // Restore our Modelview matrix
- glPopMatrix();
- }
- // Process the selection, which is triggered by a right mouse
- // click at (xPos, yPos).
- #define BUFFER_LENGTH 64
- C3dObject* C3dWorld::ProcessSelection(C3dCamera* pCamera, int xPos, int yPos, BOOL bSelParent)
- {
- // Pointer to our selected object
- C3dObject* pSelectedObject = NULL;
- // Space for selection buffer
- GLuint selectBuff[BUFFER_LENGTH];
- // Hit counter and viewport storeage
- GLint hits, viewport[4];
- // Setup selection buffer
- glSelectBuffer(BUFFER_LENGTH, selectBuff);
- // Get the viewport
- glGetIntegerv(GL_VIEWPORT, viewport);
- // Fix the yPos value. MS Windows origin 0,0 is upper left
- // while OpenGL windows origin 0,0 is lower left...
- yPos = viewport[3]-yPos;
- // Switch to projection and save the matrix
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- // Change render mode
- glRenderMode(GL_SELECT);
- // Establish new clipping volume to be unit cube around
- // mouse cursor point (xPos, yPos) and extending two pixels
- // in the vertical and horzontal direction
- glLoadIdentity();
- gluPickMatrix(xPos, yPos, 0.1f, 0.1f, viewport);
- // Apply perspective or orthographic matrix
- if(pCamera->m_bPerspective) {
- // Perspective transformations.
- gluPerspective(pCamera->m_fFovY, pCamera->m_fAspect, pCamera->m_fNear, pCamera->m_fFar);
- }
- else {
- // Orthographic transformations.
- glOrtho(pCamera->m_fLeft, pCamera->m_fRight, pCamera->m_fBottom, pCamera->m_fTop, -pCamera->m_fOrigin[Z], pCamera->m_fFar);
- }
- // Draw the scene
- RenderScene(pCamera);
- // Collect the hits
- hits = glRenderMode(GL_RENDER);
- // Restore the projection matrix
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- // Go back to modelview for normal rendering
- glMatrixMode(GL_MODELVIEW);
- // If a hit occured, display the info.
- if(hits > 0)
- {
- // The hit record consists of the number of names in the
- // name stack at the time of the event; followed by the
- // minimum and maximum depth values of all vertices that
- // hit since the previous event; followed by the name stack
- // contents, bottom name first. Get the 'top' name.
- int iHitNum = (hits*4)-1;
- // Check to see if the user selected a light object
- C3dObject* pLight = NULL;
- // walk the list
- POSITION lightPos = m_LightList.GetHeadPosition();
- while (lightPos)
- {
- pLight = m_LightList.GetAt(lightPos);
- pSelectedObject = pLight->IsName(selectBuff[iHitNum], bSelParent);
- if(pSelectedObject)
- break;
- pLight = m_LightList.GetNext(lightPos);
- }
- // User did not select a light; must be an object..
- if(!pSelectedObject)
- {
- // Display all objects attached to this world..
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos)
- {
- pObject = m_ObjectList.GetAt(objectPos);
- pSelectedObject = pObject->IsName(selectBuff[iHitNum], bSelParent);
- if(pSelectedObject)
- break;
- pObject = m_ObjectList.GetNext(objectPos);
- }
- }
- }
- return pSelectedObject;
- }
- void C3dWorld::AddObject(C3dObject* pObject, C3dObject* pParent)
- {
- ASSERT(pObject);
- // Light objects require special processing. We add them to the
- // Light list for Enabling and the Object list for display.
- if(pObject->m_iType == LIGHT_OBJECT)
- m_LightList.Append(pObject);
- if(pParent)
- {
- pParent->AddChildObject(pObject);
- pObject->m_pParent = pParent;
- }
- else
- {
- m_ObjectList.Append(pObject);
- pObject->m_pParent = NULL;
- }
- }
- BOOL C3dWorld::CreateDefColors(C3dColorList* pColorList)
- {
- // Create our Default Colors
- C3dColor* pColor = NULL; // Pointer to a color
- pColor = C3dColor::Create("Black", // Name
- 0.0f, // Red component
- 0.0f, // Green component
- 0.0f, // Blue component
- 1.0f); // Alpha component
- pColorList->Append(pColor);
- pColor = C3dColor::Create("White", // Name
- 1.0f, // Red component
- 1.0f, // Green component
- 1.0f, // Blue component
- 1.0f); // Alpha component
- pColorList->Append(pColor);
- pColor = C3dColor::Create("DarkGray", // Name
- 0.5f, // Red component
- 0.5f, // Green component
- 0.5f, // Blue component
- 1.0f); // Alpha component
- pColorList->Append(pColor);
- pColor = C3dColor::Create("LightGray", // Name
- 0.7f, // Red component
- 0.7f, // Green component
- 0.7f, // Blue component
- 1.0f); // Alpha component
- pColorList->Append(pColor);
- return TRUE;
- }
- BOOL C3dWorld::CreateDefMaterials(C3dMaterialList* pMatlList)
- {
- // Create our Default Materials
- C3dMaterial* pMatl = NULL; // Pointer to our materials
- pMatl = C3dMaterial::Create("<None>", // Name
- 0.0f, 0.0f, 0.0f, 1.0f, // Ambient Color
- 0.0f, 0.0f, 0.0f, 1.0f, // Diffuse Color
- 0.0f, 0.0f, 0.0f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 0.0f, // Specular Power
- 0.0f, // Index of Refraction
- 0.0f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Shiny", // Name
- 0.1f, 0.1f, 0.1f, 1.0f, // Ambient Color
- 1.0f, 1.0f, 1.0f, 1.0f, // Diffuse Color
- 1.0f, 1.0f, 1.0f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 20.0f, // Specular Power
- 0.0f, // Index of Refraction
- 0.0f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Matte", // Name
- 0.1f, 0.1f, 0.1f, 1.0f, // Ambient Color
- 0.2f, 0.2f, 0.2f, 1.0f, // Diffuse Color
- 0.2f, 0.2f, 0.2f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 10.0f, // Specular Power
- 0.0f, // Index of Refraction
- 0.0f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Metallic", // Name
- 0.1f, 0.1f, 0.1f, 1.0f, // Ambient Color
- 0.5f, 0.5f, 0.5f, 1.0f, // Diffuse Color
- 0.6f, 0.6f, 0.6f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 6.0f, // Specular Power
- 0.0f, // Index of Refraction
- 0.25f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Reflective", // Name
- 0.1f, 0.1f, 0.1f, 1.0f, // Ambient Color
- 0.5f, 0.5f, 0.5f, 1.0f, // Diffuse Color
- 0.5f, 0.5f, 0.5f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 7.0f, // Specular Power
- 0.0f, // Index of Refraction
- 0.5f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Mirror", // Name
- 0.0f, 0.0f, 0.0f, 1.0f, // Ambient Color
- 0.0f, 0.0f, 0.0f, 1.0f, // Diffuse Color
- 1.0f, 1.0f, 1.0f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 20.0f, // Specular Power
- 0.0f, // Index of Refraction
- 1.0f, // Reflection
- 0.0f); // Translucency
- pMatlList->Append(pMatl);
- pMatl = C3dMaterial::Create("Glass", // Name
- 0.0f, 0.0f, 0.0f, 1.0f, // Ambient Color
- 0.0f, 0.0f, 0.0f, 1.0f, // Diffuse Color
- 0.2f, 0.2f, 0.2f, 1.0f, // Specular Color
- 0.0f, 0.0f, 0.0f, 0.0f, // Emmissive Color
- 6.0f, // Specular Power
- 1.56f, // Index of Refraction
- 0.15f, // Reflection
- 1.0f); // Translucency
- pMatlList->Append(pMatl);
- return TRUE;
- }
- void C3dWorld::AddMaterial(C3dMaterial* pMaterial)
- {
- ASSERT(pMaterial);
- m_MaterialList.Append(pMaterial);
- }
- int C3dWorld::LoadBitMapImage(CImageList* pList)
- {
- CBitmap bitmap;
- // If the image index has been stored in this object,
- // return the index.
- if(m_iBMImage > -1)
- return m_iBMImage;
- // If the image index for this object type has been
- // created, store the index for this object and
- // return the index.
- if(iWorldBMImage > -1) {
- m_iBMImage = iWorldBMImage;
- return m_iBMImage;
- }
- // The image index for this object type has not been
- // loaded and the object image index has not been
- // stored.
- //
- // Load the bitmap for the non-selected world
- bitmap.LoadBitmap(IDB_WORLD);
- m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- // Load the bitmap for the selected world
- bitmap.LoadBitmap(IDB_WORLD_SELECTED);
- pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- iWorldBMImage = m_iBMImage;
- return m_iBMImage;
- }
- BOOL C3dWorld::EditAttributes()
- {
- char szName[80];
- sprintf(szName, "Edit Attributes of world '%s'", m_szName);
- m_pBackgroundPropSheet = new C3dBackgroundPropSheet(szName, NULL, this);
- m_pBackgroundPropSheet->DoModal();
- return 0;
- }
- void C3dWorld::DeleteObject(C3dObject* pObject)
- {
- if(!pObject)
- return; // Nothing to delete..
- // Remove the object from the Light list?
- if(pObject->m_iType == LIGHT_OBJECT)
- m_LightList.Delete(pObject);
- // Remove the object from the Object list
- if(!pObject->m_pParent)
- m_ObjectList.Delete(pObject);
- else
- // Let parent delete child
- pObject->m_pParent->m_ObjectList.Delete(pObject);
- pObject = NULL;
- }
- BOOL C3dWorld::AddTexture(LPSTR szFileName)
- {
- if(m_pBkgndTexture)
- // If we already have a texture, delete it
- DeleteTexture();
- // Create a TextureMap of the appropriate type
- CTexture::CreateTexture(szFileName, the3dEngine.m_hPalette, &m_pBkgndTexture);
- if(m_pBkgndTexture)
- {
- // Is the TextureMap an CTextureAviMovie?
- if( m_pBkgndTexture->IsKindOf(RUNTIME_CLASS(CTextureAviMovie)) )
- {
- // Create an AVI animation and add to the list
- CAnimAVI* pAnim = new CAnimAVI;
- ASSERT(pAnim);
- m_AnimList.Append(pAnim);
- // Save the CTextureAviMovie pointer
- pAnim->m_pAviMovie = (CTextureAviMovie*)m_pBkgndTexture;
- }
- return TRUE;
- }
- else
- return FALSE;
- }
- void C3dWorld::DeleteTexture()
- {
- if(m_pBkgndTexture)
- {
- if( m_pBkgndTexture->IsKindOf(RUNTIME_CLASS(CTextureAviMovie)) )
- {
- // TextureMap is of class type CTextureAviMovie, so find the animation
- // procedure in the list, remove from list and delete it..
- CAnimation* pAnimation = m_AnimList.Find(SZ_ANIMATE_AVI);
- if(pAnimation)
- {
- m_AnimList.Remove(pAnimation);
- delete pAnimation;
- }
- }
- // Now that we have removed any associated object members,
- // delete the texturemap
- delete m_pBkgndTexture;
- m_pBkgndTexture = NULL;
- }
- }
- void C3dWorld::RebuildAllObjects()
- {
- // This function forces all objects to rebuild their display
- // lists.
- // Display all objects attached to this world..
- C3dObject* pObject = NULL;
- // walk the list
- POSITION objectPos = m_ObjectList.GetHeadPosition();
- while (objectPos)
- {
- pObject = m_ObjectList.GetAt(objectPos);
- pObject->Rebuild();
- pObject = m_ObjectList.GetNext(objectPos);
- }
- }