mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Implement copy RDRAM to frame buffer.
This commit is contained in:
parent
35ab89d379
commit
5f57aa5c48
203
FrameBuffer.cpp
203
FrameBuffer.cpp
|
@ -17,6 +17,7 @@
|
|||
#include "Debug.h"
|
||||
|
||||
bool g_bCopyToRDRAM = true;
|
||||
bool g_bCopyFromRDRAM = false;
|
||||
FrameBufferInfo frameBuffer;
|
||||
|
||||
static GLuint m_curFrameFbo = 0;
|
||||
|
@ -50,7 +51,32 @@ private:
|
|||
u32 m_curIndex;
|
||||
};
|
||||
|
||||
class RDRAMtoFrameBuffer
|
||||
{
|
||||
public:
|
||||
RDRAMtoFrameBuffer() : m_pTexture(NULL), m_PBO(0) {}
|
||||
|
||||
void Init();
|
||||
void Destroy();
|
||||
|
||||
void CopyFromRDRAM( u32 address);
|
||||
|
||||
private:
|
||||
struct PBOBinder {
|
||||
PBOBinder(GLuint _PBO)
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _PBO);
|
||||
}
|
||||
~PBOBinder() {
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
};
|
||||
CachedTexture * m_pTexture;
|
||||
GLuint m_PBO;
|
||||
};
|
||||
|
||||
FrameBufferToRDRAM g_fbToRDRAM;
|
||||
RDRAMtoFrameBuffer g_RDRAMtoFB;
|
||||
|
||||
void FrameBuffer_Init()
|
||||
{
|
||||
|
@ -60,6 +86,7 @@ void FrameBuffer_Init()
|
|||
frameBuffer.numBuffers = 0;
|
||||
frameBuffer.drawBuffer = GL_BACK;
|
||||
g_fbToRDRAM.Init();
|
||||
g_RDRAMtoFB.Init();
|
||||
}
|
||||
|
||||
void FrameBuffer_RemoveBottom()
|
||||
|
@ -189,6 +216,7 @@ void FrameBuffer_Destroy()
|
|||
while (frameBuffer.bottom)
|
||||
FrameBuffer_RemoveBottom();
|
||||
g_fbToRDRAM.Destroy();
|
||||
g_RDRAMtoFB.Destroy();
|
||||
}
|
||||
|
||||
void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 height )
|
||||
|
@ -312,6 +340,7 @@ void FrameBuffer_RenderBuffer( u32 address )
|
|||
GL_COLOR_BUFFER_BIT, GL_LINEAR
|
||||
);
|
||||
glDrawBuffer( GL_BACK );
|
||||
ogl_glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
|
||||
}
|
||||
#else
|
||||
|
@ -634,3 +663,177 @@ void FrameBuffer_CopyToRDRAM( u32 address, bool bSync )
|
|||
{
|
||||
g_fbToRDRAM.CopyToRDRAM(address, bSync);
|
||||
}
|
||||
|
||||
void RDRAMtoFrameBuffer::Init()
|
||||
{
|
||||
m_pTexture = TextureCache_AddTop();
|
||||
m_pTexture->format = G_IM_FMT_RGBA;
|
||||
m_pTexture->clampS = 1;
|
||||
m_pTexture->clampT = 1;
|
||||
m_pTexture->frameBufferTexture = TRUE;
|
||||
m_pTexture->maskS = 0;
|
||||
m_pTexture->maskT = 0;
|
||||
m_pTexture->mirrorS = 0;
|
||||
m_pTexture->mirrorT = 0;
|
||||
m_pTexture->realWidth = 1024;
|
||||
m_pTexture->realHeight = 512;
|
||||
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * 4;
|
||||
cache.cachedBytes += m_pTexture->textureBytes;
|
||||
glBindTexture( GL_TEXTURE_2D, m_pTexture->glName );
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Generate Pixel Buffer Object. Initialize it later
|
||||
glGenBuffers(1, &m_PBO);
|
||||
}
|
||||
|
||||
void RDRAMtoFrameBuffer::Destroy()
|
||||
{
|
||||
TextureCache_Remove( m_pTexture );
|
||||
glDeleteBuffers(1, &m_PBO);
|
||||
}
|
||||
|
||||
void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 address)
|
||||
{
|
||||
FrameBuffer *current = FrameBuffer_FindBuffer(address);
|
||||
if (current == NULL || current->size < G_IM_SIZ_16b)
|
||||
return;
|
||||
|
||||
const u32 width = current->width;
|
||||
const u32 height = current->height;
|
||||
m_pTexture->width = width;
|
||||
m_pTexture->height = height;
|
||||
const u32 dataSize = width*height*4;
|
||||
PBOBinder binder(m_PBO);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW);
|
||||
GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
u8 * image = RDRAM + address;
|
||||
u32 * dst = (u32*)ptr;
|
||||
|
||||
u32 empty = 0;
|
||||
u32 r, g, b,a, idx;
|
||||
if (current->size == G_IM_SIZ_16b) {
|
||||
u16 * src = (u16*)image;
|
||||
u16 col;
|
||||
const u32 bound = (RDRAMSize + 1 - address) >> 1;
|
||||
for (u32 y = 0; y < height; y++)
|
||||
{
|
||||
for (u32 x = 0; x < width; x++)
|
||||
{
|
||||
idx = (x + (height - y - 1)*width)^1;
|
||||
if (idx >= bound)
|
||||
break;
|
||||
col = src[idx];
|
||||
empty |= col;
|
||||
r = ((col >> 11)&31)<<3;
|
||||
g = ((col >> 6)&31)<<3;
|
||||
b = ((col >> 1)&31)<<3;
|
||||
a = col&1 > 0 ? 0xff : 0;
|
||||
//*(dst++) = RGBA5551_RGBA8888(c);
|
||||
dst[x + y*width] = (a<<24)|(b<<16)|(g<<8)|r;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 32 bit
|
||||
u32 * src = (u32*)image;
|
||||
u32 col;
|
||||
const u32 bound = (RDRAMSize + 1 - address) >> 2;
|
||||
for (u32 y=0; y < height; y++)
|
||||
{
|
||||
for (u32 x=0; x < width; x++)
|
||||
{
|
||||
idx = x + (height - y - 1)*width;
|
||||
if (idx >= bound)
|
||||
break;
|
||||
col = src[idx];
|
||||
empty |= col;
|
||||
r = (col >> 24) & 0xff;
|
||||
g = (col >> 16) & 0xff;
|
||||
b = (col >> 8) & 0xff;
|
||||
a = col & 0xff;
|
||||
dst[x + y*width] = (a<<24)|(b<<16)|(g<<8)|r;
|
||||
}
|
||||
}
|
||||
}
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer
|
||||
if (empty == 0)
|
||||
return;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
#if 0
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
ogl_glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO);
|
||||
const GLuint attachment = GL_COLOR_ATTACHMENT0;
|
||||
glReadBuffer(attachment);
|
||||
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
|
||||
glDrawBuffers(1, &attachment);
|
||||
ogl_glBlitFramebuffer(
|
||||
0, 0, width, height,
|
||||
0, 0, OGL.width, OGL.height,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR
|
||||
);
|
||||
ogl_glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
|
||||
#else
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT );
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
Combiner_SetCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0 ) );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
//glDisable( GL_ALPHA_TEST );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_CULL_FACE );
|
||||
glDisable( GL_POLYGON_OFFSET_FILL );
|
||||
glDisable( GL_FOG );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glLoadIdentity();
|
||||
glOrtho( 0, OGL.width, 0, OGL.height, -1.0f, 1.0f );
|
||||
glViewport( 0, 0, OGL.width, OGL.height );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
|
||||
float u1, v1;
|
||||
|
||||
u1 = (float)width / (float)m_pTexture->realWidth;
|
||||
v1 = (float)height / (float)m_pTexture->realHeight;
|
||||
|
||||
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
|
||||
const GLuint attachment = GL_COLOR_ATTACHMENT0;
|
||||
glDrawBuffers(1, &attachment);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2f( 0.0f, 0.0f );
|
||||
|
||||
glTexCoord2f( 0.0f, v1 );
|
||||
glVertex2f( 0.0f, (GLfloat)OGL.height );
|
||||
|
||||
glTexCoord2f( u1, v1 );
|
||||
glVertex2f( (GLfloat)OGL.width, (GLfloat)OGL.height );
|
||||
|
||||
glTexCoord2f( u1, 0.0f );
|
||||
glVertex2f( (GLfloat)OGL.width, 0.0f );
|
||||
glEnd();
|
||||
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glLoadIdentity();
|
||||
glPopAttrib();
|
||||
|
||||
gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT;
|
||||
gDP.changed |= CHANGED_COMBINE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FrameBuffer_CopyFromRDRAM( u32 address )
|
||||
{
|
||||
g_RDRAMtoFB.CopyFromRDRAM(address);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ struct FrameBufferInfo
|
|||
|
||||
extern FrameBufferInfo frameBuffer;
|
||||
extern bool g_bCopyToRDRAM;
|
||||
extern bool g_bCopyFromRDRAM;
|
||||
|
||||
void FrameBuffer_Init();
|
||||
void FrameBuffer_Destroy();
|
||||
|
@ -35,6 +36,7 @@ void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 h
|
|||
void FrameBuffer_RenderBuffer( u32 address );
|
||||
void FrameBuffer_RemoveBuffer( u32 address );
|
||||
void FrameBuffer_CopyToRDRAM( u32 address, bool bSync );
|
||||
void FrameBuffer_CopyFromRDRAM( u32 address );
|
||||
FrameBuffer *FrameBuffer_FindBuffer( u32 address );
|
||||
void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer );
|
||||
void FrameBuffer_ActivateBufferTextureBG( s16 t, FrameBuffer *buffer );
|
||||
|
|
|
@ -375,6 +375,7 @@ EXPORT void CALL RomOpen (void)
|
|||
|
||||
EXPORT void CALL ShowCFB (void)
|
||||
{
|
||||
gSP.changed |= CHANGED_CPU_FB_WRITE;
|
||||
}
|
||||
|
||||
EXPORT void CALL UpdateScreen (void)
|
||||
|
|
|
@ -105,6 +105,7 @@ PFNGLBINDBUFFERPROC glBindBuffer;
|
|||
PFNGLBUFFERDATAPROC glBufferData;
|
||||
PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
|
||||
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
|
||||
|
@ -270,6 +271,7 @@ void OGL_InitExtensions()
|
|||
glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress( "glBufferData" );
|
||||
glMapBuffer = (PFNGLMAPBUFFERPROC)wglGetProcAddress( "glMapBuffer" );
|
||||
glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)wglGetProcAddress( "glUnmapBuffer" );
|
||||
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)wglGetProcAddress( "glDeleteBuffers" );
|
||||
|
||||
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
|
||||
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
|
||||
|
|
1
OpenGL.h
1
OpenGL.h
|
@ -172,6 +172,7 @@ extern PFNGLBINDBUFFERPROC glBindBuffer;
|
|||
extern PFNGLBUFFERDATAPROC glBufferData;
|
||||
extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||
extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
|
||||
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
|
||||
|
|
1
RSP.cpp
1
RSP.cpp
|
@ -201,6 +201,7 @@ void RSP_ProcessDList()
|
|||
|
||||
gSP.matrix.stackSize = min( 32, *(u32*)&DMEM[0x0FE4] >> 6 );
|
||||
gSP.matrix.modelViewi = 0;
|
||||
gSP.changed &= ~CHANGED_CPU_FB_WRITE;
|
||||
gSP.changed |= CHANGED_MATRIX;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
|
30
VI.cpp
30
VI.cpp
|
@ -42,19 +42,21 @@ void VI_UpdateScreen()
|
|||
OGL.captureScreen = false;
|
||||
}
|
||||
|
||||
if (OGL.frameBufferTextures)
|
||||
{
|
||||
//FrameBuffer *current = FrameBuffer_FindBuffer( *REG.VI_ORIGIN );
|
||||
if (OGL.frameBufferTextures) {
|
||||
const bool bDListUpdated = (gSP.changed&CHANGED_CPU_FB_WRITE) == 0;
|
||||
const bool bNeedUpdate = bDListUpdated ? (*REG.VI_ORIGIN != VI.lastOrigin) && gDP.colorImage.changed : true;
|
||||
|
||||
if ((*REG.VI_ORIGIN != VI.lastOrigin) && gDP.colorImage.changed)
|
||||
{
|
||||
/*
|
||||
if (gDP.colorImage.changed)
|
||||
{
|
||||
FrameBuffer_SaveBuffer( gDP.colorImage.address, gDP.colorImage.size, gDP.colorImage.width, gDP.colorImage.height );
|
||||
gDP.colorImage.changed = FALSE;
|
||||
if (bNeedUpdate) {
|
||||
FrameBuffer * pBuffer = FrameBuffer_FindBuffer(*REG.VI_ORIGIN);
|
||||
if (pBuffer == NULL || pBuffer->width != *REG.VI_WIDTH) {
|
||||
VI_UpdateSize();
|
||||
OGL_UpdateScale();
|
||||
const u32 size = *REG.VI_STATUS & 3;
|
||||
if (VI.height > 0 && size > G_IM_SIZ_8b)
|
||||
FrameBuffer_SaveBuffer( *REG.VI_ORIGIN, G_IM_FMT_RGBA, size, *REG.VI_WIDTH, VI.height );
|
||||
}
|
||||
*/
|
||||
if (g_bCopyFromRDRAM || !bDListUpdated)
|
||||
FrameBuffer_CopyFromRDRAM( *REG.VI_ORIGIN );
|
||||
if (g_bCopyToRDRAM)
|
||||
FrameBuffer_CopyToRDRAM( *REG.VI_ORIGIN, false );
|
||||
FrameBuffer_RenderBuffer( *REG.VI_ORIGIN );
|
||||
|
@ -67,10 +69,8 @@ void VI_UpdateScreen()
|
|||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gSP.changed & CHANGED_COLORBUFFER)
|
||||
{
|
||||
else {
|
||||
if (gSP.changed & CHANGED_COLORBUFFER) {
|
||||
#ifndef __LINUX__
|
||||
SwapBuffers( OGL.hDC );
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue
Block a user