Initial commit
This commit is contained in:
568
application/demos/example.opengl/engine/program.c
Normal file
568
application/demos/example.opengl/engine/program.c
Normal file
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* This file is automaticaly generated, Please dont edit this file!
|
||||
*/
|
||||
#include <engine/program.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void program_addShader( program * this, struct shader * shaderInstance ) {
|
||||
|
||||
array_add( this->shaders, shaderInstance );
|
||||
|
||||
}
|
||||
|
||||
|
||||
GLint program_glGetProgramResourceiv( program * this, GLint programProperty, GLint index, GLint Property ) {
|
||||
|
||||
GLint offsetValues;
|
||||
|
||||
glGetProgramResourceiv( this->glProgram, programProperty, index, 1, &Property , 1, 0, &offsetValues );
|
||||
|
||||
return offsetValues;
|
||||
|
||||
}
|
||||
|
||||
GLchar * program_glGetProgramResourceName( program * this, GLint programProperty, GLint index, GLint nameLength ) {
|
||||
|
||||
|
||||
GLchar name[ GL_NAME_LENGTH + 1 ];
|
||||
|
||||
glGetProgramResourceName(
|
||||
this->glProgram,
|
||||
|
||||
programProperty,
|
||||
index,
|
||||
GL_NAME_LENGTH + 1,
|
||||
0,
|
||||
name );
|
||||
|
||||
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void program_extractBlocks( program * this ) {
|
||||
|
||||
GLint programInterfaces[2] = { GL_SHADER_STORAGE_BLOCK, GL_UNIFORM_BLOCK };
|
||||
|
||||
GLint programProperties[2] = { GL_BUFFER_VARIABLE, GL_UNIFORM };
|
||||
|
||||
GLenum programBufferTypes[2] = { GL_SHADER_STORAGE_BUFFER, GL_UNIFORM_BUFFER };
|
||||
|
||||
|
||||
|
||||
for (int blockTypeIndex = 0; blockTypeIndex < 2; ++blockTypeIndex)
|
||||
{
|
||||
|
||||
|
||||
GLint program = this->glProgram;
|
||||
|
||||
GLint numActiveResources;
|
||||
|
||||
GLint programInterface = programInterfaces[blockTypeIndex];
|
||||
|
||||
GLint programProperty = programProperties[blockTypeIndex];
|
||||
|
||||
GLenum programBufferType = programBufferTypes[blockTypeIndex];
|
||||
|
||||
glGetProgramInterfaceiv( program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources );
|
||||
|
||||
|
||||
|
||||
for ( GLuint blockIndex = 0; blockIndex < numActiveResources; blockIndex++ ) {
|
||||
|
||||
struct block * blockInstance = block_newPointer();
|
||||
|
||||
|
||||
|
||||
GLint blockNameLength = program_glGetProgramResourceiv( this, programInterface, blockIndex, GL_NAME_LENGTH );
|
||||
|
||||
blockInstance->bufferSize = program_glGetProgramResourceiv( this, programInterface, blockIndex, GL_BUFFER_DATA_SIZE );
|
||||
|
||||
GLint numberActiveVariables = program_glGetProgramResourceiv( this, programInterface, blockIndex, GL_NUM_ACTIVE_VARIABLES );
|
||||
|
||||
blockInstance->bindingPoint = program_glGetProgramResourceiv( this, programInterface, blockIndex, GL_BUFFER_BINDING );
|
||||
|
||||
|
||||
GLchar name[ GL_NAME_LENGTH + 1 ];
|
||||
|
||||
glGetProgramResourceName( this->glProgram, programInterface, blockIndex, GL_NAME_LENGTH + 1, NULL, name );
|
||||
|
||||
blockInstance->name = malloc( GL_NAME_LENGTH );
|
||||
|
||||
strcpy( blockInstance->name, name );
|
||||
|
||||
|
||||
blockInstance->bufferType = programBufferType;
|
||||
|
||||
printf("block:%s \n\n", blockInstance->name );
|
||||
|
||||
printf(" block name %s\n", blockInstance->name);
|
||||
|
||||
printf(" block buffer size: %i\n", blockInstance->bufferSize);
|
||||
|
||||
printf(" block binding point: %i\n\n", blockInstance->bindingPoint);
|
||||
|
||||
|
||||
|
||||
|
||||
GLint indices[ numberActiveVariables ];
|
||||
|
||||
GLenum member = GL_ACTIVE_VARIABLES;
|
||||
|
||||
glGetProgramResourceiv( program, programInterface, blockIndex, 1, &member, numberActiveVariables, 0, indices );
|
||||
|
||||
printf(" number of variables: %i\n\n\n", numberActiveVariables);
|
||||
|
||||
|
||||
|
||||
|
||||
for ( GLuint index = 0; index < numberActiveVariables; index++ )
|
||||
{
|
||||
|
||||
struct member * memberInstance = member_newPointer();
|
||||
|
||||
|
||||
GLint itemIndex = indices[ index ];
|
||||
|
||||
memberInstance->index = itemIndex;
|
||||
|
||||
GLint nameLength = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_NAME_LENGTH );
|
||||
|
||||
memberInstance->offset = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_OFFSET );
|
||||
|
||||
memberInstance->type = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_TYPE );
|
||||
|
||||
memberInstance->arrayStride = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_ARRAY_STRIDE );
|
||||
|
||||
|
||||
memberInstance->size = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_ARRAY_SIZE );
|
||||
|
||||
int topLevelSize = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_TOP_LEVEL_ARRAY_SIZE );
|
||||
|
||||
int topLevelStride = program_glGetProgramResourceiv( this, programProperty, itemIndex, GL_TOP_LEVEL_ARRAY_STRIDE );
|
||||
|
||||
|
||||
if( memberInstance->arrayStride == 0 ) {
|
||||
|
||||
memberInstance->arrayStride = topLevelStride;
|
||||
|
||||
}
|
||||
|
||||
memberInstance->topLevelSize = topLevelSize;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GLchar memberName[ GL_NAME_LENGTH + 1 ];
|
||||
|
||||
glGetProgramResourceName( this->glProgram, programProperty, itemIndex, GL_NAME_LENGTH + 1, NULL, memberName );
|
||||
|
||||
memberInstance->name = malloc( GL_NAME_LENGTH );
|
||||
|
||||
strcpy( memberInstance->name, memberName );
|
||||
|
||||
|
||||
|
||||
printf(" offset: #%i name: %s vec2: %i offset: %i itemSize / arrayStride: %i Array size: %i toplevel size: %i top level size: %i \n\n",
|
||||
|
||||
memberInstance->index,
|
||||
memberInstance->name,
|
||||
memberInstance->type == GL_FLOAT_VEC2,
|
||||
memberInstance->offset,
|
||||
memberInstance->arrayStride,
|
||||
memberInstance->size, topLevelSize,
|
||||
topLevelStride );
|
||||
|
||||
|
||||
|
||||
block_add( blockInstance, memberInstance );
|
||||
|
||||
}
|
||||
|
||||
block_createBuffer( blockInstance );
|
||||
|
||||
array_add( this->blocks, blockInstance );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct block * program_createNewBlock( program * this, char * blockName ) {
|
||||
|
||||
printf("Copy buffer: %s\n\n", blockName);
|
||||
|
||||
block * originalBlock = program_getBlock( this, blockName );
|
||||
|
||||
block * blockCopy = block_newPointer();
|
||||
|
||||
blockCopy->members = originalBlock->members;
|
||||
|
||||
blockCopy->bindingPoint = originalBlock->bindingPoint;
|
||||
|
||||
blockCopy->index = originalBlock->index;
|
||||
|
||||
blockCopy->bufferSize = originalBlock->bufferSize;
|
||||
|
||||
block_createBuffer( blockCopy );
|
||||
|
||||
return blockCopy;
|
||||
|
||||
}
|
||||
|
||||
struct block * program_getBlock( program * this, char * blockName ) {
|
||||
|
||||
int blockCount = array_length( this->blocks );
|
||||
|
||||
for ( int i = 0; i < blockCount; ++i )
|
||||
{
|
||||
block * currentBlock = array_get( this->blocks, i );
|
||||
|
||||
char * currentBlockName = currentBlock->name;
|
||||
|
||||
if( char_operator_compare( currentBlockName , blockName) ) {
|
||||
|
||||
return currentBlock;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void program_create( program * this ) {
|
||||
|
||||
this->glProgram = glCreateProgram();
|
||||
|
||||
|
||||
array * shaders = this->shaders;
|
||||
|
||||
int shaderCount = array_length( shaders );
|
||||
|
||||
|
||||
for (int i = 0; i < shaderCount; ++i)
|
||||
{
|
||||
|
||||
shader * currentShader = array_get( shaders, i );
|
||||
|
||||
glAttachShader( this->glProgram, currentShader->glShader );
|
||||
|
||||
}
|
||||
|
||||
glLinkProgram( this->glProgram );
|
||||
|
||||
glUseProgram( this->glProgram );
|
||||
|
||||
|
||||
program_extractBlocks( this );
|
||||
|
||||
program_extractAttributes( this );
|
||||
|
||||
program_extractUniforms( this );
|
||||
|
||||
}
|
||||
|
||||
void program_bindBlock( program * this, char * blockName ) {
|
||||
|
||||
block * currentBlock = program_getBlock( this, blockName );
|
||||
|
||||
glBindBufferBase( currentBlock->bufferType, currentBlock->bindingPoint, currentBlock->buffer );
|
||||
|
||||
}
|
||||
|
||||
void program_use( program * this ) {
|
||||
|
||||
glUseProgram( this->glProgram );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void program_extractUniforms( program * this ) {
|
||||
|
||||
int attributeCount = 0;
|
||||
|
||||
GLsizei bufSize = 64;
|
||||
|
||||
GLsizei length;
|
||||
|
||||
GLint size;
|
||||
|
||||
GLenum type;
|
||||
|
||||
int uniformCount = 0;
|
||||
|
||||
glGetProgramiv( this->glProgram, GL_ACTIVE_UNIFORMS, &uniformCount );
|
||||
|
||||
for (int i = 0; i < uniformCount; i++)
|
||||
{
|
||||
|
||||
struct uniform * uniformInstance = uniform_newPointer();
|
||||
|
||||
GLenum type;
|
||||
|
||||
GLchar name[bufSize];
|
||||
|
||||
glGetActiveUniform( this->glProgram, ( GLuint ) i, bufSize, &length, &size, &type, uniformInstance->name );
|
||||
|
||||
|
||||
|
||||
GLint uniformLocation = glGetUniformLocation( this->glProgram, uniformInstance->name );
|
||||
|
||||
uniformInstance->location = uniformLocation;
|
||||
|
||||
uniformInstance->type = type;
|
||||
|
||||
array_add( this->uniforms, uniformInstance );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void program_extractAttributes( program * this ) {
|
||||
|
||||
int attributeCount = 0;
|
||||
|
||||
GLsizei bufSize = 64;
|
||||
|
||||
GLsizei length;
|
||||
|
||||
GLint size;
|
||||
|
||||
GLenum type;
|
||||
|
||||
glGetProgramiv( this->glProgram, GL_ACTIVE_ATTRIBUTES, &attributeCount );
|
||||
|
||||
for (int i = 0; i < attributeCount; i++)
|
||||
{
|
||||
GLenum type;
|
||||
|
||||
attribute * attributeInstance = attribute_newPointer();
|
||||
|
||||
glGetActiveAttrib( this->glProgram, ( GLuint ) i, bufSize, &length, &size, &type, attributeInstance->name);
|
||||
|
||||
|
||||
|
||||
GLint attributeLocation = glGetAttribLocation( this->glProgram, attributeInstance->name );
|
||||
|
||||
glEnableVertexAttribArray( attributeLocation );
|
||||
|
||||
|
||||
attributeInstance->location = attributeLocation;
|
||||
|
||||
|
||||
|
||||
attributeInstance->type = type;
|
||||
|
||||
array_add( this->attributes, attributeInstance );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct attribute * program_getAttributeByName( program * this, char * attributeName ) {
|
||||
|
||||
int attributeCount = array_length( this->attributes );
|
||||
|
||||
|
||||
|
||||
for ( int i = 0; i < attributeCount; ++i )
|
||||
{
|
||||
struct attribute * currentAttribute = array_get( this->attributes, i );
|
||||
|
||||
char * currentAttributeName = currentAttribute->name;
|
||||
|
||||
|
||||
|
||||
if( char_operator_compare( currentAttributeName , attributeName) ) {
|
||||
|
||||
return currentAttribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void program_setUniform( program * this, char * name, void * value ) {
|
||||
|
||||
int uniformCount = array_length( this->uniforms );
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < uniformCount; ++i)
|
||||
{
|
||||
uniform * currentUniform = array_get( this->uniforms, i );
|
||||
|
||||
char * uniformName = (char *)currentUniform->name;
|
||||
|
||||
|
||||
|
||||
if( char_operator_compare( uniformName , name) ) {
|
||||
|
||||
|
||||
|
||||
switch( currentUniform->type ) {
|
||||
|
||||
|
||||
case GL_FLOAT_VEC2:
|
||||
|
||||
vector2 * vector2Value = ( vector2 * ) value;
|
||||
|
||||
|
||||
|
||||
glUniform2f( currentUniform->location, vector2Value->x, vector2Value->y );
|
||||
|
||||
break;
|
||||
|
||||
case GL_FLOAT_VEC3:
|
||||
|
||||
vector3 * vector3Value = ( vector3 * ) value;
|
||||
|
||||
|
||||
|
||||
glUniform3f( currentUniform->location, vector3Value->x, vector3Value->y, vector3Value->z );
|
||||
|
||||
break;
|
||||
|
||||
case GL_SAMPLER_2D:
|
||||
|
||||
program_updateSampler2D( this, currentUniform, value );
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
|
||||
program_updateSampler2D( this, currentUniform, value );
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void program_updateSampler2D( program * this, uniform * currentUniform, void * value ) {
|
||||
|
||||
glEnable( GL_BLEND );
|
||||
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
sampler2D * sampler = ( sampler2D * ) value;
|
||||
|
||||
|
||||
if( !sampler->binded ) {
|
||||
|
||||
sampler->index = this->samplerIndex++;
|
||||
|
||||
sampler2D_bind( sampler );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
glActiveTexture( GL_TEXTURE0 + sampler->index );
|
||||
|
||||
glBindTexture( sampler->target, sampler->glTexture );
|
||||
|
||||
|
||||
|
||||
glUniform1i( currentUniform->location, sampler->index );
|
||||
|
||||
|
||||
}
|
||||
|
||||
program program_new() {
|
||||
|
||||
program instance;
|
||||
|
||||
instance.samplerIndex = 0;
|
||||
|
||||
instance.uniforms = array_newPointer();
|
||||
|
||||
instance.attributes = array_newPointer();
|
||||
|
||||
instance.blocks = array_newPointer();
|
||||
|
||||
instance.shaders = array_newPointer();
|
||||
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
program * program_newPointer() {
|
||||
|
||||
struct program * pointer = malloc( sizeof ( struct program ) );
|
||||
|
||||
pointer->samplerIndex = 0;
|
||||
|
||||
pointer->uniforms = array_newPointer();
|
||||
|
||||
pointer->attributes = array_newPointer();
|
||||
|
||||
pointer->blocks = array_newPointer();
|
||||
|
||||
pointer->shaders = array_newPointer();
|
||||
|
||||
return pointer;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user