2016-04-09 9 views
-1

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:

http://itmag.es/4KxQ5/

http://itmag.es/H5RD/

+0

Verwenden Sie OpenGL oder OpenGL ES? –

+0

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

Antwort

0

Der Rückgabewert 0x8cdd1 ist die Konstante gl_FRAMEBUFFER_UNSUPPORTED.
Vom documentation

GL_FRAMEBUFFER_UNSUPPORTED zurückgegeben, wenn die Kombination von internen Formaten der beigefügten Bilder eine Implementierung abhängiger Satz von Einschränkungen verstößt.

Um herauszufinden, wo das Problem liegt Sie ein paar Dinge tun können:

überprüfen Sie die Rückgabewerte

GLenum lastErr: 
... 
if ((lastErr = glGetError())!= GL_NO_ERROR) 
{ 
    fprintf(stderr, "<lastFunctionCalledHere>: error %s", gluErrorString(lastErr)); 
    return <returnCodeHere>; 
} 

Prüfen auf das Vorhandensein der GL_EXT_framebuffer_object Erweiterung.

Verwenden glGetIntegerv(GL_NUM_EXTENSIONS, ...) die die Anzahl der Erweiterungen bekommen, als glGetStringi​(GL_EXTENSIONS, i) verwendet mit i weniger als die genannten Zahl.

Überprüfen Sie die Implementierung Einschränkungen

Wenn keine der oben genannten, die Ursache gefunden, mit glGetXXX versuchen einige nützliche Wert abzurufen und mit GL_PROXY_TEXTURE_2D für die Textur Schöpfung zu testen.

Verwandte Themen