diff --git a/include/renderer_gl/renderer_gl.hpp b/include/renderer_gl/renderer_gl.hpp index 6f55fdce..072f0d11 100644 --- a/include/renderer_gl/renderer_gl.hpp +++ b/include/renderer_gl/renderer_gl.hpp @@ -11,9 +11,6 @@ struct Vertex { }; class Renderer { - // OpenGL renderer state - OpenGL::Framebuffer fbo; - OpenGL::Texture fboTexture; OpenGL::Program triangleProgram; OpenGL::Program displayProgram; diff --git a/include/renderer_gl/surfaces.hpp b/include/renderer_gl/surfaces.hpp index e88acf1d..93ccd839 100644 --- a/include/renderer_gl/surfaces.hpp +++ b/include/renderer_gl/surfaces.hpp @@ -39,12 +39,39 @@ struct ColourBuffer { } void allocate() { - printf("Make this colour buffer allocate itself\n"); + // Create texture for the FBO, setting up filters and the like + // Reading back the current texture is slow, but allocate calls should be and far between. + // If this becomes a bottleneck, we can fix it semi-easily + auto prevTexture = OpenGL::getTex2D(); + texture.create(size.x(), size.y(), GL_RGBA8); + texture.bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, prevTexture); + + //Helpers::panic("Creating FBO: %d, %d\n", size.x(), size.y()); + + fbo.createWithDrawTexture(texture); + fbo.bind(OpenGL::DrawAndReadFramebuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + Helpers::panic("Incomplete framebuffer"); + //glBindRenderbuffer(GL_RENDERBUFFER, 0); + + // TODO: This should not clear the framebuffer contents. It should load them from VRAM. + GLint oldViewport[4]; + glGetIntegerv(GL_VIEWPORT, oldViewport); + OpenGL::setViewport(size.x(), size.y()); + OpenGL::setClearColor(0.0, 0.0, 0.0, 1.0); + OpenGL::clearColor(); + OpenGL::setViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); } void free() { valid = false; - printf("Make this colour buffer free itself\n"); + + if (texture.exists() || fbo.exists()) + Helpers::panic("Make this buffer free itself"); } bool matches(ColourBuffer& other) { diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp index 8d493620..48c66ad4 100644 --- a/src/core/renderer_gl/renderer_gl.cpp +++ b/src/core/renderer_gl/renderer_gl.cpp @@ -118,30 +118,6 @@ void Renderer::reset() { } void Renderer::initGraphicsContext() { - // Set up texture for top screen - fboTexture.create(400, 240, GL_RGBA8); - fboTexture.bind(); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); - - fbo.createWithDrawTexture(fboTexture); - fbo.bind(OpenGL::DrawAndReadFramebuffer); - - GLuint rbo; - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 400, 240); // use a single renderbuffer object for both a depth AND stencil buffer. - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - Helpers::panic("Incomplete framebuffer"); - //glBindRenderbuffer(GL_RENDERBUFFER, 0); - - OpenGL::setViewport(400, 240); - OpenGL::setClearColor(0.0, 0.0, 0.0, 1.0); - OpenGL::clearColor(); - OpenGL::Shader vert(vertexShader, OpenGL::Vertex); OpenGL::Shader frag(fragmentShader, OpenGL::Fragment); triangleProgram.create({ vert, frag }); @@ -174,15 +150,12 @@ void Renderer::initGraphicsContext() { void Renderer::getGraphicsContext() { OpenGL::disableScissor(); OpenGL::setViewport(400, 240); - fbo.bind(OpenGL::DrawAndReadFramebuffer); vbo.bind(); vao.bind(); triangleProgram.use(); } -OpenGL::Framebuffer poop; - void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 count) { // Adjust alpha test if necessary const u32 alphaControl = regs[PICAInternalRegs::AlphaTestConfig]; @@ -191,7 +164,8 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c glUniform1ui(alphaControlLoc, alphaControl); } - poop = getColourFBO(); + OpenGL::Framebuffer poop = getColourFBO(); + poop.bind(OpenGL::DrawAndReadFramebuffer); const u32 depthControl = regs[PICAInternalRegs::DepthAndColorMask]; bool depthEnable = depthControl & 1; @@ -239,18 +213,21 @@ constexpr u32 bottomScreenBuffer = 0x1f05dc00; void Renderer::display() { OpenGL::disableDepth(); OpenGL::disableScissor(); + OpenGL::bindScreenFramebuffer(); - fboTexture.bind(); + colourBufferCache[0].texture.bind(); + displayProgram.use(); dummyVAO.bind(); - OpenGL::setClearColor(0.0, 0.0, 0.0, 1.0); // Clear screen colour + OpenGL::setClearColor(0.0, 0.0, 1.0, 1.0); // Clear screen colour OpenGL::clearColor(); OpenGL::setViewport(0, 240, 400, 240); // Actually draw our 3DS screen OpenGL::draw(OpenGL::TriangleStrip, 4); } void Renderer::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) { + return; log("GPU: Clear buffer\nStart: %08X End: %08X\nValue: %08X Control: %08X\n", startAddress, endAddress, value, control); const float r = float((value >> 24) & 0xff) / 255.0;