实例渲染 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的主要内容,如果未能解决你的问题,请参考以下文章