#define GL_GLEXT_PROTOTYPES #include #include // GL 1.1 functions #include #include #include "fileSystem.h" #include "array.h" #include "char.h" #include "sampler2D.h" #include "member.h" class block{ array * members = new array(); GLint buffer; GLuint index; GLenum bufferType; GLint bufferSize; GLint bindingPoint; GLchar * name; float * data; GLint autoUpload = 0; add( struct member * memberInstance ) { this->members->add( memberInstance ); } enableAutoUpload() { this->autoUpload = 1; } char * getBufferTypeText( ) { switch( this->bufferType ) { case GL_SHADER_STORAGE_BUFFER: return "GL_SHADER_STORAGE_BUFFER"; break; case GL_UNIFORM_BUFFER: return "GL_UNIFORM_BUFFER"; break; } return "buffer message not found"; } createBuffer() { unsigned int blockBufferSize = this->bufferSize; // allocate 152 bytes of memory //printf(" create array for block %s os size %i \n", this->name, this->bufferSize ); this->data = ( float * ) malloc( blockBufferSize ); glGenBuffers( 1, &this->buffer ); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->index, this->buffer ); glBufferData( this->bufferType, blockBufferSize, 0, GL_DYNAMIC_DRAW ); } void upload() { //printf("upload uniform buffer: %f %f %f %f\n", this->data[0], this->data[1], this->data[2], this->data[3]); //printf("upload uniform buffer: %i\n", this->index); //glBindBuffer( this->bufferType, this->buffer ); //glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); //glBufferData( this->bufferType, this->bufferSize, this->data, GL_DYNAMIC_DRAW ); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, 0, this->bufferSize, this->data ); } mapBufferError( void * pointer ) { if ( pointer == NULL ){ GLenum errorCode = glGetError(); switch( errorCode ) { case GL_INVALID_ENUM: printf("GL_INVALID_ENUM\n"); break; case GL_INVALID_OPERATION: printf("GL_INVALID_OPERATION\n"); break; case GL_INVALID_VALUE: printf("GL_INVALID_VALUE\n"); break; } printf("null pointer on buffer: %i\n", errorCode); return; } } void * getMemberArray( char * name ) { glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT ); vector * output = new vector(); int uniformCount = this->members->length(); for (int i = 0; i < uniformCount; ++i) { member * currentMember = this->members->get( i ); char * memberName = ( char * ) currentMember->name; if( memberName == name ) { int size = currentMember->size * 8; int offset = currentMember->offset / 4; output->items = glMapBufferRange( GL_SHADER_STORAGE_BUFFER, 0, size, GL_MAP_WRITE_BIT ); output->total = currentMember->size; this->mapBufferError( output->items ); } } glUnmapBuffer( GL_SHADER_STORAGE_BUFFER ); return output; } void setMemberArrayRow( char * name, int arrayIndex, float * data ) { int memberCount = this->members->length(); for (int i = 0; i < memberCount; ++i) { member * currentMember = this->members->get( i ); char * memberName = ( char * ) currentMember->name; if( memberName == name ) { int size = currentMember->size * 8; int arrayStride = currentMember->arrayStride; int offset = arrayStride * arrayIndex; //printf("set array stride: %i %i\n", arrayIndex, arrayStride); //int offset = currentMember->offset / 4; if( this->autoUpload ) { glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, offset, arrayStride, data ); } memcpy( this->data + offset, data, arrayStride ); } } } void setMemberArray( char * name, float * data ) { int memberCount = this->members->length(); for (int i = 0; i < memberCount; ++i) { member * currentMember = this->members->get( i ); char * memberName = ( char * ) currentMember->name; if( memberName == name ) { int size = currentMember->size * 8; int offset = currentMember->offset / 4; memcpy( this->data + offset, data, size ); } } } void setMemberItem( char * name, int index, void * value ) { int uniformCount = this->members->length(); //printf("uniformCount: %i\n\n", uniformCount); for (int i = 0; i < uniformCount; ++i) { member * currentMember = this->members->get( i ); char * memberName = ( char * ) currentMember->name; if( memberName == name ) { //printf("\n\n Update this uniform from uniform block %s\n\n", name); int stride; int strideNormalized; int size; int offset; switch( currentMember->type ) { case GL_FLOAT_VEC2: stride = currentMember->arrayStride; strideNormalized = stride / sizeof( float ) ; //printf("get size of item: %i\n",strideNormalized ); vector2 * vector2Value = ( vector2 * ) value; size = 8; offset = currentMember->offset; if( this->autoUpload ) { GLint arrayIndex = ( strideNormalized * index * 2 * 8 ); float data[2] = { vector2Value->x, vector2Value->y }; printf("%i: (size:%i) %f %f\n", arrayIndex, data[0], data[1]); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, arrayIndex, size, data ); } else { GLint dataOffset = offset / sizeof( float ); GLint arrayIndex = ( strideNormalized * index ); // need to fix this if( currentMember->topLevelSize == 1 ) { //arrayIndex = 0; } //printf(" %i: %f \n", dataOffset + 1 + arrayIndex , vector2Value->y ); this->data[ dataOffset + arrayIndex ] = vector2Value->x; this->data[ dataOffset + 1 + arrayIndex ] = vector2Value->y; } break; case GL_FLOAT_VEC3: stride = currentMember->arrayStride; strideNormalized = stride / sizeof( float ) ; vector3 * vector3Value = ( vector3 * ) value; size = 12; offset = currentMember->offset; if( this->autoUpload ) { float data[3] = { vector3Value->x, vector3Value->y, vector3Value->z }; // printf("%f %f\n", data[0], data[1]); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, offset, size, data ); } else { GLint dataOffset = offset / sizeof( float ); GLint arrayIndex = ( strideNormalized * index ); this->data[ dataOffset + arrayIndex ] = vector3Value->x; this->data[ dataOffset + 1 + arrayIndex ] = vector3Value->y; this->data[ dataOffset + 2 + arrayIndex ] = vector3Value->z; } break; case GL_SAMPLER_2D: break; } } } } void setData( float * data ) { this->data = data; } void setMember( char * name, void * value ) { int uniformCount = this->members->length(); //printf("uniformCount: %i\n\n", uniformCount); for (int i = 0; i < uniformCount; ++i) { member * currentMember = this->members->get( i ); char * memberName = ( char * ) currentMember->name; if( memberName == name ) { //printf("\n\n Update this uniform from uniform block %s\n\n", name); GLuint size = 8; GLint offset = currentMember->offset; switch( currentMember->type ) { case GL_INT: int intValue = *( int * ) value; printf("set int value: %i offset: %i\n", intValue, offset); if( this->autoUpload ) { float data[1] = { value }; // printf("%f %f\n", data[0], data[1]); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, offset, size, data ); } else { GLint dataOffset = offset / sizeof( float ); this->data[ dataOffset ] = intValue; //this->data[ dataOffset + 1 ] = vector2Value->y; } break; case GL_FLOAT: float floatValue = *( float * ) value; printf("set int value: %f offset: %i\n", floatValue, offset); if( this->autoUpload ) { float data[1] = { value }; // printf("%f %f\n", data[0], data[1]); glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, offset, size, data ); } else { GLint dataOffset = offset / sizeof( float ); this->data[ dataOffset ] = floatValue; //this->data[ dataOffset + 1 ] = vector2Value->y; } break; case GL_FLOAT_VEC2: vector2 * vector2Value = ( vector2 * ) value; if( this->autoUpload ) { float data[2] = { vector2Value->x, vector2Value->y }; glBindBuffer( this->bufferType, this->buffer ); glBindBufferBase( this->bufferType, this->bindingPoint, this->buffer ); glBufferSubData( this->bufferType, offset, size, data ); } else { GLint dataOffset = offset / sizeof( float ); this->data[ dataOffset ] = vector2Value->x; this->data[ dataOffset + 1 ] = vector2Value->y; } break; case GL_FLOAT_VEC3: vector3 * vector3Value = ( vector3 * ) value; break; case GL_SAMPLER_2D: break; } } } } }