#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 tangent = Normalize(mTangents[i]); Vector3 normal = Normalize(mNormals[i]); float dotProd = DotProd(tangent, normal); //tangent -= normal * dotProd;tangent = Normalize(tangent); //mTangents[i] = tangent; mTangents[i] = tangent * 0.5f + Vector3(0.5f); } for (int i = 0; i < mNumVertices; ++ i) ((Vector3 *)data)[mNumVertices * 2 + i] = mTangents[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) { //cout << "dotprods: " << endl; /*for (int i = 0; i < 100; ++ i) { //cout << mTangents[i] << " " << mNormals[i] << " " << DotProd(Normalize(mTangents[i]), Normalize(mNormals[i])) << endl; float d = fabs(DotProd(Normalize(mTangents[i]), Normalize(mNormals[i]))); if (d > 0.01) cout << d << " "; //cout << d << " "; } cout << endl; */ for (int i = 0; i < 50; ++ i) { cout << mTexCoords[i].first << "," << mTexCoords[i].second << " "; } 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) { //glClientActiveTextureARB(GL_TEXTURE1_ARB); //glTexCoordPointer(2, GL_FLOAT, (char *)NULL + mNumVertices * sizeof(Vector3)); glColorPointer(3, GL_FLOAT, 0, (char *)NULL + mNumVertices * 2 * sizeof(Vector3)); currentPointer = mNumVertices * 3 * sizeof(Vector3); //glClientActiveTextureARB(GL_TEXTURE0_ARB); } 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; } }