按照本教程https://doc.qt.io/qt-5/qtgui-openglwindow-example.html的操作,我可以创建一个旋转的三角形。
我想通过渲染4面金字塔来扩展示例。 (为清楚起见,我仅绘制了两个三角形)
我希望看到金字塔的外部三角形,但是当渲染所有侧面时,红色的永远不会显示,而黄色的永远都会显示。
我尝试了glEnable(GL_DEPTH_TEST),glDepthMask(GL_TRUE),4维矢量(?)的各种不同排列以及更改三角形的方向,但是找不到解决方案。
#include "openglwindow.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QScreen>
#include <QtCore/qmath.h>
class TriangleWindow : public OpenGLWindow
{
public:
TriangleWindow();
void initialize() override;
void render() override;
private:
GLuint m_posAttr;
GLuint m_colAttr;
GLuint m_matrixUniform;
QOpenGLShaderProgram *m_program;
int m_frame;
};
TriangleWindow::TriangleWindow()
: m_program(0)
, m_frame(0)
{
}
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
QSurfaceFormat format;
format.setSamples(16);
TriangleWindow window;
window.setFormat(format);
window.resize(640, 480);
window.show();
window.setAnimating(true);
return app.exec();
}
static const char *vertexShaderSource =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
void TriangleWindow::initialize()
{
m_program = new QOpenGLShaderProgram(this);
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->link();
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
}
void TriangleWindow::render()
{
const qreal retinaScale = devicePixelRatio();
glViewport(0, 0, width() * retinaScale, height() * retinaScale);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -1);
matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0);
m_program->setUniformValue(m_matrixUniform, matrix);
GLfloat vertices[] = {
0.0f, 0.577f, 0.0f, 1.0f,
0.5f, -0.289f, 0.289f, 1.0f,
-0.5f, -0.289f, 0.289f, 1.0f,
0.0f, 0.577f, 0.0f, 1.0f,
0.0f, -0.289f, -0.577f, 1.0f,
0.5f, -0.289f, 0.289f, 1.0f,
0.0f, 0.577f, 0.0f, 1.0f,
-0.5f, -0.289f, 0.289f, 1.0f,
0.0f, -0.289f, -0.577f, 1.0f,
-0.5f, -0.289f, 0.289f, 1.0f,
0.5f, -0.289f, 0.289f, 1.0f,
0.0f, -0.289f, -0.577f, 1.0f
};
GLfloat colors[] = {
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
glVertexAttribPointer(m_posAttr, 4, GL_FLOAT, GL_FALSE, 0, vertices);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 6); // to only draw two faces
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
m_program->release();
++m_frame;
}
frame from rendering 2 triangles frame from rendering all triangles