#define GL_GLEXT_PROTOTYPES #include #include // GL 1.1 functions #include #include "block.h" #include "shader.h" #include "program.h" #include "floatArray.h" #include "unsignedIntegerArray.h" class mesh{ struct program * program; struct unsignedIntegerArray * indices; struct floatArray * textureCoordinates; struct floatArray * vertexCoordinates; struct floatArray * normalCoordinates; struct array * blocks = new array(); GLuint vertexArrayObject; GLuint uniformBuffer; GLuint indexBuffer; GLuint vertexbuffer; GLuint textureCoordinateBuffer; GLuint meshIndexBuffer; GLuint uvBuffer; struct unsignedIntegerArray * uniformBuffers = new unsignedIntegerArray(); struct block * getUniformBlock( char * blockName ) { int blockCount = this->blocks->length(); for ( int i = 0; i < blockCount; ++i ) { struct block * currentBlock = this->blocks->get( i ); char * currentBlockName = currentBlock->name; if( currentBlockName == blockName ) { return currentBlock; } } return NULL; } void bindBlock( struct block * blockInstance ) { //printf("%s\n", blockInstance); blockInstance->createBuffer(); this->blocks->add( blockInstance ); } void setProgram( struct program * currentProgram ) { this->program = currentProgram; } GLuint getGLTypeSize( GLuint type ) { switch( type ) { case GL_FLOAT: return sizeof( GLfloat ); break; case GL_INT: return sizeof( GLint ); break; case GL_UNSIGNED_INT: return sizeof( GLuint ); break; } return 0; } GLuint getComponentType( GLuint type ) { switch( type ) { case GL_FLOAT: return GL_FLOAT; break; case GL_FLOAT_VEC2: return GL_FLOAT; break; case GL_FLOAT_VEC3: return GL_FLOAT; break; case GL_FLOAT_VEC4: return GL_FLOAT; break; case GL_INT: return GL_INT; break; case GL_INT_VEC2: return GL_INT; break; case GL_INT_VEC3: return GL_INT; break; case GL_INT_VEC4: return GL_INT; break; case GL_UNSIGNED_INT: return GL_UNSIGNED_INT; break; case GL_UNSIGNED_INT_VEC2: return GL_UNSIGNED_INT; break; case GL_UNSIGNED_INT_VEC3: return GL_UNSIGNED_INT; break; case GL_UNSIGNED_INT_VEC4: return GL_UNSIGNED_INT; break; } return 0; } GLuint getItemSize( GLuint type ) { switch( type ) { case GL_FLOAT: return 1; break; case GL_FLOAT_VEC2: return 2; break; case GL_FLOAT_VEC3: return 3; break; case GL_FLOAT_VEC4: return 4; break; case GL_INT: return 1; break; case GL_INT_VEC2: return 2; break; case GL_INT_VEC3: return 3; break; case GL_INT_VEC4: return 4; break; case GL_UNSIGNED_INT: return 1; break; case GL_UNSIGNED_INT_VEC2: return 2; break; case GL_UNSIGNED_INT_VEC3: return 3; break; case GL_UNSIGNED_INT_VEC4: return 4; break; } return 0; } GLuint createBuffer( char * attributeName, void * data, GLenum target, GLenum usage ) { GLuint itemSize; GLuint componentType; GLuint componentSize; GLuint attributeLocation; //GLenum target; GLuint isIndexBuffer = 0; GLuint buffer; glGenBuffers( 1, &buffer ); if( attributeName == "index" ) { isIndexBuffer = 1; componentType = GL_INT; componentSize = this->getGLTypeSize( componentType ); target = GL_ELEMENT_ARRAY_BUFFER; glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffer ); } else { attribute * attribute = this->program->getAttributeByName( attributeName ); if( attribute == NULL ) { return 0; } itemSize = this->getItemSize( attribute->type ); componentType = this->getComponentType( attribute->type ); componentSize = this->getGLTypeSize( componentType ); attributeLocation = attribute->location; target = GL_ARRAY_BUFFER; glEnableVertexAttribArray( attribute->location ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); } //printf("Name: %s itemSize: %i componentSize: %i ", attributeName, itemSize, componentSize); int itemCount; GLuint bufferSize; if( componentType == GL_UNSIGNED_INT || componentType == GL_INT ) { unsignedIntegerArray * test = ( unsignedIntegerArray * ) data; itemCount = test->length(); bufferSize = itemCount * componentSize; glBufferData( target, bufferSize, test->items, usage ); if( isIndexBuffer == NULL ) { glVertexAttribIPointer( attributeLocation, itemSize, componentType, 0, ( void * ) 0 ); } } else if( componentType == GL_FLOAT ) { floatArray * test = ( floatArray * ) data; itemCount = test->total; bufferSize = itemCount * componentSize; glBufferData( GL_ARRAY_BUFFER, bufferSize, test->items, usage ); if( isIndexBuffer == NULL ) { glVertexAttribPointer( attributeLocation, itemSize, componentType, GL_FALSE, 0, ( void * ) 0 ); } } //printf("itemCount: %i\n\n", bufferSize); GLint compareSize = 0; glGetBufferParameteriv( target, GL_BUFFER_SIZE, &compareSize ); if( bufferSize != compareSize ) { glDeleteBuffers(1, &buffer); printf("ERROR: size error"); return 0; } return buffer; } void createBuffers( ) { struct unsignedIntegerArray * indices = new unsignedIntegerArray(); struct floatArray * textureCoordinates = new floatArray(); struct floatArray * vertexCoordinates = new floatArray(); struct floatArray * normalCoordinates = new floatArray(); struct unsignedIntegerArray * meshIndices = new unsignedIntegerArray(); int subdivisionsDepth = 1; int subdivisionsWidth = 1; float width = 2; float depth = 2; int meshCount = 100 * 50; int meshStartIndex = 0; for (int meshIndex = 0; meshIndex < meshCount; ++meshIndex) { meshStartIndex = meshIndices->length(); //printf("Number of vectex cnumVertsAcrossoordinates: %i\n\n", vertexCoordinates->length()); int numVertsAcross = subdivisionsWidth + 1; for ( int z = 0; z < subdivisionsDepth; z++ ) { for ( int x = 0; x < subdivisionsWidth; x++ ) { // triangle 1 of quad indices->add( ( z + 0 ) * numVertsAcross + x + meshStartIndex ); indices->add( ( z + 1 ) * numVertsAcross + x + meshStartIndex ); indices->add( ( z + 0 ) * numVertsAcross + x + 1 + meshStartIndex ); // triangle 2 of quad indices->add( ( z + 1 ) * numVertsAcross + x + meshStartIndex ); indices->add( ( z + 1 ) * numVertsAcross + x + 1 + meshStartIndex ); indices->add( ( z + 0 ) * numVertsAcross + x + 1 + meshStartIndex ); } } for ( int z = 0; z <= subdivisionsDepth; z++ ) { for ( int x = 0; x <= subdivisionsWidth; x++ ) { float u = ( float ) x;// / subdivisionsWidth; float v = ( float ) z;// / subdivisionsDepth; textureCoordinates->add( u ); textureCoordinates->add( ( 1 - v ) ); vertexCoordinates->add( width * u - width * 0.5 ); vertexCoordinates->add( depth * v - depth * 0.5 ); vertexCoordinates->add( 0 ); normalCoordinates->add( 0 ); normalCoordinates->add( 0 ); normalCoordinates->add( 1 ); meshIndices->add( meshIndex ); } } } glGenVertexArrays( 1, &this->vertexArrayObject ); glBindVertexArray( this->vertexArrayObject ); this->vertexbuffer = this->createBuffer( "position", vertexCoordinates, GL_ARRAY_BUFFER, GL_STATIC_DRAW ); this->textureCoordinateBuffer = this->createBuffer( "textureCoordinates", textureCoordinates, GL_ARRAY_BUFFER, GL_STATIC_DRAW ); this->vertexbuffer = this->createBuffer( "meshIndex", meshIndices, GL_ARRAY_BUFFER, GL_STATIC_DRAW ); this->indexBuffer = this->createBuffer( "index", indices, GL_ARRAY_BUFFER, GL_STATIC_DRAW ); //this->subMeshPositions = this->createBuffer( "subMeshPositions", indices, GL_SHADER_STORAGE_BUFFER, GL_STATIC_DRAW ); int blockCount = this->blocks->length(); for (int i = 0; i < blockCount; ++i) { block * currentBlock = this->blocks->get( i ); int size = currentBlock->bufferSize; printf("Bind block %s bufferSize: %i bindingPoint: %i bufferType: %s \n\n", currentBlock->name, currentBlock->bufferSize, currentBlock->bindingPoint, currentBlock->getBufferTypeText( ) ); glBindBuffer( currentBlock->bufferType, currentBlock->buffer ); glBindBufferBase( currentBlock->bufferType, currentBlock->bindingPoint, currentBlock->buffer ); glBufferData( currentBlock->bufferType, currentBlock->bufferSize, 0, GL_DYNAMIC_DRAW ); } glBindVertexArray( 0 ); /* unsigned int uniformBufferSize = 152; // allocate 152 bytes of memory glGenBuffers( 1, &this->uniformBuffer ); glBindBuffer( GL_UNIFORM_BUFFER, this->uniformBuffer ); glBufferData( GL_UNIFORM_BUFFER, uniformBufferSize, NULL, GL_DYNAMIC_DRAW ); glBindBuffer( GL_UNIFORM_BUFFER, this->uniformBuffer ); //glBufferData( this->uniformBuffer, size, data ); glBufferSubData( this->uniformBuffer, offset, size, data ); */ //glBindBufferRange( GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4) ); /* glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f); glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection)); glBindBuffer(GL_UNIFORM_BUFFER, 0); glm::mat4 view = camera.GetViewMatrix(); glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices); glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view)); glBindBuffer(GL_UNIFORM_BUFFER, 0); */ //glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, indexBufferSize, indices->items ); /* int vertexCount = vertexCoordinates->length(); for (int i = 0; i < vertexCount; ++i) { float currentVertex = vertexCoordinates->get( i ); printf(" %i: %f \n", i, currentVertex); } int indexCount = indices->length(); printf("\n\n"); for (int i = 0; i < indexCount; ++i) { int currentIndex = indices->get( i ); printf(" %i: %i \n", i, currentIndex); } printf("number of indices: %i\n", indices->length()); */ this->indices = indices; this->textureCoordinates = textureCoordinates; this->vertexCoordinates = vertexCoordinates; this->normalCoordinates = normalCoordinates; } createOrderedTriangleStripQuad() { /* vector3 * a = new vector3(0.0, 0.0, 0.0); vector3 * b = new vector3(0.0, 0.5, 0.0); vector3 * c = new vector3(0.5, 0.0, 0.0); vector3 * d = new vector3(0.5, 0.5, 0.0); GLfloat g_vertex_buffer_data[ 12 * 2 ]; for (int i = 0; i < 2; ++i) { int vectorIndex = i * 3; float index = 0.5 *i; g_vertex_buffer_data[ vectorIndex + 0 ] = 0.0 - index; g_vertex_buffer_data[ vectorIndex + 1 ] = 0.; g_vertex_buffer_data[ vectorIndex + 2 ] = 0.0; g_vertex_buffer_data[ vectorIndex + 3 ] = 0.0 - index; g_vertex_buffer_data[ vectorIndex + 4 ] = 0.5; g_vertex_buffer_data[ vectorIndex + 5 ] = 0.0; g_vertex_buffer_data[ vectorIndex + 6 ] = 0.5 - index; g_vertex_buffer_data[ vectorIndex + 7 ] = 0.0; g_vertex_buffer_data[ vectorIndex + 8 ] = 0.0; g_vertex_buffer_data[ vectorIndex + 9 ] = 0.5 - index; g_vertex_buffer_data[ vectorIndex + 10 ] = 0.5; g_vertex_buffer_data[ vectorIndex + 11 ] = 0.0; } GLfloat g_vertex_buffer_data[] = { 0.0, 0.0, 0.0f, 0.0, 0.5, 0.0f, 0.5f, 0.0f, 0.0f, .5, 0.5, 0.0 }; */ } }