#include "Geometry.h" #include "Triangle3.h" #include "glInterface.h" #include "RenderState.h" #ifdef _CRT_SET #define _CRTDBG_MAP_ALLOC #include #include // redefine new operator #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) #define new DEBUG_NEW #endif namespace CHCDemoEngine { Geometry::Geometry(Vector3 *vertices, Vector3 *normals, Texcoord2 *texcoords, int numVertices, bool delData): mVertices(vertices), mNormals(normals), mTexCoords(texcoords), mNumVertices(numVertices), mVboId(-1) { mHasTexture = (mTexCoords != NULL); Prepare(); if (delData) { DEL_ARRAY_PTR(mVertices); DEL_ARRAY_PTR(mNormals); DEL_ARRAY_PTR(mTexCoords); } } Geometry::~Geometry() { DEL_ARRAY_PTR(mVertices); DEL_ARRAY_PTR(mNormals); DEL_ARRAY_PTR(mTexCoords); // delete vbo glDeleteBuffersARB(1, &mVboId); } void Geometry::Prepare() { CalcBoundingBox(); int dataSize = mNumVertices * 6; if (mTexCoords) dataSize += mNumVertices * 2; float *data = new float[dataSize]; for (int i = 0; i < mNumVertices; ++ i) { ((Vector3 *)data)[i] = mVertices[i]; ((Vector3 *)data)[i + mNumVertices] = mNormals[i]; } if (mTexCoords) { for (int i = 0; i < mNumVertices; ++ i) ((Texcoord2 *)data)[mNumVertices * 3 + i] = mTexCoords[i]; } glGenBuffersARB(1, &mVboId); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId); glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); glNormalPointer(GL_FLOAT, 0, (char *)NULL + mNumVertices * sizeof(Vector3)); if (mTexCoords) { glTexCoordPointer(2, GL_FLOAT, 0, (char *)NULL + 2 * mNumVertices * sizeof(Vector3)); } glBufferDataARB(GL_ARRAY_BUFFER_ARB, dataSize * sizeof(float), (float *)data, GL_STATIC_DRAW_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); // data handled by graphics driver from now on delete [] data; } void Geometry::Render(RenderState *state) { if (state->GetCurrentVboId() != mVboId) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId); if (mHasTexture) glTexCoordPointer(2, GL_FLOAT, 0, (char *)NULL + 2 * mNumVertices * sizeof(Vector3)); glNormalPointer(GL_FLOAT, 0, (char *)NULL + mNumVertices * sizeof(Vector3)); glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); state->SetCurrentVboId(mVboId); } // don't render first degenerate index glDrawArrays(GL_TRIANGLES, 0, mNumVertices); } void Geometry::CalcBoundingBox() { mBoundingBox.Initialize(); for (int i = 0; i < mNumVertices; ++ i) { mBoundingBox.Include(mVertices[i]); } } const AxisAlignedBox3& Geometry::GetBoundingBox() const { return mBoundingBox; } }