* Я старался изо всех сил реализовать реалистичные текстурные функции, используя фреймворчество OpenGL вместе с библиотекой LWJGL с Java. Тем не менее, результатом, который я всегда получаю, является 100% ** черная ** текстура. *OpenGL - Почему моя fbo/текстура остается черной?
Я просто прошу совета относительно проблемы. Я не создаю никаких конкретных фигур. Я связываю свой сгенерированный фреймбуфер и вызываю glClearColor(1, 0, 0, 1);
, а затем glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
, а затем отвязываю фреймбуфер. Но когда я пытаюсь отобразить текстуру, связанную с фреймбуфером, текстура показывает только черную, где она на самом деле должна быть красной, верно?
Кроме того, glCheckFramebufferStatus()
возвращает GL_FRAMEBUFFER_COMPLETE
, поэтому я полагаю, что ошибка лежит внутри части рендеринга, а не фазы инициализации. Но я покажу код инициализации.
Код инициализации:
public RenderableTexture initialize(int width, int height, int internalFormat, int[] attachments, boolean useDepthBuffer) {
if(!GLContext.getCapabilities().GL_EXT_framebuffer_object) {
System.err.println("FrameBuffers not supported on your graphics card!");
}
this.width = width;
this.height = height;
hasDepthBuffer = useDepthBuffer;
fbo = glGenFramebuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
id = glGenTextures();
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
if(useDepthBuffer) {
rbo = glGenRenderbuffers();
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
}
glFramebufferTexture2D(GL_FRAMEBUFFER, attachments[0], GL_TEXTURE_2D, id, 0);
int[] drawBuffers = new int[attachments.length];
for(int i = 0; i < attachments.length; i++)
if(attachments[i] == GL_DEPTH_ATTACHMENT)
drawBuffers[i] = GL_NONE;
else
drawBuffers[i] = attachments[i];
glDrawBuffers(Util.toIntBuffer(drawBuffers));
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
System.err.println("Warning! Incomplete Framebuffer");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return this;
}
internalFormat
имеет значение GL_RGBA8
и width
и height
имеют значение 512 и 512. attachments[]
содержит только 1 значение и это GL_COLOR_ATTACHMENT0
. useDepthBuffer
: true
.
Вышеупомянутый код вызывается только один раз.
Это код рендеринга:
public RenderManager draw() {
glClearColor(bg.x, bg.y, bg.z, bg.w);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture.bindAsRenderTarget(true);
texture.releaseRenderTarget();
quad.draw();
return this;
}
Я установил четкий цвет на черный (0, 0, 0, 1)
, а затем очистить экран. Затем я звоню texture.bindAsRenderTarget(true);
. Объект texture
- это тот, который содержит метод initialize
сверху, поэтому некоторые переменные распределяются между этим методом и bindAsRenderTarget()
.
Этот метод выглядит следующим образом:
public RenderableTexture bindAsRenderTarget(boolean clear) {
glViewport(0, 0, width, height);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glClearColor(1, 0, 0, 1f);
if(clear)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return this;
}
Как вы можете видеть, что я настроить окно просмотра с размером текстуры/фреймбуфером. Затем я связываю фреймбуфер и устанавливаю прозрачный цвет на красный. Затем, поскольку я прошел true
в коде рендеринга, он (как я считаю) очищает связанный с ним фреймбуфер до красного.
texture.releaseRenderTarget();
регулирует видовой экран, чтобы соответствовать дисплей, а затем вызывает glBindFramebuffer(GL_FRAMEBUFFER, 0);
Последняя строка кода quad.draw();
просто связывает textureID текстуры, связанной с фреймбуфером, а затем рисует простой четырехугольник с ним.
Это почти все есть.
Я могу заверить, что я правильно представляю квадрат, так как я могу привязать текстуры, загруженные из файлов PNG, к нему, и текстура успешно показана.
Итак, чтобы сделать вещи ясно, главный вопрос, довольно много:
Почему на земле текстура черный после того, как ясно, как это должно быть красным? Где и что я делаю неправильно?
EDIT: У меня такое чувство, что это может иметь отношение к ограничению разных объектов. Должен ли renderbuffer привязываться в точке рендеринга к его фреймбуу? Не так ли? Это имеет значение? Как насчет текстуры? в какие моменты они должны быть?
Когда вы закончите рисовать текстуру фреймбуфера и освободили фреймбуфер, перед тем, как вы хотите снова отобразить обратно буфер, попробуйте glDrawBuffer (GL_BACK) ; – Robinson
Спасибо за ответ Робинсон :) К сожалению, это не решило ответ. Проблема, вероятно, заключается в рендеринге fbo, а не в обратном буфере. – SporreKing
Ну, это неясно из вашего кода, если проблема на самом деле является рендерингом _into_ текстуры/FBO, или если она передает текстуру в стандартный фреймбуфер. – derhass