Supermodel/Src/Graphics/FBO.cpp
Ian Curtis c6ea81d996 Emulate the entire tilegen chip in a GLSL shader. (This is now possible with opengl 3+). The tilegen drawing was emulated on the CPU, but was one of the most expensive functions in the emulator according to a profiler. On a modern GPU it's pretty much free, because a GPU is a massive SIMD monster.
Tilegen shaders are mapped to uniforms, and the vram and palette are mapped to two textures.

TODO rip out the redundant code in the tilegen class. We don't need to pre-calculate palettes anymore. etc

The tilegen code supports has a start/end line so we can emulate as many lines as we want in a chunk, which will come in later as some games update the tilegen immediately after the ping_pong bit has flipped ~ 66% of the frame.

The scud rolling start tilegen bug is probably actually a bug in the original h/w implementation, that ends up looking correct on original h/w but not for us. Need hardware testing to confirm what it's actually doing.
2023-09-23 15:27:04 +01:00

74 lines
1.6 KiB
C++

#include "FBO.h"
FBO::FBO() :
m_frameBufferID(0),
m_textureID(0)
{
}
bool FBO::Create(int width, int height)
{
CreateTexture(width, height);
glGenFramebuffers(1, &m_frameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureID, 0);
auto frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, 0); //created FBO now disable it
return frameBufferStatus == GL_FRAMEBUFFER_COMPLETE;
}
void FBO::Destroy()
{
if (m_frameBufferID) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &m_frameBufferID);
}
if (m_textureID) {
glDeleteTextures(1, &m_textureID);
}
m_frameBufferID = 0;
m_textureID = 0;
}
void FBO::BindTexture()
{
glBindTexture(GL_TEXTURE_2D, m_textureID);
}
void FBO::Set()
{
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferID);
}
void FBO::Disable()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GLuint FBO::GetFBOID()
{
return m_frameBufferID;
}
GLuint FBO::GetTextureID()
{
return m_textureID;
}
void FBO::CreateTexture(int width, int height)
{
glGenTextures (1, &m_textureID);
glBindTexture (GL_TEXTURE_2D, m_textureID);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}