实例渲染 OpenGL

Posted

技术标签:

【中文标题】实例渲染 OpenGL【英文标题】:Instance rendering OpenGL 【发布时间】:2014-09-18 11:20:22 【问题描述】:

我很难弄清楚为什么对 glDrawArraysInstanced 的调用会绘制正确数量的实例但对象的大小错误。 这是我的代码(省略了类声明)

#include <QtOpenGL/QGLWidget>
#include <QtOpenGL/QGLBuffer>
#include <QtOpenGL/QGLShaderProgram>
#include <iostream>

const float OpenGLViewer::_quad[] = 
    -1.0f, 0.0f, 0.0f,
    -0.9f, 0.0f, 0.0f,
    -1.0f,  1.0f, 0.0f,
    -0.9f,  1.0f, 0.0f
;

const float OpenGLViewer::_offset[] = 
    0.0, 0.2, 0.7, 0.4
;

...

void OpenGLViewer::initializeGL()

    QGLFormat glFormat = QGLWidget::format();
    if(!glFormat.sampleBuffers())
        std::cout << "Could not enable sample buffers.";

    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    glViewport(0, 0, this->width(), this->height());

    if(!prepareShaderProgram(":/vertex.glsl", ":/fragment.glsl"))
        return;

    if(!_shaderProgram.bind())
    
        std::cout << "Could not bind shader program to the context.";
        return;
    

    glGenVertexArrays(1, &_vertexArraysObject);
    glBindVertexArray(_vertexArraysObject);         // BIND

    glGenBuffers(1, &_quadBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _quadBuffer);     // BIND
    glBufferData(GL_ARRAY_BUFFER, sizeof(_quad), _quad, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    //glVertexAttribDivisorARB(0, 0);

    glGenBuffers(1, &_offsetBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _offsetBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(_offset), _offset, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribDivisorARB(1, 1);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


void OpenGLViewer::paintGL()

    // Clear the buffer with the current clearing color
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    // Draw stuff
    glBindVertexArray(_vertexArraysObject);

    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 4);


...

我要做的是使用顶点着色器中的偏移值绘制相同的矩形,但在不同的位置。重要的是,我使用的是 glVertexAttribDivisorARB(1, 1)(注意 ARB 后缀),因为在 Qt+OSX Mavericks 中我找不到函数 glVertexAttribDivisor。有什么想法吗?

生成的图像看起来像

编辑

忘记包含着色器

// VERTEX shader
#version 330

layout(location = 0) in vec4 vertexPosition;
layout(location = 1) in float offset;

void main()

    gl_Position = vec4(vertexPosition.x + offset, vertexPosition.y + offset, vertexPosition.zw);


//FRAGMENT shader
#version 330

layout(location = 0, index = 0) out vec4 fragmentColor;

void main(void)

    fragmentColor = vec4(1.0, 0.0, 0.0, 1.0);

【问题讨论】:

着色器的外观如何? @ratchetfreak 刚刚编辑了我的帖子 【参考方案1】:
gl_Position = vec4(vertexPosition.x + offset, vertexPosition.y + offset, vertexPosition.zw);

将偏移量添加到 y 将其向上移动(屏幕外)

您不应该将偏移量添加到 y 或将其减去:

gl_Position = vec4(vertexPosition.x + offset, vertexPosition.y - offset, vertexPosition.zw);

【讨论】:

以上是关于实例渲染 OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

OPenGLopengl 64位 配置

Modern OpenGLOpenGL简介

OpenGLOpenGL中的Buffer的巧妙使用

OpenGL入门之认识OpenGL和创建Window

Android OpenGL ES开发入门

如何通过实例渲染将每个实例数据(例如定位)传递给 OpenGL 3.2 中的着色器?