Для моего алгоритма мне нужно иметь доступ к буферу глубины.У меня нет проблем, когда я делаю это с использованием glReadPixels, но чтение окна 800x600 очень медленно (от 300 кадров в секунду до 20 кадров в секунду)
Я много читаю об этом и думаю, что дамп буфера глубины вТекстура будет быстрее.Я знаю, как создать текстуру, но как мне получить глубину?
Создание FBO и создание текстуры оттуда может быть еще быстрее, на данный момент я использую FBO (но все еще в комбинациис glReadPixels).
Так что это самый быстрый способ сделать это?
(я, вероятно, не могу использовать GLSL, потому что я ничего не знаю об этом, и у меня не так много времени, чтобы учиться, сроки!)
edit: БудетПБО работаешь?Как описано здесь: http://www.songho.ca/opengl/gl_pbo.html это может идти намного быстрее, но я не могу все время менять буферы, как в примере.
Edit2: Как мне поступить с помещением данных глубины в PBO?На данный момент я делаю:
glGenBuffersARB(1, &pboId);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 800*600*sizeof(GLfloat),0, GL_STREAM_READ_ARB);
и прямо перед чтением пикселей я снова вызываю glBindbuffer.В результате я вообще ничего не читаю.Если я отключаю PBO, все это работает.
Окончательное редактирование: думаю, я решил это, мне пришлось использовать:
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
glReadPixels( 0, 0,Engine::fWidth, Engine::fHeight, GL_DEPTH_COMPONENT,GL_FLOAT, BUFFER_OFFSET(0));
GLuint *pixels = (GLuint*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
Это дало мне увеличение на 20 FPS.Это не так уж много, но это что-то.
Итак, я использовал 2 PBO, но все еще сталкиваюсь с проблемой: мой код выполняется только один раз.
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]);
std::cout << "Reading pixels" << std::endl;
glReadPixels( 0, 0,Engine::fWidth, Engine::fHeight, GL_DEPTH_COMPONENT,GL_FLOAT, BUFFER_OFFSET(0));
std::cout << "Getting pixels" << std::endl;
// glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, 800*600*sizeof(GLfloat), 0, GL_STREAM_DRAW_ARB);
GLfloat *pixels = (GLfloat*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
int count = 0;
for(int i = 0; i != 800*600; ++i){
std::cout << pixels[i] << std::endl;
}
Последняя строка выполняется один раз, но только один раз, после этого он продолжает вызывать метод (что нормально), но останавливается на вызове пикселей.
Я, видимо, забыл загрузить glUnMapBuffers, что-то вроде решило это, хотя моя частота кадров снова стала медленнее ..
Я решил попробовать FBO, но наткнулся напроблема: Инициализация FBO:
glGenFramebuffersEXT(1, framebuffers);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffers[0]);
std::cout << "framebuffer generated, id: " << framebuffers[0] << std::endl;
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glGenRenderbuffersEXT(1,renderbuffers);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffers[0]);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, 800, 600);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbuffers[0]);
bool status = checkFramebufferStatus();
if(!status)
std::cout << "Could not initialise FBO" << std::endl;
else
std::cout << "FBO ready!" << std::endl;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
Мой цикл рисования:
GLenum errCode;const GLubyte * errString;
if ((errCode = glGetError()) != GL_NO_ERROR) {
errString = gluErrorString(errCode);
fprintf (stderr, "OpenGL Error: %s\n", errString);
}
++frameCount;
// ----------- First pass to fill the depth buffer -------------------
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffers[0]);
std::cout << "FBO bound" << std::endl;
//Enable depth testing
glEnable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDepthMask( GL_TRUE );
//Disable stencil test, we don't need that for this pass
glClearStencil(0);
glEnable(GL_STENCIL_TEST);
//Disable drawing to the color buffer
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
//We clear all buffers and reset the modelview matrix
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();
//We set our viewpoint
gluLookAt(eyePoint[0],eyePoint[1], eyePoint[2], 0.0,0.0,0.0,0.0,1.0,0.0);
//std::cout << angle << std::endl;
std::cout << "Writing to FBO depth" << std::endl;
//Draw the VBO's, this does not draw anything to the screen, we are just filling the depth buffer
glDrawElements(GL_TRIANGLES, 120, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
После этого я вызываю функцию, которая вызывает glReadPixels () Функция даже не вызывается.Цикл перезапускается при вызове функции.
Видимо, я решил и это: мне пришлось использовать
glReadPixels( 0, 0,Engine::fWidth, Engine::fHeight, GL_DEPTH_COMPONENT,GL_UNSIGNED_SHORT, pixels);
с GL_UNSIGNED_SHORT вместо GL_FLOAT (или любым другим форматом в этом отношении)