#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 using namespace std; namespace CHCDemoEngine { Geometry::Geometry(Vector3 *vertices, Vector3 *normals, Texcoord2 *texcoords, int numVertices, bool delData, Vector3 *tangents): mVertices(vertices), mNormals(normals), mTexCoords(texcoords), mTangents(tangents), mNumVertices(numVertices), mVboId(-1) { mHasTexture = (mTexCoords != NULL); mHasTangents = (mTangents != NULL); Prepare(); if (delData) { DEL_ARRAY_PTR(mVertices); DEL_ARRAY_PTR(mNormals); DEL_ARRAY_PTR(mTexCoords); DEL_ARRAY_PTR(mTangents); } } Geometry::~Geometry() { DEL_ARRAY_PTR(mVertices); DEL_ARRAY_PTR(mNormals); DEL_ARRAY_PTR(mTexCoords); DEL_ARRAY_PTR(mTangents); // delete vbo glDeleteBuffersARB(1, &mVboId); } void Geometry::Prepare() { CalcBoundingBox(); int dataSize = mNumVertices * 6; if (mTexCoords) dataSize += mNumVertices * 2; if (mTangents) dataSize += mNumVertices * 3; float *data = new float[dataSize]; for (int i = 0; i < mNumVertices; ++ i) { ((Vector3 *)data)[i] = mVertices[i]; ((Vector3 *)data)[i + mNumVertices] = mNormals[i]; } float *currentPData = data + mNumVertices * 6; if (mTangents) { for (int i = 0; i < mNumVertices; ++ i) ((Vector3 *)data)[mNumVertices * 2 + i] = mTangents[i]; for (int i = 0; i < 3; ++ i) cout << ((Vector3 *)data)[mNumVertices * 2 + i] << " "; currentPData += mNumVertices * 3; } if (mTexCoords) { for (int i = 0; i < mNumVertices; ++ i) ((Texcoord2 *)currentPData)[i] = mTexCoords[i]; } glGenBuffersARB(1, &mVboId); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId); int currentPVbo = 0; glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); currentPVbo += mNumVertices * sizeof(Vector3); glNormalPointer(GL_FLOAT, 0, (char *)NULL + currentPVbo); currentPVbo += mNumVertices * 2 * sizeof(Vector3); if (mTangents) { glColorPointer(3, GL_FLOAT, 0, (char *)NULL + currentPVbo); currentPVbo += mNumVertices * sizeof(Vector3); } if (mTexCoords) { glTexCoordPointer(2, GL_FLOAT, 0, (char *)NULL + currentPVbo); } 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 (mHasTangents) glEnableClientState(GL_COLOR_ARRAY); if (state->GetCurrentVboId() != mVboId) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVboId); int currentPointer; glNormalPointer(GL_FLOAT, 0, (char *)NULL + mNumVertices * sizeof(Vector3)); if (mHasTangents) { glColorPointer(3, GL_FLOAT, 0, (char *)NULL + mNumVertices * sizeof(Vector3)); currentPointer = mNumVertices * 3 * sizeof(Vector3); } else currentPointer = mNumVertices * 2 * sizeof(Vector3); if (mHasTexture) glTexCoordPointer(2, GL_FLOAT, 0, (char *)NULL + currentPointer); glVertexPointer(3, GL_FLOAT, 0, (char *)NULL); state->SetCurrentVboId(mVboId); } // don't render first degenerate index glDrawArrays(GL_TRIANGLES, 0, mNumVertices); if (mHasTangents) glDisableClientState(GL_COLOR_ARRAY); } void Geometry::CalcBoundingBox() { mBoundingBox.Initialize(); for (int i = 0; i < mNumVertices; ++ i) { mBoundingBox.Include(mVertices[i]); } } const AxisAlignedBox3& Geometry::GetBoundingBox() const { return mBoundingBox; } }