Hi,
I am learning how to use Uniforms in OpenGL to provide data to my shaders. I have the following code (the forum decides to do some weird formatting in the code):
#include "sb6.h"
#include <vmath.h>
#include <math.h>
#include <stdlib.h>
using namespace sb6;
class my_application : public sb6::application
{
private:
GLuint buffers[2];
GLuint rendering_program;
GLuint vertex_array_object;
public:
void startup( void )
{
rendering_program = compile_shaders();
glGenVertexArrays(1, &vertex_array_object );
glBindVertexArray( vertex_array_object );
// Generate names for the two buffers
glGenBuffers( 2, buffers );
// The data used for vertex positions
static const float positions[] =
{
0.25, -0.25, 0.5, 1.0,
-0.25, -0.25, 0.5, 1.0,
0.25, 0.25, 0.5, 1.0
};
// The data used for vertex colors
static const float colors[] =
{
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
};
// Bind the first attribute and initialize it
glBindBuffer( GL_ARRAY_BUFFER, buffers[ 0 ] );
glBufferData( GL_ARRAY_BUFFER, sizeof( positions ), positions, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, NULL );
glEnableVertexAttribArray( 0 );
// Bind the second attribute and initialize it
glBindBuffer( GL_ARRAY_BUFFER, buffers[ 1 ] );
glBufferData( GL_ARRAY_BUFFER, sizeof( colors ), colors, GL_STATIC_DRAW );
glVertexAttribPointer( 1, 4, GL_FLOAT, GL_FALSE, 0, NULL );
glEnableVertexAttribArray( 1 );
// Get the indices of the uniform block
static const GLchar* uniformNames[ 4 ] =
{
"TransformBlock.scale",
"TransformBlock.translation",
"TransformBlock.rotation",
"TransformBlock.projection_matrix"
};
GLuint uniformIndices[ 4 ];
glGetUniformIndices( rendering_program, 4, uniformNames, uniformIndices );
// Find the locations of the uniform block members
GLint uniformOffsets[ 4 ];
GLint arrayStrides[ 4 ];
GLint matrixStrides[ 4 ];
glGetActiveUniformsiv( rendering_program, 4, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets );
glGetActiveUniformsiv( rendering_program, 4, uniformIndices, GL_UNIFORM_ARRAY_STRIDE, arrayStrides );
glGetActiveUniformsiv( rendering_program, 4, uniformIndices, GL_UNIFORM_MATRIX_STRIDE, matrixStrides );
// Allocate some memory for our buffer (don't forget to free it later)
unsigned char* buffer = ( unsigned char* ) malloc( 4096 );
memset( buffer, 0, sizeof( buffer ) );
// Store the scale in the buffer
*( ( float* )( buffer + uniformOffsets[ 0 ] ) ) = 3.0f;
// Store the translation in the buffer
( ( float* )( buffer + uniformOffsets[ 1 ] ) )[ 0 ] = 1.0f;
( ( float* )( buffer + uniformOffsets[ 1 ] ) )[ 1 ] = 2.0f;
( ( float* )( buffer + uniformOffsets[ 1 ] ) )[ 2 ] = 3.0f;
// Store the rotation in the buffer
const GLfloat rotations[] = { 30.0f, 40.0f, 60.0f };
unsigned int offset = uniformOffsets[ 2 ];
for( int n = 0; n < 3; n++ )
{
*( ( float* )( buffer + offset ) ) = rotations[ n ];
offset += arrayStrides[ 2 ];
}
// Store the matrix in the buffer
const GLfloat matrix[] =
{
1.0f, 2.0f, 3.0f, 4.0f,
9.0f, 8.0f, 7.0f, 6.0f,
2.0f, 4.0f, 6.0f, 8.0f,
1.0f, 3.0f, 5.0f, 7.0f
};
for( int i = 0; i < 4; i++ )
{
GLuint offset = uniformOffsets[ 3 ] + matrixStrides[ 3 ] * i;
for( int j = 0; j < 4; j++ )
{
*( ( float* )( buffer + offset ) ) = matrix[ i * 4 + j ];
offset += sizeof( GLfloat );
}
}
free( buffer );
}
void shutdown( void )
{
glDeleteVertexArrays(1, &vertex_array_object );
glDeleteProgram( rendering_program );
}
void render( double currentTime )
{
const GLfloat color[] = { 0.0f, 0.2f, 0.0f, 1.0f };
glClearBufferfv( GL_COLOR, 0, color );
// Use the program object we created earlier for rendering
glUseProgram( rendering_program );
glDrawArrays( GL_TRIANGLES, 0, 3 );
}
GLuint compile_shaders( void )
{
GLuint vertex_shader;
GLuint fragment_shader;
GLuint program;
// Source code for the vertex shader
static const GLchar* vertex_shader_source[] =
{
"#version 430 core
"
"
"
"layout ( location = 0 ) in vec4 position;
"
"layout ( location = 1 ) in vec4 color;
"
"
"
"layout(std140) uniform TransformBlock
"
"{
"
" float scale;
"
" vec3 translation;
"
" float rotation[ 3 ];
"
" mat4 projection_matrix;
"
"} transform;
"
"
"
"out vec4 vs_color;
"
"
"
"void main( void )
"
"{
"
" gl_Position = position;
"
" vs_color = color;
"
"}
"
};
// Source code for the fragment shader
static const GLchar* fragment_shader_source[] =
{
"#version 430 core
"
"
"
"in vec4 vs_color;
"
"
"
"out vec4 color;
"
"
"
"void main( void )
"
"{
"
" color = vs_color;
"
"}
"
};
// Create and compile the vertex shader
vertex_shader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertex_shader, 1, vertex_shader_source, NULL );
glCompileShader( vertex_shader );
// Create and compile the fragment shader
fragment_shader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragment_shader, 1, fragment_shader_source, NULL );
glCompileShader( fragment_shader );
// Create program, attach shaders to it, and link it
program = glCreateProgram();
glAttachShader( program, vertex_shader );
glAttachShader( program, fragment_shader );
glLinkProgram( program );
// Delete the shaders as the program has them now
glDeleteShader( vertex_shader );
glDeleteShader( fragment_shader );
return program;
}
};
DECLARE_MAIN( my_application );
For some reason “glGetUniformIndices” returns garbage to the “uniformIndices” array, and because of that I get a crash when i try to load a value for the “scale” into the buffer.
Any suggestions?
Thanks
Robin