Ich initialisiere Framebuffer. Dann rende ich in einem Zyklus die Szene in eine Textur, behandle ihren Shader und folge dem Bildschirm. Auf meinem PC ist alles in Ordnung. (Radeon HD 7870.) Auf einem anderen PC (GeForce FX 5200) gibt die Funktion glCheckFramebufferStatusEXT den Fehler "8cdd" zurück und rendert einen schwarzen Bildschirm mit einer Framerate von 0-1 fps.Rendern Textur über das Framebuffer-Objekt
Quellcode:
#include "main.hpp"
GLuint fbo, fbo_texture, rbo_depth;
GLuint vbo_fbo_vertices;
GLuint program_postproc, attribute_v_coord_postproc, uniform_fbo_texture;
GLuint vs, fs;
Shader shader;
int main(void)
{
init();
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &fbo_texture);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_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);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture, 0);
GLenum status;
if ((status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) != GL_FRAMEBUFFER_COMPLETE_EXT) {
fprintf(stderr, "glCheckFramebufferStatus: error %p", status);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GLfloat fbo_vertices[] = { -1, -1, 1, -1,-1, 1, 1, 1 };
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);
shader.load("shaders/post_processing.vert", "shaders/post_processing.frag");
attribute_v_coord_postproc = glGetAttribLocation(shader.program(), "v_coord");
if (attribute_v_coord_postproc == -1) {
fprintf(stderr, "Could not bind attribute %s\n", "v_coord");
return 0;
}
uniform_fbo_texture = glGetUniformLocation(shader.program(), "fbo_texture");
if (uniform_fbo_texture == -1) {
fprintf(stderr, "Could not bind uniform %s\n", "fbo_texture");
return 0;
}
while (!glfwWindowShouldClose(m_window))
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClear(GL_COLOR_BUFFER_BIT);
shader.use();
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glUniform1i(uniform_fbo_texture, /*GL_TEXTURE*/0);
glEnableVertexAttribArray(attribute_v_coord_postproc);
glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
glVertexAttribPointer(attribute_v_coord_postproc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(attribute_v_coord_postproc);
glfwSwapBuffers(m_window);
glfwPollEvents();
}
glDeleteRenderbuffersEXT(1, &rbo_depth);
glDeleteTextures(1, &fbo_texture);
glDeleteFramebuffersEXT(1, &fbo);
glDeleteBuffers(1, &vbo_fbo_vertices);
glDeleteProgram(shader.program());
glfwDestroyWindow(m_window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
void callbackError(int error, const char* description)
{
fputs(description, stderr);
}
void callbackKey(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void callbackFramebufferSize(GLFWwindow* window, int width, int height)
{
m_width = width; m_height = height;
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
void init()
{
glfwSetErrorCallback(callbackError);
if (!glfwInit()) exit(EXIT_FAILURE);
m_width = 800; m_height = 600;
m_window = glfwCreateWindow(m_width, m_height, "Framebuffer Test", NULL, NULL);
if (!m_window) { glfwTerminate(); exit(EXIT_FAILURE); }
glfwMakeContextCurrent(m_window);
glfwSwapInterval(0);
glfwSetKeyCallback(m_window, callbackKey);
glfwSetFramebufferSizeCallback(m_window, callbackFramebufferSize);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) std::cout << "GLEW Init Error" << std::endl;
glClearColor(0.2, 0.3, 0.4, 1.0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
Ergebnis:
Verwenden Sie OpenGL oder OpenGL ES? –
GeForce FX 5200 ist ziemlich alt, vielleicht wird Ihre 'FBO Konfiguration' nicht unterstützt. Tut mir leid, ich weiß nicht genug, um dir mehr zu helfen. – fordcars