我尝试使用SpriteBatch和FrameBuffer渲染三张图片。
这些是我正在做的步骤。
以下是我对此问题了解的一些事实
这是它应该是什么样子的样子
以下是我用帧缓冲区查看的内容。
以下是我使用我的帧缓冲区和第一次纹理绘制两次的方式。仍然缺少其他两个纹理。定位不是问题。
这是我的FrameBuffer的代码:
// Stencil is broken currently broken, in my example. I'm not using any stencil buffers.
public FrameBuffer(int width, int height, boolean hasDepth, boolean hasStencil) {
this.width = width;
this.height = height;
frameBufferID = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
if (hasDepth && hasStencil) {
int depthAndStencilBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthAndStencilBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_DEPTH24_STENCIL8, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_STENCIL_ATTACHMENT, GL30.GL_RENDERBUFFER, depthAndStencilBufferID);
}
else if (hasDepth) {
int depthBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_DEPTH_COMPONENT32F, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depthBufferID);
}
else if (hasStencil) {
int stencilBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, stencilBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_STENCIL_INDEX16, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_STENCIL_ATTACHMENT, GL30.GL_RENDERBUFFER, stencilBufferID);
}
colorTexture = new Texture(width, height);
colorTexture.bind();
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colorTexture.getTextureID(), 0);
int result = GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
//error handling
RenderUtil.unbindFrameBuffer();
}
private Texture colorTexture;
private int width, height;
private int frameBufferID, depthBufferID, stencilBufferID;
public void begin () {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
GL11.glViewport(0, 0, width, height);
}
public void end () {
GL11.glViewport(0, 0, RenderingEngine.getWidth(), RenderingEngine.getHeight());
RenderUtil.unbindFrameBuffer();
RenderUtil.unbindTextures();
}
public Texture getColorTexture () {
return colorTexture;
}
public int getWidth () {
return width;
}
public int getHeight () {
return height;
}
如果有任何用途,我可以创建一个纹理:
private void loadTexture (ByteBuffer buffer, int textureID, int width, int height) {
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, width, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
}
切换纹理时,我的SpriteBatch似乎有问题。以下是切换的工作原理。 我提醒你,使用我的SpriteBatch渲染到屏幕上给出了我想要的结果。但渲染到FrameBuffer并不起作用。
`
public void flush () {
flushes++;
buffer.flip();
MESH.setVertices(buffer);
if (lastTexture != null) {
lastTexture.bind();
}
MESH.draw();
buffer.clear();
}
/** Begins the SpriteBatch. */
public void begin () {
if (rendering) {
new IllegalStateException("You have to SpriteBatch.end() before calling begin again!").printStackTrace();
}
flushes = 0;
rendering = true;
shader.bind();
shader.setUniformMat4f("projection", camera.getCombined());
shader.setUniformVec4("color", color);
}
/** Ends the SpriteBatch, also flushes it. */
public void end () {
if (!rendering) {
new IllegalStateException("You've to SpriteBatch.begin before ending the spritebatch").printStackTrace();
}
rendering = false;
flush();
RenderUtil.unbindShaders();
RenderUtil.unbindTextures();
}
/** Switches the textures and flushes the old one.
* @param t */
private void switchTextures (Texture t) {
if (lastTexture != null) {
flush();
}
lastTexture = t;
}
` 打算创建一个小例子。应该很快。
编辑: 问题不在于我的FrameBuffer。是我的SpriteBatch。
答案 0 :(得分:3)
您需要在FBO绑定时清除缓冲区,否则您只清除与窗口关联的颜色/模板/深度缓冲区。这不是您想要的行为,因为此场景中的深度测试使用您的FBO深度而不是窗口(默认帧缓冲区)。
public void begin ()
是最合理的地方:public void begin () {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
GL11.glViewport(0, 0, width, height);
}