У меня странная проблема в OpenGL.Сначала немного предыстории: в моей программе я реализую эффект цветения, используя две текстуры с полным набором мипмапов.Каждый уровень mipmap привязан к FBO, так что я могу выполнить гауссово размытие из двух частей на каждом уровне, прежде чем объединять их, чтобы создать цветение.Эта часть работает хорошо, и я мог визуализировать красивый вращающийся светящийся объект.
Проблема началась, когда я попытался выполнить тестирование глубины.
Я добавил карту глубины в FBO, соответствующиеуровень 0 каждой текстуры.Затем я включил GL_DEPTH_TEST.Как только я включил GL_DEPTH_TEST, экран начал мерцать, и объект больше не вращался.
Я сократил код до его самого простого, и, кажется, это происходит, только когда я рендеринг в FBO с GL_DEPTH_TESTвключен.Проблема не произойдет, если я выполню рендеринг в кадровый буфер по умолчанию с включенным GL_DEPTH_TEST.Проблема не произойдет, если я выполню рендеринг в FBO с отключенным GL_DEPTH_TEST.
Приведенный ниже код является упрощенной версией моего кода, просто чтобы проиллюстрировать последовательность вызовов OpenGL, которая, кажется, воссоздает эту проблему.Пожалуйста
Правильно ли я добавляю буфер глубины в FBO?
// Create a set of framebuffers, one for each mipmap level of a texture.
void FrameBuffer::Initialise(int xs, int ys)
{
xSizeTexture = PowerOfTwoAboveOrEqualTo(xs);
ySizeTexture = PowerOfTwoAboveOrEqualTo(ys);
numLevels = Log2(max(xSizeTexture, ySizeTexture));
// Generate one FB for each texture level
glGenFramebuffers(numLevels, frameBufferID);
glGenTextures(1, &textureID);
glBindTexture( GL_TEXTURE_2D, textureID);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, xSizeTexture, ySizeTexture, 0, GL_RGB, GL_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numLevels-1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glGenerateMipmap(GL_TEXTURE_2D);
// Bind each texture level to one FB
for (int i = 0; i < numLevels; i++)
{
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[i]);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, i);
}
attachment = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &attachment);
// Add a depth buffer to the top FB
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[0]);
glGenRenderbuffers(1, &depthrenderbufferID);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, xSizeTexture, ySizeTexture);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbufferID);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "Failed to create frame buffer" << endl;
else
cout << "Created buffer OK" << endl;
// Also initialise vertex array VAO
// ...
}
void FrameBuffer::Use()
{
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[0]);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, 0);
}
void FrameBuffer::CopyToMain()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, textureID);
glViewport(0, 0, 1024, 1024);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
}
void MainClass::Initialise()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
framebuffer.Initialise(1024, 1024);
}
void MainClass::Render()
{
if (!initialised)
{
Initialise();
initialised = true;
}
framebuffer.Use();
glViewport(0, 0, 1024, 1024);
glUseProgram(0);
glEnable(GL_DEPTH_TEST); // Causes problems
//glDisable(GL_DEPTH_TEST); // Works fine
t += 0.05;
glLoadIdentity();
glRotatef(sin(t) * 10, 0, 0, 1);
glLineWidth(2.0);
glBegin(GL_LINE_LOOP);
glColor3f(1.0, 0.1, 0.1); glVertex3f(-0.5, -0.5, 0.0);
glColor3f(0.1, 1.0, 0.1); glVertex3f( 0.5, -0.5, 0.0);
glColor3f(0.1, 0.1, 1.0); glVertex3f( 0.5, 0.5, 0.0);
glColor3f(0.1, 0.1, 0.1); glVertex3f(-0.5, 0.5, 0.0);
glEnd();
framebuffer.CopyToMain();
}
Я не получаю ошибок, о которых сообщает glGetError ().
Пожалуйста, простите за слегка псевдокодприрода кода C ++.Он просто предназначен для иллюстрации последовательности вызовов OpenGL.