I'm trying to render a cube into a QGLWidgetput inside a QSplitter. I'd like it to have a 1:1 ratio so it is a cube and keeps that ratio regardless of window dimensions. I haven't been able to get this to work, though. No matter what I do, the cube stretches with the window.
I have two additional problems with how the code works.
matrix.setToIdentity()
resets everything except projection and translation which happen at the end ofinitializeGL()
, and so when I invoke it inresizeGL()
, the projection combines with the previous one, even if I set the matrix to identity before that.The argument
aspect ratio
ofmatrix.perspective()
seems to be doing nothing. I've tried several values with no effect.For some reason, the projection is orthographic, not perspective.
The matrix is still an identity after
perspective()
, but only if I callsetToIdentity()
andperspective()
inresizeGL
in that order.Matrix operations in
initializeGL()
andresizeGL()
get different treatment. If I don't calltranslate()
andperspective()
ininitializeGL()
, the cube will not appear even if I do it later inresizeGL()
.
Can anyone explain this to me? I thought that QMatrix4x4
class was here to hold the matrices to 3D transformations so I don't have to implement them myself.
I've looked at some tutorials, but either they use some kind of matrices in a similar way or they seem to use deprecated OpenGL functions. Tried casting width and height to floats and using separate matrices for transformations.
How do I make the 1:1 ratio work?
A relevant piece of my code:
void ModelView::initializeGL()
{
m_program = new QGLShaderProgram(this);
m_program->addShaderFromSourceCode(QGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QGLShader::Fragment, fragmentShaderSource);
m_program->link();
GLuint shader_id = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(shader_id, 1, vertexShaderSource, NULL);
glCompileShader(shader_id);
ShaderIds[2] = shader_id;
shader_id = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(shader_id, 1, fragmentShaderSource, NULL);
glCompileShader(shader_id);
ShaderIds[1] = shader_id;
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);
glLinkProgram(ShaderIds[0]);*/
matrix.setToIdentity(); //--------------------------------------
float aspect = (((float)width())/((float)height()));
matrix.perspective(60, aspect, 0.1, 100.0);
matrix.translate(0, 0, -2);
}
void ModelView::paintGL()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(.5f, .5f, .5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width(), height());
m_program->bind();
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
m_program->setUniformValue(m_matrixUniform, matrix); //-----------------
glGenBuffers(1, &BufferId);
glGenBuffers(1, &IndexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, BufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId);
glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, VertexSize, 0);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid *)RgbOffset);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
m_program->release();
}
void ModelView::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
matrix.setToIdentity(); //------------------------------------
matrix.translate(0, 0, -2);
matrix.perspective(60, ((float)w)/((float)h), 0.1, 100.0);
updateGL();
}