Я пытаюсь преобразовать куб в QGLWidgetput внутри QSplitter. Я бы хотел, чтобы у него было соотношение 1: 1, чтобы оно было кубом и сохраняло это соотношение независимо от размеров окна. Однако я не смог заставить это работать. Что бы я ни делал, куб тянется вместе с окном.
У меня есть две дополнительные проблемы с тем, как работает код.
matrix.setToIdentity()
сбрасывает все, кроме проекции и перевода, которые происходят в концеinitializeGL()
, поэтому, когда я вызываю ее вresizeGL()
, проекция объединяется с предыдущей, даже если я перед этим установил матрицу в идентичность.Аргумент
aspect ratio
изmatrix.perspective()
, кажется, ничего не делает. Я пробовал несколько значений безрезультатно.Почему-то проекция орфографическая, а не перспективная.
Матрица по-прежнему является тождеством после
perspective()
, но только если я вызываюsetToIdentity()
иperspective()
вresizeGL
в этом порядке.Матричные операции в
initializeGL()
иresizeGL()
обрабатываются по-разному. Если я не вызовуtranslate()
иperspective()
вinitializeGL()
, куб не появится, даже если я сделаю это позже вresizeGL()
.
Кто-нибудь может мне это объяснить? Я думал, что класс QMatrix4x4
предназначен для хранения матриц для 3D-преобразований, поэтому мне не нужно реализовывать их самостоятельно.
Я просмотрел некоторые учебные пособия, но либо они используют какие-то матрицы аналогичным образом, либо они, похоже, используют устаревшие функции OpenGL. Пробовал приводить ширину и высоту к числам с плавающей запятой и использовать отдельные матрицы для преобразований.
Как заставить работать соотношение 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();
}
m_matrixUniform
перед вызовомm_matrixUniform = m_program->uniformLocation("matrix")
? - person genpfault   schedule 09.03.2013m_matrixUniform
в своем конструкторе, это, вероятно, не будет проблемой, поскольку первое место юниформ обычно равно нулю. - person genpfault   schedule 09.03.2013resizeGL()
, когда вы меняете порядок вызововtranslate()
иperspective()
? - person genpfault   schedule 09.03.2013translate()
вообще не может быть, иначе куб исчезнет. Иperspective()
должен иметь свой первый аргументangle
равным нулю. Я думал, что установка матрицы на идентичность сбросила все. - person Brokensoul .   schedule 09.03.2013