My mistake Alfonse, the error is “invalid value” actually.
I just made a basic sample code out of it to show the problem and I guess it’s a bug then:
//**********************************
// OpenGL Uniform Buffer Shared
// 23/08/2010 - 23/08/2010
//**********************************
// Christophe Riccio
// [email]g.truc.creation@gmail.com[/email]
//**********************************
// G-Truc Creation
// www.g-truc.net
//**********************************
#include <glf/glf.hpp>
namespace
{
std::string const SAMPLE_NAME = "OpenGL Uniform Buffer Shared";
std::string const VERTEX_SHADER_SOURCE(glf::DATA_DIRECTORY + "400/uniform-buffer.vert");
std::string const FRAGMENT_SHADER_SOURCE(glf::DATA_DIRECTORY + "400/uniform-buffer.frag");
int const SAMPLE_SIZE_WIDTH = 640;
int const SAMPLE_SIZE_HEIGHT = 480;
int const SAMPLE_MAJOR_VERSION = 4;
int const SAMPLE_MINOR_VERSION = 0;
glf::window Window(glm::ivec2(SAMPLE_SIZE_WIDTH, SAMPLE_SIZE_HEIGHT));
GLsizei const VertexCount = 4;
GLsizeiptr const PositionSize = VertexCount * sizeof(glm::vec2);
glm::vec2 const PositionData[VertexCount] =
{
glm::vec2(-1.0f,-1.0f),
glm::vec2( 1.0f,-1.0f),
glm::vec2( 1.0f, 1.0f),
glm::vec2(-1.0f, 1.0f)
};
GLsizei const ElementCount = 6;
GLsizeiptr const ElementSize = ElementCount * sizeof(GLushort);
GLushort const ElementData[ElementCount] =
{
0, 1, 2,
2, 3, 0
};
GLuint const Instances = 2;
GLuint ProgramName = 0;
GLuint ElementBufferName = 0;
GLuint ArrayBufferName = 0;
GLuint VertexArrayName = 0;
GLuint TransformBufferName = 0;
GLuint MaterialBufferName = 0;
GLint UniformTransform[Instances] = {0, 0};
GLint UniformMaterial = 0;
}//namespace
bool initProgram()
{
bool Validated = true;
// Create program
if(Validated)
{
GLuint VertexShaderName = glf::createShader(GL_VERTEX_SHADER, VERTEX_SHADER_SOURCE);
GLuint FragmentShaderName = glf::createShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE);
ProgramName = glCreateProgram();
glAttachShader(ProgramName, VertexShaderName);
glAttachShader(ProgramName, FragmentShaderName);
glDeleteShader(VertexShaderName);
glDeleteShader(FragmentShaderName);
glLinkProgram(ProgramName);
Validated = glf::checkProgram(ProgramName);
}
// Get variables locations
if(Validated)
{
UniformMaterial = glGetUniformBlockIndex(ProgramName, "material");
UniformTransform[0] = glGetUniformBlockIndex(ProgramName, "transform[0]");
UniformTransform[1] = glGetUniformBlockIndex(ProgramName, "transform[1]");
}
return Validated && glf::checkError("initProgram");
}
bool initVertexArray()
{
// Build a vertex array object
glGenVertexArrays(1, &VertexArrayName);
glBindVertexArray(VertexArrayName);
glBindBuffer(GL_ARRAY_BUFFER, ArrayBufferName);
glVertexAttribPointer(glf::semantic::attr::POSITION, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(glf::semantic::attr::POSITION);
glBindVertexArray(0);
return glf::checkError("initVertexArray");
}
bool initArrayBuffer()
{
// Generate a buffer object
glGenBuffers(1, &ElementBufferName);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBufferName);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementSize, ElementData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenBuffers(1, &ArrayBufferName);
glBindBuffer(GL_ARRAY_BUFFER, ArrayBufferName);
glBufferData(GL_ARRAY_BUFFER, PositionSize, PositionData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return glf::checkError("initArrayBuffer");
}
bool initUniformBuffer()
{
GLint UniformBlockSize = 0;
glGenBuffers(1, &TransformBufferName);
glBindBuffer(GL_UNIFORM_BUFFER, TransformBufferName);
glGetActiveUniformBlockiv(
ProgramName,
UniformTransform[0],
GL_UNIFORM_BLOCK_DATA_SIZE,
&UniformBlockSize);
glBufferData(GL_UNIFORM_BUFFER, UniformBlockSize * Instances, 0, GL_DYNAMIC_DRAW);
// Attach the buffer to UBO binding point glf::semantic::uniform::TRANSFORMn
glBindBufferRange(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, TransformBufferName, 0 * sizeof(glm::mat4), sizeof(glm::mat4));
glBindBufferRange(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM1, TransformBufferName, 1 * sizeof(glm::mat4), sizeof(glm::mat4));
{
glm::vec4 Diffuse(1.0f, 0.5f, 0.0f, 1.0f);
glGetActiveUniformBlockiv(
ProgramName,
UniformMaterial,
GL_UNIFORM_BLOCK_DATA_SIZE,
&UniformBlockSize);
glGenBuffers(1, &MaterialBufferName);
glBindBuffer(GL_UNIFORM_BUFFER, MaterialBufferName);
glBufferData(GL_UNIFORM_BUFFER, UniformBlockSize, &Diffuse[0], GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Attach the buffer to UBO binding point glf::semantic::uniform::MATERIAL
glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::MATERIAL, MaterialBufferName);
}
return glf::checkError("initUniformBuffer");
}
bool begin()
{
GLint MajorVersion = 0;
GLint MinorVersion = 0;
glGetIntegerv(GL_MAJOR_VERSION, &MajorVersion);
glGetIntegerv(GL_MINOR_VERSION, &MinorVersion);
bool Validated = glf::version(MajorVersion, MinorVersion) >= glf::version(SAMPLE_MAJOR_VERSION, SAMPLE_MINOR_VERSION);
if(Validated)
Validated = initProgram();
if(Validated)
Validated = initArrayBuffer();
if(Validated)
Validated = initVertexArray();
if(Validated)
Validated = initUniformBuffer();
return Validated && glf::checkError("begin");
}
bool end()
{
glDeleteVertexArrays(1, &VertexArrayName);
glDeleteBuffers(1, &ArrayBufferName);
glDeleteBuffers(1, &ElementBufferName);
glDeleteBuffers(1, &TransformBufferName);
glDeleteBuffers(1, &MaterialBufferName);
glDeleteProgram(ProgramName);
return glf::checkError("end");
}
void display()
{
glBindBuffer(GL_UNIFORM_BUFFER, TransformBufferName);
glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) * Instances, NULL, GL_DYNAMIC_DRAW);
{
// Compute the MVP (Model View Projection matrix)
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MVP), &MVP[0][0]);
}
{
// Compute the MVP (Model View Projection matrix)
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x + 90.f, glm::vec3(0.f, 1.f, 0.f));
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 MVP = Projection * View * Model;
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MVP), sizeof(MVP), &MVP[0][0]);
}
glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Set the display viewport
glViewport(0, 0, Window.Size.x, Window.Size.y);
// Clear color buffer with black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Bind program
glUseProgram(ProgramName);
glUniformBlockBinding(ProgramName, UniformTransform[0], glf::semantic::uniform::TRANSFORM0);
glUniformBlockBinding(ProgramName, UniformTransform[1], glf::semantic::uniform::TRANSFORM1);
glUniformBlockBinding(ProgramName, UniformMaterial, glf::semantic::uniform::MATERIAL);
// Bind vertex array & draw
glBindVertexArray(VertexArrayName);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementBufferName);
glDrawElementsInstancedBaseVertex(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, NULL, Instances, 0);
glf::checkError("display");
glf::swapBuffers();
}
int main(int argc, char* argv[])
{
if(glf::run(
argc, argv,
glm::ivec2(::SAMPLE_SIZE_WIDTH, ::SAMPLE_SIZE_HEIGHT),
::SAMPLE_MAJOR_VERSION,
::SAMPLE_MINOR_VERSION))
return 0;
return 1;
}