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\$
2
  • \$\begingroup\$ Well, let's take the obvious out of the way:Are you sure your GPU supports glsl 4? \$\endgroup\$
    – Bálint
    Nov 11, 2016 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, 2016 at 14:52

1 Answer 1

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.

\$\endgroup\$
2
  • \$\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, 2016 at 16:00
  • \$\begingroup\$ I remove deprecated functions, thnx. \$\endgroup\$
    – Bill Rock
    Nov 12, 2016 at 21:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .