Рендеринг в текстуру через объект framebuffer

Я инициализирую фреймбуфер. Затем в цикле я рендерил сцену в текстуру, обрабатывал ее шейдер и выводил экран. На моем ПК все ок. (Radeon HD 7870.) На другом ПК (GeForce FX 5200) функция glCheckFramebufferStatusEXT возвращает ошибку «8cdd» и отображает черный экран с частотой кадров 0-1 кадров в секунду.

Исходный код:

#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/

-1

Решение

Возвращаемое значение 0x8cdd1 постоянная gl_FRAMEBUFFER_UNSUPPORTED,
От документация

GL_FRAMEBUFFER_UNSUPPORTED возвращается, если комбинация внутренних форматов прикрепленных изображений нарушает зависящий от реализации набор ограничений.

Чтобы выяснить, в чем проблема, вы можете сделать несколько вещей:

Проверьте возвращаемые значения

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

Проверьте наличие GL_EXT_framebuffer_object расширение.

использование glGetIntegerv(GL_NUM_EXTENSIONS, ...) получить количество расширений, чем использовать glGetStringi​(GL_EXTENSIONS, i) с я меньше указанного числа.

Проверьте ограничения реализации

Если ни один из вышеперечисленных не нашел причину, попробуйте с glGetXXX получить некоторое полезное значение и с GL_PROXY_TEXTURE_2D для тестирования создания текстур.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector