【问题标题】:Composing images using framebuffer objects使用帧缓冲区对象组合图像
【发布时间】:2014-07-09 20:38:24
【问题描述】:

我正在尝试在 OpenGL ES 2.0 中制作一些“图像”,但遇到了一些问题。我想要的是构建一个帧缓冲区对象,比如说 400x300 像素之一,然后使用正交投影渲染一些图形。

我认为创建帧缓冲区对象的方式是正确的。这是保存它的顶点数组:

GLfloat vertexData[] = {
// X      Y     Z     U     V
  -0.5f,  0.5f, 0.0f, 0.0f, 0.0f, // Top-left
   0.5f,  0.5f, 0.0f, 1.0f, 0.0f, // Top-right
   0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // Bottom-right
  -0.5f, -0.5f, 0.0f, 0.0f, 1.0f  // Bottom-left
};

稍后,我创建了相同大小(即 400x300)的纹理和渲染缓冲区。另外,我真的不知道之前的vertexData是否正确,不应该使用400x300而不是1x1吗?

另外,当我构建投影和视图矩阵时,问题就来了:

_projection = glm::ortho(0.0f, 400.0f, 300.0f, 0.0f, 0.0f, 1.0f);
_view = glm::lookAt(glm::vec3(0,0,1), glm::vec3(0,0,0), glm::vec3(0,1,0));

当我使用它们时,我在屏幕上看不到任何东西。但是,当我将它们设置为单位矩阵时,我会看到我绘制的图形到帧缓冲区对象,但当然我想将像素坐标映射到 opengl 坐标以便轻松绘制图像。

这是我用来绘制绘制到帧缓冲区对象的元素的代码:

// Bind the framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, _framebufferObject);

// Set viewport to size of texture map and erase previous image
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, 400, 300);

// Render every GraphicComponents to the FBO
for(GraphicComponent* gc : _graphicComponents) {
  gc->render();
}

// Unbind the FBO so rendering will return to the backbuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, _screenWidth, _screenHeight);

GraphicComponent 类的 render 方法只是绘制元素。例如,对于 RectangleComponent:

void RectangleComponent::render() {
    _shader.useProgram();

    glVertexAttribPointer(_colorHandler, 3, GL_FLOAT, GL_FALSE, 0, _vertexData);
    glEnableVertexAttribArray(_colorHandler);

    glUniformMatrix4fv(_mvpHandler, 1, GL_FALSE, glm::value_ptr(_projectionMatrix * _viewMatrix * _modelMatrix));

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, _indices);

}

当我在帧缓冲区对象之外绘制它时,效果非常好。

TL;DR 我想将一些元素(如矩形、文本等)绘制到帧缓冲区对象,但我不知道在渲染元素时使用哪些尺寸(或顶点位置)到帧缓冲区对象。另外,我希望帧缓冲区对象中的元素以正交投影呈现,因此它们的 opengl 坐标映射到屏幕像素,左上角位于 (0,0)。

【问题讨论】:

    标签: c++ opengl-es


    【解决方案1】:

    好的,所以我做得对,但是我的环境有点奇怪(我使用的是投影仪,而不是屏幕),我必须处理它。

    我所做的唯一更改是使用单位矩阵作为视图矩阵,因为它不需要,并将顶点数据数组设置为:

    GLfloat vertexData[] = {
    // X        Y       Z     U     V
      -400.0f,  300.0f, 0.0f, 0.0f, 0.0f, // Top-left
       400.0f,  300.0f, 0.0f, 1.0f, 0.0f, // Top-right
       400.0f, -300.0f, 0.0f, 1.0f, 1.0f, // Bottom-right
      -400.0f, -300.0f, 0.0f, 0.0f, 1.0f  // Bottom-left
    };
    

    正交投影矩阵是对的。

    【讨论】:

      【解决方案2】:

      在绘制到 FBO 时,您很可能希望使用正射投影,这样您就可以使用“像素”坐标。

      从 FBO 绘制纹理作为全屏四边形使用单位投影矩阵和

      GLfloat vertexData[] = {
      // X      Y     Z     U     V
        -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // Bottom-right
        -1.0f,  1.0f, 0.0f, 0.0f, 1.0f, // Top-left
         1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // Bottom-right
         1.0f,  1.0f, 0.0f, 1.0f, 1.0f  // Top-left
      };
      

      然后绘制 glDrawArrays(GL_TRIANGLE_STRING, 0, 4);所以你不需要使用索引数组。

      【讨论】:

      • 这与我的问题完全无关,因为这不是我要问的。
      猜你喜欢
      • 1970-01-01
      • 2014-07-13
      • 2010-10-19
      • 2013-06-29
      • 2020-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多