#pragma once #include "AftrOpenGLIncludes.h" #include "AftrGlobals.h" #include "Vector.h" #include "GLSLAttributeArray.h" #include "ModelMeshRenderData.h" #include #include #include namespace Aftr { class ModelMeshDataShared; /** This class is the internal mechanism used by the ModelMeshDataShared object to generate the proper Vertex Arrays used by OpenGL so that the mesh can be rendered via VBOs or VAs. The associted strides and offsets for the verticies, indicies, colors, and textures are publicly accessible for use by the owning ModelMeshDataShared object. */ class ModelMeshRenderDataGenerator { public: ModelMeshRenderDataGenerator(); virtual ~ModelMeshRenderDataGenerator(); std::string toString(); /** Public strides and offsets to provide fast access when dispatching the VBOs/VAs. The user should not modify these; however, getters are not implemented because these need to be accessed as quickly as possible. They are also listed first so a compiler may optimize the cache layout for this class to put these members first. */ GLsizei stride = 0; unsigned int vertsOffset = 0; GLenum numColorChannels = GL_RGBA; ///< GL_RGB or GL_RGBA unsigned int colorsOffset = 0; unsigned int normalsOffset = 0; std::vector< unsigned int > texCoordsOffset; std::vector< unsigned int > attributesOffset; /** Determines the primitive shape the indicies define for the corresponding set of verticies. Valid values include GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON. */ void setIndexTopology( GLenum indexTopology ) { this->indexTopology = indexTopology; } GLenum getIndexTopology() { return this->indexTopology; } bool useTangents = false; std::vector< Vector >* getVerts() { return &this->verts; } std::vector< unsigned int >* getIndicies() { return &this->indicies; } std::vector< aftrColor4ub >* getColors() { return &this->colors; } std::vector< std::pair< std::vector< aftrTexture4f >, GLenum > >* getTexCoords() { return &this->texCoords; } std::vector< GLSLAttributeArray >* getAttributes() { return &this->attributes; } std::map< unsigned int, std::pair< unsigned int, unsigned int > >* getVertIdxToOrigVertIdxMap() { return &this->vertIdxToOrigVertIdx; } /** Generates an optimized buffer for this mesh. The first GLvoid* is a pointer to the interleaved vertex data. The second GLvoid* is a pointer to the index data. The member variables of this instance (namely, strides (size of each vertex entry), vertsOffsets, numColorChannels, colorsOffset, normalsOffset, texCoordsOffset, and attributesOffset) indicate the necessary offset to generate a VBO or render using a VA. */ virtual ModelMeshRenderData generate( MESH_SHADING_TYPE shadingType, GLenum glPrimType ); virtual ModelMeshRenderData generateFlat( GLenum glPrimType ); virtual ModelMeshRenderData generateFlatTriangles(); virtual ModelMeshRenderData generateSmooth( GLenum glPrimType ); virtual ModelMeshRenderData generateSmoothTriangles(); virtual ModelMeshRenderData generateNoNormals( GLenum glPrimType ); virtual ModelMeshRenderData generateNoNormalsTriangles(); virtual ModelMeshRenderData generateNoNormalsPoints(); virtual ModelMeshRenderData generateNoNormalsPointsFromPoints(); virtual ModelMeshRenderData generateNoNormalsPointsFromTriangles(); virtual ModelMeshRenderData generateNoNormalsLineStrip(); virtual ModelMeshRenderData generateNoNormalsLineStripFromLineStrip(); virtual ModelMeshRenderData generateNoNormalsLines(); virtual ModelMeshRenderData generateNoNormalsLinesFromLines(); virtual ModelMeshRenderData generateNoNormalsLineLoop(); virtual ModelMeshRenderData generateNoNormalsLineLoopFromLineLoop(); virtual ModelMeshRenderData generateNoNormalsLineLoopFromTriangles(); //generates the render data when no conversion is necessary lines->lines, triangles->triangles, etc... virtual ModelMeshRenderData generateNoTransformRequired(); protected: std::vector< Vector > verts; ///< All verticies contained in this mesh std::vector< unsigned int > indicies; ///< Indicies into the verts /** This stores a mapping from a current vertex index to the original (meshID, vertex index) that was read from file/standard input within the ModelParser::parse method. The size of this map will always equal the size of ModelMeshRenderDataGenerator::verts.size(). This map is useful when one generates per vertex attributes off line that are associated with vertices in a particular file. For example, if I need to generate per vertex attributes for a given 3ds file, I will have a vertex attribute set with a one-to-one mapping with the vertices in the 3ds file. Unfortunately, when that 3ds file is read in an parsed, the indices are changed by Aftr for efficiency reasons. Therefore, when the per vertex attributes are loaded from file the Aftr Mesh/Vertex Index pairs are different from those of the original 3ds file; one can no longer map the original 3ds mesh/vertIdx to the Aftr mesh/VertIdx. This map resolves the issue: [OrigFileMeshID, OrigFilVertIdx] = vertIdxToOrigVertIdx[y]; Where y is the yth vert within ModelMeshRenderDataGenerator::verts. This is not associated with the splitting / Aftrbimap reordering that may occur due to splitting within the ModelDataShared. This maps original file data to the data within this mesh. */ std::map< unsigned int, std::pair< unsigned int, unsigned int > > vertIdxToOrigVertIdx; virtual void generateOffsets( MESH_SHADING_TYPE shadingType ); ///< This generates the offsets for both smooth and flat shading (they are the same). virtual void populateVertices( GLvoid* x ); ///< This populates the buffer with the values stored in verts virtual void populateColors( GLvoid* x ); virtual void populateTextures( GLvoid* x ); virtual void populateAttributes( GLvoid* x ); virtual void populateIndicesSmooth( GLenum& idxMemType, GLvoid** x ); virtual void populateIndicesFlat( GLenum& idxMemType, GLvoid** x );//<-- may be the same as smooth, check this //normal rendering stuff virtual void processNormalData( GLvoid* x, GLvoid** y, size_t vertsSize ); virtual void populateIndicesNormal( GLenum& idxMemType, GLvoid** x, size_t vertsSize ); std::vector< aftrColor4ub > colors; ///< If size > 0, then this data uses glColor Data /** This is the color used by glColor(...). This only takes effect if this->colors.size() is 0 and the corresponding skin's isUsingColorMaterial() returns true. */ aftrColor4ub meshColor; /** Collection of multi-textured coordinates and their cooresponding GLenum defining the dimensionality of that texture set. GLenum is set to GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, or GL_TEXTURE_4D; default is 2D. */ std::vector< std::pair< std::vector< aftrTexture4f >, GLenum > > texCoords; std::vector< GLSLAttributeArray > attributes; GLsizei getOffsetFromTextureType( GLenum textureType ); GLsizei getOffsetFromAttributeType( GLSLAttributeType type ); virtual Vector calculateTangentVector( const Vector& v1, const Vector& v2, const Vector& st1, const Vector& st2 ); ///Calculates tangent space using the square patch assumption virtual Vector calculateTangentVectorSQPA( const Vector& p0, const Vector& p1, const Vector& p2, const Vector& t0, const Vector& t1, const Vector& t2 ); virtual Vector calcTangentVector( const Vector& p0, const Vector& p1, const Vector& p2, const Vector& t0, const Vector& t1, const Vector& t2, const Vector& normal ); GLenum indexTopology; ///< Valid values include GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON }; } //namespace Aftr