Initial commit
This commit is contained in:
534
application/source/engine/program.c
Normal file
534
application/source/engine/program.c
Normal file
@@ -0,0 +1,534 @@
|
||||
|
||||
#include "block.h"
|
||||
|
||||
#include "member.h"
|
||||
|
||||
#include "uniform.h"
|
||||
|
||||
|
||||
#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 "shader.h"
|
||||
|
||||
class program{
|
||||
|
||||
|
||||
GLuint samplerIndex = 0;
|
||||
|
||||
array * uniforms = new array();
|
||||
|
||||
array * attributes = new array();
|
||||
|
||||
array * blocks = new array();
|
||||
|
||||
array * shaders = new array();
|
||||
|
||||
GLuint glProgram;
|
||||
|
||||
|
||||
|
||||
addShader( struct shader * shaderInstance ) {
|
||||
|
||||
this->shaders->add( shaderInstance );
|
||||
|
||||
}
|
||||
|
||||
|
||||
GLint glGetProgramResourceiv( GLint programProperty, GLint index, GLint Property ) {
|
||||
|
||||
GLint offsetValues;
|
||||
|
||||
glGetProgramResourceiv( this->glProgram, programProperty, index, 1, &Property , 1, 0, &offsetValues );
|
||||
|
||||
return offsetValues;
|
||||
|
||||
}
|
||||
|
||||
GLchar * glGetProgramResourceName( 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 extractBlocks() {
|
||||
|
||||
GLint programInterfaces[2] = { GL_SHADER_STORAGE_BLOCK, GL_UNIFORM_BLOCK }; // GL_UNIFORM_BLOCK
|
||||
|
||||
GLint programProperties[2] = { GL_BUFFER_VARIABLE, GL_UNIFORM }; // GL_UNIFORM , GL_PROGRAM_INPUT
|
||||
|
||||
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]; // GL_UNIFORM_BLOCK
|
||||
|
||||
GLint programProperty = programProperties[blockTypeIndex]; // GL_UNIFORM
|
||||
|
||||
GLenum programBufferType = programBufferTypes[blockTypeIndex];
|
||||
|
||||
glGetProgramInterfaceiv( program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources );
|
||||
|
||||
//printf("extractShaderStorageBuffers %i\n\n", numActiveResources);
|
||||
|
||||
for ( GLuint blockIndex = 0; blockIndex < numActiveResources; blockIndex++ ) {
|
||||
|
||||
struct block * blockInstance = new block();
|
||||
|
||||
//GLint blockIndex = this->glGetProgramResourceiv( programInterface, blockIndex, GL_BLOCK_INDEX );
|
||||
|
||||
GLint blockNameLength = this->glGetProgramResourceiv( programInterface, blockIndex, GL_NAME_LENGTH );
|
||||
|
||||
blockInstance->bufferSize = this->glGetProgramResourceiv( programInterface, blockIndex, GL_BUFFER_DATA_SIZE );
|
||||
|
||||
GLint numberActiveVariables = this->glGetProgramResourceiv( programInterface, blockIndex, GL_NUM_ACTIVE_VARIABLES );
|
||||
|
||||
blockInstance->bindingPoint = this->glGetProgramResourceiv( programInterface, blockIndex, GL_BUFFER_BINDING );
|
||||
|
||||
//const GLchar * name = this->glGetProgramResourceName( programInterface, blockIndex, blockNameLength );
|
||||
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);
|
||||
|
||||
// add block
|
||||
|
||||
|
||||
for ( GLuint index = 0; index < numberActiveVariables; index++ )
|
||||
{
|
||||
|
||||
struct member * memberInstance = new member();
|
||||
|
||||
|
||||
GLint itemIndex = indices[ index ];
|
||||
|
||||
memberInstance->index = itemIndex;
|
||||
|
||||
GLint nameLength = this->glGetProgramResourceiv( programProperty, itemIndex, GL_NAME_LENGTH );
|
||||
|
||||
memberInstance->offset = this->glGetProgramResourceiv( programProperty, itemIndex, GL_OFFSET );
|
||||
|
||||
memberInstance->type = this->glGetProgramResourceiv( programProperty, itemIndex, GL_TYPE );
|
||||
|
||||
memberInstance->arrayStride = this->glGetProgramResourceiv( programProperty, itemIndex, GL_ARRAY_STRIDE );
|
||||
|
||||
|
||||
memberInstance->size = this->glGetProgramResourceiv( programProperty, itemIndex, GL_ARRAY_SIZE );
|
||||
|
||||
int topLevelSize = this->glGetProgramResourceiv( programProperty, itemIndex, GL_TOP_LEVEL_ARRAY_SIZE );
|
||||
|
||||
int topLevelStride = this->glGetProgramResourceiv( programProperty, itemIndex, GL_TOP_LEVEL_ARRAY_STRIDE );
|
||||
|
||||
|
||||
if( memberInstance->arrayStride == 0 ) {
|
||||
|
||||
memberInstance->arrayStride = topLevelStride;
|
||||
|
||||
}
|
||||
|
||||
memberInstance->topLevelSize = topLevelSize;
|
||||
|
||||
|
||||
// memberInstance->name = this->glGetProgramResourceName( programProperty, itemIndex, nameLength );
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
|
||||
blockInstance->add( memberInstance );
|
||||
|
||||
}
|
||||
|
||||
blockInstance->createBuffer();
|
||||
|
||||
this->blocks->add( blockInstance );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct block * createNewBlock( char * blockName ) {
|
||||
|
||||
printf("Copy buffer: %s\n\n", blockName);
|
||||
|
||||
block * originalBlock = this->getBlock( blockName );
|
||||
|
||||
block * blockCopy = new block();
|
||||
|
||||
blockCopy->members = originalBlock->members;
|
||||
|
||||
blockCopy->bindingPoint = originalBlock->bindingPoint;
|
||||
|
||||
blockCopy->index = originalBlock->index;
|
||||
|
||||
blockCopy->bufferSize = originalBlock->bufferSize;
|
||||
|
||||
blockCopy->createBuffer();
|
||||
|
||||
return blockCopy;
|
||||
|
||||
}
|
||||
|
||||
struct block * getBlock( char * blockName ) {
|
||||
|
||||
int blockCount = this->blocks->length();
|
||||
|
||||
for ( int i = 0; i < blockCount; ++i )
|
||||
{
|
||||
block * currentBlock = this->blocks->get( i );
|
||||
|
||||
char * currentBlockName = currentBlock->name;
|
||||
|
||||
if( currentBlockName == blockName ) {
|
||||
|
||||
return currentBlock;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
create() {
|
||||
|
||||
this->glProgram = glCreateProgram();
|
||||
|
||||
|
||||
array * shaders = this->shaders;
|
||||
|
||||
int shaderCount = shaders->length();
|
||||
|
||||
|
||||
for (int i = 0; i < shaderCount; ++i)
|
||||
{
|
||||
|
||||
shader * currentShader = shaders->get( i );
|
||||
|
||||
glAttachShader( this->glProgram, currentShader->glShader );
|
||||
|
||||
}
|
||||
|
||||
glLinkProgram( this->glProgram );
|
||||
|
||||
glUseProgram( this->glProgram );
|
||||
|
||||
|
||||
this->extractBlocks();
|
||||
|
||||
this->extractAttributes();
|
||||
|
||||
this->extractUniforms();
|
||||
|
||||
}
|
||||
|
||||
bindBlock( char * blockName ) {
|
||||
|
||||
block * currentBlock = this->getBlock( blockName );
|
||||
|
||||
glBindBufferBase( currentBlock->bufferType, currentBlock->bindingPoint, currentBlock->buffer );
|
||||
|
||||
}
|
||||
|
||||
use() {
|
||||
|
||||
glUseProgram( this->glProgram );
|
||||
|
||||
}
|
||||
|
||||
|
||||
extractUniforms() {
|
||||
|
||||
int attributeCount = 0;
|
||||
|
||||
GLsizei bufSize = 64;
|
||||
|
||||
GLsizei length; // name length
|
||||
|
||||
GLint size;
|
||||
|
||||
GLenum type; // type of the variable (float, vec3 or mat4, etc)
|
||||
|
||||
int uniformCount = 0;
|
||||
|
||||
glGetProgramiv( this->glProgram, GL_ACTIVE_UNIFORMS, &uniformCount );
|
||||
|
||||
for (int i = 0; i < uniformCount; i++)
|
||||
{
|
||||
|
||||
struct uniform * uniformInstance = new uniform();
|
||||
|
||||
GLenum type;
|
||||
|
||||
GLchar name[bufSize];
|
||||
|
||||
glGetActiveUniform( this->glProgram, ( GLuint ) i, bufSize, &length, &size, &type, uniformInstance->name );
|
||||
|
||||
//printf( " Uniform #%d Type: %u Name: %s\n", i, type, uniformInstance->name );
|
||||
|
||||
GLint uniformLocation = glGetUniformLocation( this->glProgram, uniformInstance->name );
|
||||
|
||||
uniformInstance->location = uniformLocation;
|
||||
|
||||
uniformInstance->type = type;
|
||||
|
||||
this->uniforms->add( uniformInstance );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extractAttributes() {
|
||||
|
||||
int attributeCount = 0;
|
||||
|
||||
GLsizei bufSize = 64;
|
||||
|
||||
GLsizei length; // name length
|
||||
|
||||
GLint size;
|
||||
|
||||
GLenum type; // type of the variable (float, vec3 or mat4, etc)
|
||||
|
||||
glGetProgramiv( this->glProgram, GL_ACTIVE_ATTRIBUTES, &attributeCount );
|
||||
|
||||
for (int i = 0; i < attributeCount; i++)
|
||||
{
|
||||
GLenum type;
|
||||
|
||||
attribute * attributeInstance = new attribute();
|
||||
|
||||
glGetActiveAttrib( this->glProgram, ( GLuint ) i, bufSize, &length, &size, &type, attributeInstance->name);
|
||||
|
||||
//printf(" Attribute #%d Type: %u Name: %s size: %i\n", i, type, attributeInstance->name, size);
|
||||
|
||||
GLint attributeLocation = glGetAttribLocation( this->glProgram, attributeInstance->name );
|
||||
|
||||
glEnableVertexAttribArray( attributeLocation );
|
||||
|
||||
|
||||
attributeInstance->location = attributeLocation;
|
||||
|
||||
//attributeInstance.name = name;
|
||||
|
||||
attributeInstance->type = type;
|
||||
|
||||
this->attributes->add( attributeInstance );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct attribute * getAttributeByName( char * attributeName ) {
|
||||
|
||||
int attributeCount = this->attributes->length();
|
||||
|
||||
//printf("uniformCount: %i\n\n", attributeCount);
|
||||
|
||||
for ( int i = 0; i < attributeCount; ++i )
|
||||
{
|
||||
struct attribute * currentAttribute = this->attributes->get( i );
|
||||
|
||||
char * currentAttributeName = currentAttribute->name;
|
||||
|
||||
//printf("attributeName->name: %s %s\n\n", currentAttributeName, attributeName );
|
||||
|
||||
if( currentAttributeName == attributeName ) {
|
||||
|
||||
return currentAttribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void setUniform( char * name, void * value ) {
|
||||
|
||||
int uniformCount = this->uniforms->length();
|
||||
|
||||
// printf("uniformCount: %i\n\n", uniformCount);
|
||||
|
||||
for (int i = 0; i < uniformCount; ++i)
|
||||
{
|
||||
uniform * currentUniform = this->uniforms->get( i );
|
||||
|
||||
char * uniformName = (char *)currentUniform->name;
|
||||
|
||||
// printf("currentUniform->name: %s\n\n", uniformName);
|
||||
|
||||
if( uniformName == name ) {
|
||||
|
||||
//printf("\n\n Update this uniform %s\n\n", name);
|
||||
|
||||
switch( currentUniform->type ) {
|
||||
|
||||
|
||||
case GL_FLOAT_VEC2:
|
||||
|
||||
vector2 * vector2Value = ( vector2 * ) value;
|
||||
|
||||
//printf("\n\n this is an float vec2 %f %f \n\n", vector2Value->x, vector2Value->y );
|
||||
|
||||
glUniform2f( currentUniform->location, vector2Value->x, vector2Value->y );
|
||||
|
||||
break;
|
||||
|
||||
case GL_FLOAT_VEC3:
|
||||
|
||||
vector3 * vector3Value = ( vector3 * ) value;
|
||||
|
||||
//printf("\n\n this is an float vec3 %f %f %f \n\n", vector3Value->x, vector3Value->y, vector3Value->z);
|
||||
|
||||
glUniform3f( currentUniform->location, vector3Value->x, vector3Value->y, vector3Value->z );
|
||||
|
||||
break;
|
||||
|
||||
case GL_SAMPLER_2D:
|
||||
|
||||
this->updateSampler2D( currentUniform, value );
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case GL_SAMPLER_2D_ARRAY:
|
||||
|
||||
this->updateSampler2D( currentUniform, value );
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
updateSampler2D( 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++;
|
||||
|
||||
sampler->bind();
|
||||
|
||||
//printf("sampler->index: %i \n", sampler->index);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
glActiveTexture( GL_TEXTURE0 + sampler->index );
|
||||
|
||||
glBindTexture( sampler->target, sampler->glTexture );
|
||||
|
||||
//glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,GL_UNSIGNED_BYTE, texture );
|
||||
|
||||
glUniform1i( currentUniform->location, sampler->index );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user