3dObjectDisk.cpp NEW
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:11k
源码类别:
OpenGL
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // 3dObjectDisk.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 freely distributable without licensing fees and is
- // provided without guarantee or warrantee expressed or implied. This
- // program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "glOOP.h"
- #include "3dObjectDialog.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- //////////////////////////////////////////////////////////////////
- // C3dObjectDisk
- IMPLEMENT_DYNAMIC(C3dObjectDisk, C3dObject)
- /////////////////////////////////////////////////////////////////////////////
- // C3dShape construction
- C3dObjectDisk::C3dObjectDisk()
- {
- // Set the attributes to default values..
- m_iType = SHAPE_OBJECT;
- m_szName.Format("Disk %u", nDiskObjects++);
- m_fInnerRadius = 0.0f;
- m_fOuterRadius = 1.0f;
- m_fSweepAngle = 360.0f; // full circle
- m_iSegments = 10;
- m_iRings = 1;
- // Create our C3dPointArray object
- m_pPointArray = new C3dPointArray;
- ASSERT(m_pPointArray);
- // Create an array of points for our vertices
- m_pPointArray->Create(m_iSegments+2);
- // Initialize our cubes vertices (points)
- InitVertices();
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3DWorld Destructor
- C3dObjectDisk::~C3dObjectDisk()
- {
- // Delete our point array
- if(m_pPointArray)
- delete m_pPointArray;
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dObjectDisk Methods or virtual function implimentation
- void C3dObjectDisk::AddAttributePage(C3dWorld* pWorld, LPVOID pSht)
- {
- C3dObjectPropSheet* pSheet = (C3dObjectPropSheet*)pSht;
- ASSERT(pSheet);
- // Add the page to the property sheet
- pSheet->AddPage(&pSheet->m_DiskPage);
- // Save the address of this object in the page
- pSheet->m_DiskPage.m_pObject = this;
- }
- int C3dObjectDisk::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( iObjectDiskBMImage > -1) {
- m_iBMImage = iObjectDiskBMImage;
- 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 light
- bitmap.LoadBitmap(IDB_OBJECT_DISK);
- m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- // Load the bitmap for the non-selected light
- bitmap.LoadBitmap(IDB_OBJECT_DISK_SELECTED);
- pList->Add(&bitmap, (COLORREF)0xFFFFFF);
- bitmap.DeleteObject();
- iObjectDiskBMImage = m_iBMImage;
- return m_iBMImage;
- }
- void C3dObjectDisk::Serialize(CArchive& ar, int iVersion)
- {
- CString szBuffer;
- if (ar.IsStoring())
- {
- // Save the Object Class header...
- szBuffer.Format("n%sC3dObjectDisk {n", szIndent);
- ar.WriteString(szBuffer);
- // Save the this objects' specific data...
- szBuffer.Format("%stInnerRadius < %f >n", szIndent, m_fInnerRadius);
- ar.WriteString(szBuffer);
- szBuffer.Format("%stOuterRadius < %f >n", szIndent, m_fOuterRadius);
- ar.WriteString(szBuffer);
- szBuffer.Format("%stSegments < %d >n", szIndent, m_iSegments);
- ar.WriteString(szBuffer);
- szBuffer.Format("%stSweepAngle < %f >n", szIndent, m_fSweepAngle);
- ar.WriteString(szBuffer);
- szBuffer.Format("%stSolid Color < %d >n", szIndent, m_bSolidColor);
- ar.WriteString(szBuffer);
- szBuffer.Format("%stNum Points < %d >n", szIndent, m_pPointArray->m_iNumPoints);
- ar.WriteString(szBuffer);
- m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
- // Save the base class object data...
- C3dObject::Serialize(ar, iVersion);
- szBuffer.Format("%s}n", szIndent); // end of object def
- ar.WriteString(szBuffer);
- }
- else
- {
- if(iVersion < 102)
- // Read the base class object data...
- C3dObject::Serialize(ar, iVersion);
- // Read the derived class data..
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft(); // Remove leading white spaces
- sscanf(szBuffer, "InnerRadius < %f >n", &m_fInnerRadius);
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "OuterRadius < %f >n", &m_fOuterRadius);
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "Segments < %d >n", &m_iSegments);
- // Resize our point array to accomodate all points
- int arraySize;
- if(m_fInnerRadius)
- arraySize = (m_iSegments+2)*2;
- else
- arraySize = m_iSegments+2;
- if(m_pPointArray->SetArraySize(arraySize))
- return;
- if(iVersion < 110)
- {
- // Version 1.10 and higher do not support rings on disk, so just read
- // the buffer
- ar.ReadString(szBuffer);
- // Initialize our point array vertices
- InitVertices();
- }
- else
- {
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "SweepAngle < %f >n", &m_fSweepAngle);
- if(iVersion > 130)
- {
- // Version 1.4 added point color capability
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "Solid Color < %d >n", &m_bSolidColor);
- }
- ar.ReadString(szBuffer);
- szBuffer.TrimLeft();
- sscanf(szBuffer, "Num Points < %d >n", &m_pPointArray->m_iNumPoints);
- // Read the shape vertice, or point data
- m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
- }
- if(iVersion < 102)
- // Read all child objects...
- LoadChildObjects(ar, iVersion);
- else
- // Read the base class object data...
- C3dObject::Serialize(ar, iVersion);
- }
- }
- void C3dObjectDisk::Build(C3dWorld* pWorld, C3dCamera* pCamera)
- {
- VECTORF Normal;
- GLfloat x0, y0, x1, y1;
- double a0, a1;
- int i;
- // Compile and build the list
- glNewList(m_iDisplayLists, GL_COMPILE_AND_EXECUTE);
- if(!m_fInnerRadius)
- {
- C3dPoint* pInnerPoint; // Pointer to the first inner point
- C3dPoint* pOuterPoint; // Pointer to the first outer point
- pInnerPoint = &m_pPointArray->m_pPoints[0]; // first point in array
- pOuterPoint = &m_pPointArray->m_pPoints[1]; // second point in array
- // Initialize our disks vertice points
- for(i=0; i<m_iSegments; i++)
- {
- a0 = i * (m_fSweepAngle/m_iSegments);
- x0 = Cosf((GLfloat)a0);
- y0 = Sinf((GLfloat)a0);
- a1 = (i+1) * (m_fSweepAngle/m_iSegments);
- x1 = Cosf((GLfloat)a1);
- y1 = Sinf((GLfloat)a1);
- glBegin(GL_TRIANGLES);
- // Calculate the normal for the triangle
- CalNormalf(pInnerPoint->m_fOrigin,
- pOuterPoint[i+1].m_fOrigin,
- pOuterPoint[i].m_fOrigin,
- Normal);
- glNormal3fv(Normal);
- glTexCoord2d(0.5, 0.5);
- if(!m_bSolidColor)
- glColor4fv(pInnerPoint->m_Color.m_fColor);
- glVertex3fv(pInnerPoint->m_fOrigin);
- glTexCoord2d((x0*0.5)+0.5, (y0*0.5)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pOuterPoint[i].m_Color.m_fColor);
- glVertex3fv(pOuterPoint[i].m_fOrigin);
- glTexCoord2d((x1*0.5)+0.5, (y1*0.5)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pOuterPoint[i+1].m_Color.m_fColor);
- glVertex3fv(pOuterPoint[i+1].m_fOrigin);
- glEnd();
- }
- }
- else
- {
- C3dPoint* pPoint = m_pPointArray->m_pPoints; // first point in array
- // Initialize our disks vertice points
- for(i=0; i<(m_iSegments*2); i+=2)
- {
- a0 = (i/2) * (m_fSweepAngle/m_iSegments);
- x0 = Cosf((GLfloat)a0);
- y0 = Sinf((GLfloat)a0);
- a1 = ((i/2)+1) * (m_fSweepAngle/m_iSegments);
- x1 = Cosf((GLfloat)a1);
- y1 = Sinf((GLfloat)a1);
- glBegin(GL_TRIANGLE_STRIP);
- // Calculate the normal for the triangle
- CalNormalf(pPoint[i+1].m_fOrigin,
- pPoint[i].m_fOrigin,
- pPoint[i+3].m_fOrigin,
- Normal);
- glNormal3fv(Normal);
- glTexCoord2d((x0*0.5)+0.5, (y0*0.5)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pPoint[i+1].m_Color.m_fColor);
- glVertex3fv(pPoint[i+1].m_fOrigin);
- glTexCoord2d((x1*0.5)+0.5, (y1*0.5)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pPoint[i+3].m_Color.m_fColor);
- glVertex3fv(pPoint[i+3].m_fOrigin);
- glTexCoord2d(((x0*(m_fInnerRadius/m_fOuterRadius))/2)+0.5,
- ((y0*(m_fInnerRadius/m_fOuterRadius))/2)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pPoint[i].m_Color.m_fColor);
- glVertex3fv(pPoint[i].m_fOrigin);
- // Calculate the normal for the triangle
- CalNormalf(pPoint[i].m_fOrigin,
- pPoint[i+2].m_fOrigin,
- pPoint[i+3].m_fOrigin,
- Normal);
- glNormal3fv(Normal);
- glTexCoord2d(((x1*(m_fInnerRadius/m_fOuterRadius))/2)+0.5,
- ((y1*(m_fInnerRadius/m_fOuterRadius))/2)+0.5);
- if(!m_bSolidColor)
- glColor4fv(pPoint[i+2].m_Color.m_fColor);
- glVertex3fv(pPoint[i+2].m_fOrigin);
- glEnd();
- }
- }
- glEndList();
- }
- /////////////////////////////////////////////////////////////////////////////
- // C3dObjectDisk Methods or Implementation
- void C3dObjectDisk::InitVertices()
- {
- /* Flat disk with Inner Flat disk with Inner
- radius = 0.0 radius = x.0
- p5 ------- p3
- /
- p3 ------ p2 /
- / / p4 ----- p2
- / | / |
- p4 | *p0 | p1&pN p7 | p6| |p0 | p1
- | | | / pN | pN+1
- / p8 ----- p10 /
- / /
- p5 ------ p6 /
- p9 ------- p11
- */
- C3dPoint* pPoint;
- int iNumPoints;
- // Determine the number of points in the disk
- if(m_fInnerRadius)
- iNumPoints = (m_iSegments+2)*2;
- else
- iNumPoints = m_iSegments+2;
- if(m_pPointArray->SetArraySize(iNumPoints))
- return; // function failed
- pPoint= m_pPointArray->m_pPoints; // address of the first point
- // Initialize our disks vertice points
- int i;
- for(i=0; i<=m_iSegments; i++)
- {
- double a0 = i * (m_fSweepAngle/m_iSegments);
- GLfloat x0 = Cosf((GLfloat)a0);
- GLfloat y0 = Sinf((GLfloat)a0);
- if(m_fInnerRadius || i==0)
- {
- pPoint->m_fOrigin[X] = m_fInnerRadius*x0;
- pPoint->m_fOrigin[Y] = m_fInnerRadius*y0;
- pPoint->m_fOrigin[Z] = 0.0f;
- pPoint++;
- }
- pPoint->m_fOrigin[X] = m_fOuterRadius*x0;
- pPoint->m_fOrigin[Y] = m_fOuterRadius*y0;
- pPoint->m_fOrigin[Z] = 0.0f;
- pPoint++;
- }
- }