gpt4 book ai didi

c++ - 具有固定纵横比的透视图(1 :1) in OpenGL and Qt5 (QGLWidget)

转载 作者:行者123 更新时间:2023-11-28 07:43:42 25 4
gpt4 key购买 nike

我正在尝试将立方体渲染到 QSplitter 内的 QGLWidgetput 中。我希望它具有 1:1 的比例,因此它是一个立方体,并且无论窗口尺寸如何都保持该比例。不过,我还没能让它发挥作用。无论我做什么,立方体都会随着窗口拉伸(stretch)。

关于代码的工作方式,我还有两个问题。

  • matrix.setToIdentity() 重置除了在 initializeGL() 末尾发生的投影和平移之外的所有内容,所以当我在 中调用它时>resizeGL(),投影与之前的合并,即使我之前将矩阵设置为identity。

  • matrix.perspective() 的参数纵横比 似乎什么也没做。我尝试了几个值都没有效果。

  • 出于某种原因,投影是正交的,而不是透视的。

  • 矩阵在 perspective() 之后仍然是恒等式,但前提是我调用了 setToIdentity()perspective()按此顺序在 resizeGL 中。

  • initializeGL()resizeGL() 中的矩阵运算得到不同的处理。如果我在initializeGL()中不调用translate()perspective(),即使后面调用了立方体也不会出现在 resizeGL() 中。

谁能给我解释一下?我认为 QMatrix4x4 类在这里用于保存矩阵到 3D 转换,因此我不必自己实现它们。

我看过一些教程,但它们要么以类似的方式使用某种矩阵,要么似乎使用了已弃用的 OpenGL 函数。尝试将宽度和高度转换为 float 并使用单独的矩阵进行转换。

如何使 1:1 的比例发挥作用?

我的一段相关代码:

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();
}

最佳答案

终于找到问题了

首先,矩阵运算不应该在 initializeGL() 中。不完全确定为什么。正确的(想想也是合理的)位置在 resizeGL() 中,因为它在第一帧渲染的某个地方被调用。

其次,矩阵乘法有其定义的顺序,如透视 > 平移 > 旋转。否则会搞砸。

所以 resizeGL() 中正确的(或者至少是工作的)代码是这样的:

glViewport(startX, startY, width, height);    //resize the viewport
matrix.setToIdentity(); //reset the uniform value (matrix)
perspectiveMatrix.setToIdentity(); //reset the projection matrix
//set new projection (aspect ratio)
perspectiveMatrix.perspective(angle, (float)width/(float)height, nearPlane, farPlane);

matrix *= perspectiveMatrix; //apply transformations
matrix *= translationMatrix;
matrix *= rotationMatrix;

updateGL(); //re-render

关于c++ - 具有固定纵横比的透视图(1 :1) in OpenGL and Qt5 (QGLWidget),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15303969/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com