0

I need your help for a simple thing to do (I hope) when passing Matrices4x4 by VBO and get it in the shader (version 4.3). I don't know how to do exactly. I have my version of code like it :

void GLWidget::initializeGL()
{
// Set up the rendering context, load shaders and other resources, etc.:
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();

/** creation first triangle **/
m_data.push_back(-.1f);     m_data.push_back(0.f);     m_data.push_back(0.f);
m_data.push_back(0.f);      m_data.push_back(.1f);     m_data.push_back(0.f);
m_data.push_back(.1f);      m_data.push_back(0.f);     m_data.push_back(0.f);
m_label = 0;

m_matrixObjects.push_back(QMatrix4x4());

//initialize a triangle and a matrix model in  VBOs
m_VAO[0].create();
m_VBO[COORDINATES].create();
m_VBO[MATRICES].create();
m_VAO[0].bind();
m_VBO[COORDINATES].bind();
m_VBO[COORDINATES].allocate(sizeof(float) * NBCOORDSTRIANGLE * MAXNBELEMENTSVBO);
m_VBO[COORDINATES].write(0, m_data.data(), sizeof(float) * m_data.size());
f->glVertexAttribPointer(COORDINATES, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
f->glEnableVertexAttribArray(COORDINATES);
m_VBO[COORDINATES].release();
m_VBO[MATRICES].bind();
m_VBO[MATRICES].allocate(sizeof(float) * SIZEMATRIX4X4 * MAXNBELEMENTSVBO);
m_VBO[MATRICES].write(0, m_matrixObjects[0].data(), sizeof(float) * SIZEMATRIX4X4);

f->glVertexAttribPointer(MATRICES, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)0);
f->glEnableVertexAttribArray(MATRICES);

f->glVertexAttribPointer(MATRICES+1, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(4 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+1);

f->glVertexAttribPointer(MATRICES+2, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(8 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+2);

f->glVertexAttribPointer(MATRICES+3, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(12 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+3);

m_VBO[MATRICES].release();
m_VAO[0].release();

m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "vertexShader.glsl");
m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "fragmentShader.glsl");
m_program.link();

m_matrixPUniform = m_program.uniformLocation("P");
m_matrixVUniform = m_program.uniformLocation("V");
m_matrixMUniform = m_program.uniformLocation("M");
m_matrixMObjectsUniform[0] = m_program.uniformLocation("M0");

m_near = .1f;
float far = 100.f, angleInDegrees = 60.f, ratio = 4.f/3.f;
m_eyeOrigin = QVector3D(0.f,0.f,-4.f);
QVector3D target(0.f,0.f,0.f), up(0.f,1.f,0.f);

MVP.V.lookAt(
    m_eyeOrigin,
    target,
    up
);
MVP.P.perspective(
    angleInDegrees, 
    ratio, 
    m_near, 
    far
);

m_nbDrawingPoints = 3; }

And my vertex shader :

#version 430 core
layout (location = 0) in vec3 position;
layout (location = 4) in mat4 M0


uniform mat4 P, V, M;

void main() {
    gl_Position = P * V * M * vec4(position.x, position.y, position.z, 1.0);    }

These codes don't work, do you have an idea where I'm wrong.

Thanks a lot for you answers!

chtimy
  • 11
  • 4
  • In the code you've shown `M0` is *not* a uniform but you try to access it as if it was. – G.M. Feb 13 '18 at 11:19
  • Thank you for your answer, I remove the lines for the UBO : - m_matrixMObjectsUniform[0] = m_program.uniformLocation("M0"); But it doesn't change anything. Is it my vertexAttributePointer or my shader which are wrong? – chtimy Feb 14 '18 at 08:48

1 Answers1

0

Ok, I get it.

My error is simple. I put just one matrix in the second VBO, then the vertex shader apply the matrix for the first vertex, after there is no defined matrix for the other vertices.

I need to duplicate 3 times the same matrix for each point of my mesh.

The code below:

m_VAO[0].create();
m_VBO[COORDINATES].create();
m_VBO[MATRICES].create();
m_VAO[0].bind();
m_VBO[COORDINATES].bind();
m_VBO[COORDINATES].allocate(sizeof(float) * NBCOORDSTRIANGLE * MAXNBELEMENTSVBO);
m_VBO[COORDINATES].write(0, m_data.data(), sizeof(float) * m_data.size());
f->glVertexAttribPointer(COORDINATES, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
f->glEnableVertexAttribArray(COORDINATES);
m_VBO[COORDINATES].release();
m_VBO[MATRICES].bind();
m_VBO[MATRICES].allocate(sizeof(float) * SIZEMATRIX4X4 * MAXNBELEMENTSVBO * 3);
//first vertex
m_VBO[MATRICES].write(0, m_matrixObjects[0].data(), sizeof(float) * SIZEMATRIX4X4);
//second vertex
m_VBO[MATRICES].write(sizeof(float) * SIZEMATRIX4X4, m_matrixObjects[0].data(), sizeof(float) * SIZEMATRIX4X4);
//third vertex
m_VBO[MATRICES].write(sizeof(float) * SIZEMATRIX4X4 * 2, m_matrixObjects[0].data(), sizeof(float) * SIZEMATRIX4X4);

f->glVertexAttribPointer(MATRICES, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)0);
f->glEnableVertexAttribArray(MATRICES);

f->glVertexAttribPointer(MATRICES+1, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(4 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+1);

f->glVertexAttribPointer(MATRICES+2, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(8 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+2);

f->glVertexAttribPointer(MATRICES+3, 4, GL_FLOAT, GL_FALSE, SIZEMATRIX4X4 * sizeof(float), (GLvoid*)(12 * sizeof(float)));
f->glEnableVertexAttribArray(MATRICES+3);

m_VBO[MATRICES].release();
m_VAO[0].release();

There is no way to keep one matrix for 3 vertices for example in my case?

chtimy
  • 11
  • 4