mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-08 23:25:40 +12:00
Implement reading texture from NULL
This commit is contained in:
parent
0aef0a6426
commit
7bbf37bb63
2 changed files with 31 additions and 4 deletions
|
@ -55,6 +55,7 @@ class RendererGL final : public Renderer {
|
||||||
OpenGL::Texture screenTexture;
|
OpenGL::Texture screenTexture;
|
||||||
GLuint lightLUTTextureArray;
|
GLuint lightLUTTextureArray;
|
||||||
OpenGL::Framebuffer screenFramebuffer;
|
OpenGL::Framebuffer screenFramebuffer;
|
||||||
|
OpenGL::Texture blankTexture;
|
||||||
|
|
||||||
OpenGL::Framebuffer getColourFBO();
|
OpenGL::Framebuffer getColourFBO();
|
||||||
OpenGL::Texture getTexture(Texture& tex);
|
OpenGL::Texture getTexture(Texture& tex);
|
||||||
|
|
|
@ -118,6 +118,7 @@ void RendererGL::initGraphicsContext(SDL_Window* window) {
|
||||||
|
|
||||||
dummyVBO.create();
|
dummyVBO.create();
|
||||||
dummyVAO.create();
|
dummyVAO.create();
|
||||||
|
gl.disableScissor();
|
||||||
|
|
||||||
// Create texture and framebuffer for the 3DS screen
|
// Create texture and framebuffer for the 3DS screen
|
||||||
const u32 screenTextureWidth = 400; // Top screen is 400 pixels wide, bottom is 320
|
const u32 screenTextureWidth = 400; // Top screen is 400 pixels wide, bottom is 320
|
||||||
|
@ -126,6 +127,24 @@ void RendererGL::initGraphicsContext(SDL_Window* window) {
|
||||||
glGenTextures(1, &lightLUTTextureArray);
|
glGenTextures(1, &lightLUTTextureArray);
|
||||||
|
|
||||||
auto prevTexture = OpenGL::getTex2D();
|
auto prevTexture = OpenGL::getTex2D();
|
||||||
|
|
||||||
|
// Create a plain black texture for when a game reads an invalid texture. It is common for games to configure the PICA to read texture info from NULL.
|
||||||
|
// Some games that do this are Pokemon X, Cars 2, Tomodachi Life, and more. We bind the texture to an FBO, clear it, and free the FBO
|
||||||
|
blankTexture.create(8, 8, GL_RGBA8);
|
||||||
|
blankTexture.bind();
|
||||||
|
blankTexture.setMinFilter(OpenGL::Linear);
|
||||||
|
blankTexture.setMagFilter(OpenGL::Linear);
|
||||||
|
|
||||||
|
OpenGL::Framebuffer dummyFBO;
|
||||||
|
dummyFBO.createWithDrawTexture(blankTexture); // Create FBO and bind our texture to it
|
||||||
|
dummyFBO.bind(OpenGL::DrawFramebuffer);
|
||||||
|
|
||||||
|
// Clear the texture and then delete FBO
|
||||||
|
OpenGL::setViewport(8, 8);
|
||||||
|
gl.setClearColour(0.0, 0.0, 0.0, 1.0);
|
||||||
|
OpenGL::clearColor();
|
||||||
|
dummyFBO.free();
|
||||||
|
|
||||||
screenTexture.create(screenTextureWidth, screenTextureHeight, GL_RGBA8);
|
screenTexture.create(screenTextureWidth, screenTextureHeight, GL_RGBA8);
|
||||||
screenTexture.bind();
|
screenTexture.bind();
|
||||||
screenTexture.setMinFilter(OpenGL::Linear);
|
screenTexture.setMinFilter(OpenGL::Linear);
|
||||||
|
@ -143,7 +162,6 @@ void RendererGL::initGraphicsContext(SDL_Window* window) {
|
||||||
GLint oldViewport[4];
|
GLint oldViewport[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, oldViewport);
|
glGetIntegerv(GL_VIEWPORT, oldViewport);
|
||||||
OpenGL::setViewport(screenTextureWidth, screenTextureHeight);
|
OpenGL::setViewport(screenTextureWidth, screenTextureHeight);
|
||||||
gl.setClearColour(0.0, 0.0, 0.0, 1.0);
|
|
||||||
OpenGL::clearColor();
|
OpenGL::clearColor();
|
||||||
OpenGL::setViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
|
OpenGL::setViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
|
||||||
|
|
||||||
|
@ -321,9 +339,17 @@ void RendererGL::bindTexturesToSlots() {
|
||||||
u32 format = regs[ioBase + (i == 0 ? 13 : 5)] & 0xF;
|
u32 format = regs[ioBase + (i == 0 ? 13 : 5)] & 0xF;
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
Texture targetTex(addr, static_cast<PICA::TextureFmt>(format), width, height, config);
|
|
||||||
OpenGL::Texture tex = getTexture(targetTex);
|
if (addr != 0) [[likely]] {
|
||||||
tex.bind();
|
Texture targetTex(addr, static_cast<PICA::TextureFmt>(format), width, height, config);
|
||||||
|
OpenGL::Texture tex = getTexture(targetTex);
|
||||||
|
tex.bind();
|
||||||
|
} else {
|
||||||
|
// Mapping a texture from NULL. PICA seems to read the last sampled colour, but for now we will display a black texture instead since it is far easier.
|
||||||
|
// Games that do this don't really care what it does, they just expect the PICA to not crash, since it doesn't have a PU/MMU and can do all sorts of
|
||||||
|
// Weird invalid memory accesses without crashing
|
||||||
|
blankTexture.bind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + 3);
|
glActiveTexture(GL_TEXTURE0 + 3);
|
||||||
|
|
Loading…
Add table
Reference in a new issue