0
\$\begingroup\$

I try use uniform blocks in OpenGL, but doesn't work. First, see my vertex shader:

#version 400
uniform Buffer0
{
    mat4 worldMatrix;
    mat4 viewMatrix;
    mat4 projectionMatrix;
};

in vec3 POSITION;
in vec4 COLOR;
out vec4 color;

void main(void)
{
    gl_Position = worldMatrix * vec4(POSITION, 1.0f);
    gl_Position = viewMatrix * gl_Position;
    gl_Position = projectionMatrix * gl_Position;

    color = vec4(1.f, 0.f, 0.f, 1.f);
}

My fragment shader output color only.

Creating and drawing vertex buffer correctly.

If use

gl_Position = vec4(POSITION, 1.0f);

drawing works, but using matrices draw doesn't work.

C++ code:

// Create GL_UNIFORM_BUFFER matrices

struct Matrix4f
{
float m11,m12,m13,m14;
float m21,m22,m23,m24;
float m31,m32,m33,m34;
float m41,m42,m43,m44;
};
struct MatrixBuffer
{
Matrix4f world, view, proj;
};
//The values bellow are correct
Matrix4f world = 
{
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
};
Matrix4f view = 
{
    1, 0, 0 , 0,
    0, 1, 0 , 0,
    0, 0, 1 , 0,
    0, 0, 10, 1
};
Matrix4f projection =
{
    1.81066012f, 0         , 0           , 0,
    0         , 2.41421342f, 0           , 0,
    0         , 0         , 1.00010002f  , 1,
    0         , 0         , -0.100010000f, 0
};
MatrixBuffer data = { world, view, proj };

GLuint matrixbuffer;
glGenBuffers(1, &matrixbuffer);

if (glGetError())
// "No error here."

glBindBuffer(GL_UNIFORM_BUFFER, matrixbuffer);

if (glGetError())
// "No error here."

// GL_STATIC_DRAW for example, but I have tested many other flags
glBufferData(GL_UNIFORM_BUFFER , sizeof(MatrixBuffer), &data, GL_STATIC_DRAW);

if (glGetError())
// "No error here."

// Render function
// This code works
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double winWidth = glutGet(GLUT_WINDOW_WIDTH);
double winHeight = glutGet(GLUT_WINDOW_HEIGHT);
double ar = winWidth / winHeight;
glOrtho(-1 * ar, 1 * ar, -1, 1, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertProgId);
glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, fragProgId);
glBindProgramPipeline(pipeline);

// this code work without erros, but not draw triangle
GLuint location = glGetUniformBlockIndex(vertProgId, "Buffer0");

if (location == GL_INVALID_INDEX)
// "No error here."

// My question here.
glUniformBlockBinding(vertProgId, location, matrixbuffer);
// "No error here, but doesn't work, show a black screen."
// "If set directly matrices in vertex shader, triangles show corretly 

// this code works
drawVBO();
glutSwapBuffers();

I tried tranpose matrices, but doesn't work too.

Something is missing? Some error?

\$\endgroup\$
  • \$\begingroup\$ Well, let's take the obvious out of the way:Are you sure your GPU supports glsl 4? \$\endgroup\$ – Bálint Nov 11 '16 at 16:43
  • \$\begingroup\$ Yep. Specifications: Windows 10 x64, Intel Core 2 Quad, Geforce Gtx 650, 4GB RAM. Support OpenGL 4.3. \$\endgroup\$ – Bill Rock Nov 12 '16 at 14:52
0
\$\begingroup\$

You do not have to call glMatrixMode and related functions if you are supplying the shader the used matrices yourself.

The second problem is that glUniformBlockBinding does not want the matrix buffer name, but a binding point. You need to define the binding point yourself and assing the buffer to that binding point. Like this:

int bindingPoint = 2; // Just some value I came up with by throwing a dice.
glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, matrixbuffer);
glUniformBlockBinding(vertProgId, location, bindingPoint);

Check the OpenGL wiki entry for Uniform Buffer Objects and glBindBufferBase

Also as noted in the comments, this is a OpenGL4 feature, which is not necessarily supported by older GPUs. You seem to be mixing the old API with the very recent functions.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Bindpoint was my mistake, thx.. Doesn't work without aspect ratio functions, I tried. Works without functions glMatrixMode. About old and recent mixing, I need separate diferent types shaders for compatibility in my api. Do you have a tip to use old api for this? \$\endgroup\$ – Bill Rock Nov 12 '16 at 16:00
  • \$\begingroup\$ I remove deprecated functions, thnx. \$\endgroup\$ – Bill Rock Nov 12 '16 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.