c++ - OpenGL 翻译不生效

标签 c++ qt opengl

这些问题可能非常基础,所以请多多包涵。

我已经构建了一个非常小的 Qt 程序来处理 OpenGL 并尝试了解渲染方法并获得了一个彩色三角形(扩展本教程 http://qt-project.org/wiki/How_to_use_OpenGL_Core_Profile_with_Qt)。我现在的问题是,我尝试对三角形应用的任何变换都不起作用。最重要的是,将参数更改为 glOrtho 似乎对显示没有任何影响,而且我不知道 glViewport 的参数应该如何工作:使它们变小似乎会使 3D 世界的渲染区域变大.

代码:

这是我的顶点/索引数组(vec3 位置,vec3 颜色)

static GLfloat tri[] = { -0.5f, -0.5f, 0.0f,  0.0f, 0.0f, 1.0f,
                        0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,
                        0.0f,  0.5f, 0.0f,  1.0f, 0.0f, 0.0f };

static GLuint tri_ind[] = { 0, 1, 2 };

static int SIZEOF_TRI = 2 * 3 * 3 * sizeof(GLfloat);
static int SIZEOF_TRI_IND = 3 * sizeof(GLuint);
static int NUM_TRI_VERTS = 3;

我的 OpenGL 小部件使用 Qt 的缓冲区对象作为顶点和索引缓冲区:

class GLWidget : public QGLWidget
{
    Q_OBJECT
public:
    GLWidget( const QGLFormat& format, QWidget* parent = 0 );

protected:
    virtual void initializeGL();
    virtual void resizeGL( int w, int h );
    virtual void paintGL();

    virtual void keyPressEvent( QKeyEvent* e );

private:
    bool prepareShaderProgram( const QString& vertexShaderPath,
                               const QString& fragmentShaderPath );

    QGLShaderProgram m_shader;
    QGLBuffer m_vertexBuffer;
    QGLBuffer m_indexBuffer;
};

构造函数初始化缓冲区:

GLWidget::GLWidget( const QGLFormat& format, QWidget* parent )
    : QGLWidget( format, parent ),
      m_vertexBuffer( QGLBuffer::VertexBuffer ),
      m_indexBuffer( QGLBuffer::IndexBuffer )
{
}

initialiseGL 初始化其余部分:

void GLWidget::initializeGL()
{
    QGLFormat glFormat = QGLWidget::format();
    if ( !glFormat.sampleBuffers() )
        qWarning() << "Could not enable sample buffers";

    // Set the clear color to black
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    // Prepare a complete shader program...
    QString vert = QCoreApplication::applicationDirPath() + "/simple.vert";
    QString frag = QCoreApplication::applicationDirPath() + "/simple.frag";
    if ( !prepareShaderProgram( vert, frag ) )
        return;

    // Bind the shader program so that we can associate variables from
    // our application to the shaders
    if ( !m_shader.bind() )
    {
        qWarning() << "Could not bind shader program to context";
        return;
    }

    // We need us some vertex data. Start simple with a triangle ;-)
    GLfloat* points = tri;
    m_vertexBuffer.create();
    m_vertexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
    if ( !m_vertexBuffer.bind() )
    {
        qWarning() << "Could not bind vertex buffer to the context";
        return;
    }
    m_vertexBuffer.allocate( points, SIZEOF_TRI );

    // Indices
    GLuint* indices = tri_ind;
    m_indexBuffer.create();
    m_indexBuffer.setUsagePattern( QGLBuffer::StaticDraw );
    if ( !m_indexBuffer.bind() )
    {
        qWarning() << "Could not bind vertex buffer to the context";
        return;
    }
    m_indexBuffer.allocate( indices, SIZEOF_TRI_IND );


    // Enable the "vertex" attribute to bind it to our currently bound
    // vertex buffer.
    m_shader.setAttributeBuffer( "vertex", GL_FLOAT, 0, 3, 6 * sizeof(GLfloat) );
    m_shader.enableAttributeArray( "vertex" );
    m_shader.setAttributeBuffer( "color", GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat) );
    m_shader.enableAttributeArray( "color" );
}

然后 paintGL 进行平移并绘制顶点:

void GLWidget::paintGL()
{
    // Clear the buffer with the current clearing color
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    // Draw stuff
    glLoadIdentity();
    glTranslatef(10.0, 10.0, 0.0);
    glDrawArrays( GL_TRIANGLES, 0, NUM_TRI_VERTS );
}

三角形看起来和我添加翻译之前完全一样。

此外,在 resizeGL(调整小部件大小时)中,将参数更改为 glOrtho 对显示没有影响。 +-5 和 +-10 之间没有区别。如果我将 glViewport 的宽度和高度分别设置为 100,然后分别设置为 200,则当值为 200 时三角形看起来比值为 100 时更大(在左下角)。我本以为视口(viewport)尺寸更大这意味着里面的物体看起来更小,但也许我遗漏了什么。

void GLWidget::resizeGL( int w, int h )
{
    // Set the viewport to window dimensions
    glViewport( 0, 0, w, qMax( h, 1 ) );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-10.0, 10.0, -10.0, 10.0, -5.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

谁能给我一些正确方向的指示?

谢谢。

编辑:顶点着色器:

#version 330

in vec3 vertex;
in vec3 color;
out vec3 Color;

void main( void )
{
    Color = color;
    gl_Position = vec4(vertex, 1.0);
}

片段着色器:

#version 330
 
layout(location = 0, index = 0) out vec4 fragColor;
in vec3 Color;
 
void main( void )
{
    fragColor = vec4(Color, 1.0);
}

最佳答案

您的着色器被编写为在 OpenGL-3.3 或更高版本的核心配置文件中工作。您正在使用在核心配置文件中不起作用的已弃用的固定功能管道方法(glMatrixMode、glLoadIdentity、glTranslate 等)。使用真正的矩阵数学库(如 GLM、Eigen 或 linmath.h)计算矩阵,然后将它们传递给着色器制服。

关于c++ - OpenGL 翻译不生效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18287363/

相关文章:

c++ - 如何使用 QTextStream 而不是 QDataStream 从 QTableView 进行加载保存?

c++ - 当程序在两者之间进入休眠状态时,OpenCV 函数 cv::remap() 的执行时间更长

c++ - 我可以定义一个(类型化的)常量,它肯定不会占用可执行文件中的空间吗?

c++ - SQLite如何限制记录数

c++ - 在 C++ Qt 中删除原始指针的替代方法

c++ - 使用 `gluUnProject` 在 opengl 中进行鼠标拾取

c++ - N-Queen问题:无法弄清楚为什么我的解决方案不起作用

c++ - 这种在 Qt 中渲染旋转椭圆的尝试有什么问题?

java - 应用地球纹理贴图球体

c++ - 如何在 OpenGL 中使用 vector 和结构上传顶点数据?