561 lines
9.7 KiB
C
561 lines
9.7 KiB
C
|
|
#define GL_GLEXT_PROTOTYPES
|
|
|
|
#include <GL/glext.h>
|
|
|
|
#include <GL/gl.h> // GL 1.1 functions
|
|
|
|
#include <GL/glx.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#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<vector2> * 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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|