使用实例化绘图时渲染到纹理

时间:2015-04-23 18:45:10

标签: c++ opengl framebuffer render-to-texture

我有几个被绘制的对象,有些使用"常规"方法和一些使用glDrawArraysInstanced,一切都很好。

我试图通过使用Frame Buffers渲染到纹理来添加一些后期处理,但是当我这样做时,如果我正在绘制实例化对象,我得到了这个结果:

(你可以看到实际项目背后的混乱)。

如果我评论实例化对象的draw方法,一切都很好。

是否可以将带有渲染的实例化绘图用于纹理?

一些代码:

实例化对象

void LifeMeter::draw(mat4 wvp)
{
    // Set the program to be used in subsequent lines:
    glUseProgram(program);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(glGetUniformLocation(program, "texSampler"), /*GL_TEXTURE*/0);

    glBindVertexArray(_vao);
    glUniformMatrix4fv (glGetUniformLocation(program, "wvp") , 1, GL_FALSE, value_ptr(wvp));
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vec4)*amountOfLives, positions);
    glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, amountOfLives);

    // Unbind the Vertex Array object
    glBindVertexArray(0);
    // Cleanup, not strictly necessary
    glUseProgram(0);
}

后处理缓冲区

void PPBuffer::init(int screen_width, int screen_height)
{
  // buffer
  // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.

  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);


  /* Texture  */

  // The texture we're going to render to
  glGenTextures(1, &fbo_texture);

  // "Bind" the newly created texture : all future texture functions will modify this texture
  glBindTexture(GL_TEXTURE_2D, fbo_texture);
  glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,screen_width, screen_height, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  glBindTexture(GL_TEXTURE_2D, 0);

  // depth buffer
  glGenRenderbuffers(1, &rbo_depth);
  glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
  glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screen_width, screen_height );

  glBindRenderbuffer(GL_RENDERBUFFER, 0);

  /* Framebuffer to link everything together */
  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fbo_texture, 0); //use more of these for MRT
  // glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, fbo_texture1, 0);

  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);

  // Set the list of draw buffers.
  GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};

  glDrawBuffers(1,DrawBuffers); 

  // for MRT:  glDrawBuffers(2,{GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1}); 

  GLenum status;
  if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
    fprintf(stderr, "glCheckFramebufferStatus: error %d", status);
    exit(0);
  }

  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  // vertices 
  GLfloat fbo_vertices[] = {
    -1, -1,
    1, -1,
    -1,  1,
    1,  1,
  };

  // Create and bind the object's Vertex Array Object:
  glGenVertexArrays(1, &_vao);
  glBindVertexArray(_vao);

  glGenBuffers(1, &vbo_fbo_vertices);
  glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
  glBufferData(GL_ARRAY_BUFFER, sizeof(fbo_vertices), fbo_vertices, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);  

  glBindVertexArray(0);
  // shader
  programManager::sharedInstance()
    .createProgram("pp",
           SHADERS_DIR "postproc.v.glsl",
           SHADERS_DIR "postproc.f.glsl");
  program_postproc = programManager::sharedInstance().programWithID("pp");

  attribute_v_coord_postproc = glGetAttribLocation(program_postproc, "v_coord");
  uniform_fbo_texture = glGetUniformLocation(program_postproc, "fbo_texture");
}

void PPBuffer::setup() {
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}

void PPBuffer::render() {
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  glClearColor(0.3, 0.0, 0.0, 1.0);

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glUseProgram(program_postproc);

  glActiveTexture(GL_TEXTURE0);

  glBindTexture(GL_TEXTURE_2D, fbo_texture);
  glUniform1i(uniform_fbo_texture, /*GL_TEXTURE*/0);

  glBindVertexArray(_vao);
  glEnableVertexAttribArray(attribute_v_coord_postproc);
  glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
  glVertexAttribPointer(
            attribute_v_coord_postproc,  // attribute
            2,                  // number of elements per vertex, here (x,y)
            GL_FLOAT,           // the type of each element
            GL_FALSE,           // take our values as-is
            0,                  // no extra data between each position
            0                   // offset of first element
            );
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  glDisableVertexAttribArray(attribute_v_coord_postproc);
  glBindBuffer(GL_ARRAY_BUFFER,0);
  glBindVertexArray(0);
  glUseProgram(0);
}

显示功能

void display(void)
{

    _ppbuffer.setup();
    // Clear the screen buffer
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

    // tell the model to draw itself...
    shuttle->draw(); // Regular object
    lifeMeter->draw(Projection ); // Instanced object


    _ppbuffer.render();

    // Swap those buffers so someone will actually see the results... //
    glutSwapBuffers();
}

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,所以如果有人遇到这个问题,问题就是blending功能。

删除行

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

解决了这个问题。因为我可以没有他们,我很满意。

相关问题