2016-04-09 6 views
-1

フレームバッファを初期化します。次に、サイクルでシーンをテクスチャにレンダリングし、シェーダを処理して画面を推論します。私のPC上ではすべてがOKです。 (Radeon HD 7870)。別のPC(GeForce FX 5200)では、関数glCheckFramebufferStatusEXTがエラー "8cdd"を返し、0-1fpsのフレームレートで黒い画面を表示します。フレームバッファオブジェクトを介してテクスチャにレンダリングする

ソースコード:

#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); 
} 

結果:

http://itmag.es/4KxQ5/

http://itmag.es/H5RD/

+0

OpenGLまたはOpenGL ESを使用していますか? –

+0

GeForce FX 5200はかなり古く、あなたの 'FBO configuration'はサポートされていないかもしれません。申し訳ありませんが、私はあなたをもっと助けるのに十分ではありません。 – fordcars

答えて

0

戻り値0x8cdd1が一定gl_FRAMEBUFFER_UNSUPPORTEDです。添付画像の内部フォーマットの組合せが制約の実装に依存セットに違反している場合documentation

GL_FRAMEBUFFER_UNSUPPORTEDから
が返されます。

問題はあなたが物事のカップルを行うことができますどこにあるかを調べるに:

はリターンをチェックしGL_EXT_framebuffer_object拡張の存在のため

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

チェック値。

使用glGetIntegerv(GL_NUM_EXTENSIONS, ...)言った数よりも少ないglGetStringi​(GL_EXTENSIONS, i)を使用するよりも、拡張子の数を取得します。

チェックの実装上の制約

上記のいずれも原因が見つからない場合は、テクスチャの作成をテストするためにいくつかの有用な値とGL_PROXY_TEXTURE_2Dとを取得するためにglGetXXXてみてください。

関連する問題