1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Frame buffer fixes

This commit is contained in:
Sergey Lipskiy 2013-06-01 20:10:30 +07:00
parent 263f4fc112
commit a07555546e
10 changed files with 218 additions and 67 deletions

View File

@ -1,6 +1,8 @@
#include <malloc.h>
#include "OpenGL.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "Types.h"
#include "Debug.h"
DepthBufferInfo depthBuffer;
@ -19,6 +21,8 @@ void DepthBuffer_RemoveBottom()
if (depthBuffer.bottom == depthBuffer.top)
depthBuffer.top = NULL;
if (depthBuffer.bottom->renderbuf != 0)
glDeleteRenderbuffers(1, &depthBuffer.bottom->renderbuf);
free( depthBuffer.bottom );
depthBuffer.bottom = newBottom;
@ -57,6 +61,8 @@ void DepthBuffer_Remove( DepthBuffer *buffer )
buffer->lower->higher = buffer->higher;
}
if (buffer->renderbuf != 0)
ogl_glDeleteRenderbuffers(1, &buffer->renderbuf);
free( buffer );
depthBuffer.numBuffers--;
@ -83,6 +89,7 @@ DepthBuffer *DepthBuffer_AddTop()
newtop->lower = depthBuffer.top;
newtop->higher = NULL;
newtop->renderbuf = 0;
if (depthBuffer.top)
depthBuffer.top->higher = newtop;
@ -138,6 +145,18 @@ void DepthBuffer_SetBuffer( u32 address )
{
DepthBuffer_MoveToTop( current );
depthBuffer.current = current;
if ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0) {
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, current->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, frameBuffer.top->texture->glName);
}
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n",
address, ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0) ? frameBuffer.top->startAddress : 0
);
#endif
return;
}
current = current->lower;
@ -147,7 +166,25 @@ void DepthBuffer_SetBuffer( u32 address )
current->address = address;
current->cleared = TRUE;
if (OGL.frameBufferTextures) {
ogl_glGenRenderbuffers(1, &current->renderbuf);
ogl_glBindRenderbuffer(GL_RENDERBUFFER, current->renderbuf);
ogl_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, (u32)pow2(OGL.width), (u32)pow2(OGL.height));
if ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0) {
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, current->renderbuf);
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, frameBuffer.top->texture->glName);
}
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n",
address, ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0) ? frameBuffer.top->startAddress : 0
);
#endif
}
depthBuffer.current = current;
}
@ -157,7 +194,10 @@ DepthBuffer *DepthBuffer_FindBuffer( u32 address )
while (current)
{
if (current->address == address)
if (current->address == address) {
if (OGL.frameBufferTextures)
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, current->renderbuf);
}
return current;
current = current->lower;
}

View File

@ -8,6 +8,7 @@ struct DepthBuffer
DepthBuffer *higher, *lower;
u32 address, cleared;
GLuint renderbuf;
};
struct DepthBufferInfo

View File

@ -3,13 +3,29 @@
#else
# include "winlnxdefs.h"
#endif // __LINUX__
#include <assert.h>
#include "OpenGL.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "RSP.h"
#include "RDP.h"
#include "Textures.h"
#include "Combiner.h"
#include "Types.h"
#include "Debug.h"
/*
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
mFrameBuffer.Identifier );
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
glBlitFramebufferEXT
(
0, 0, ClientWidth, ClientHeight,
0, 0, ClientWidth, ClientHeight,
GL_COLOR_BUFFER_BIT, GL_LINEAR
);
*/
FrameBufferInfo frameBuffer;
@ -19,6 +35,7 @@ void FrameBuffer_Init()
frameBuffer.top = NULL;
frameBuffer.bottom = NULL;
frameBuffer.numBuffers = 0;
frameBuffer.drawBuffer = GL_BACK;
}
void FrameBuffer_RemoveBottom()
@ -26,6 +43,8 @@ void FrameBuffer_RemoveBottom()
FrameBuffer *newBottom = frameBuffer.bottom->higher;
TextureCache_Remove( frameBuffer.bottom->texture );
if (frameBuffer.bottom->fbo != 0)
ogl_glDeleteFramebuffers(1, &frameBuffer.bottom->fbo);
if (frameBuffer.bottom == frameBuffer.top)
frameBuffer.top = NULL;
@ -70,6 +89,8 @@ void FrameBuffer_Remove( FrameBuffer *buffer )
if (buffer->texture)
TextureCache_Remove( buffer->texture );
if (buffer->fbo != 0)
ogl_glDeleteFramebuffers(1, &buffer->fbo);
free( buffer );
@ -97,6 +118,7 @@ FrameBuffer *FrameBuffer_AddTop()
FrameBuffer *newtop = (FrameBuffer*)malloc( sizeof( FrameBuffer ) );
newtop->texture = TextureCache_AddTop();
newtop->fbo = 0;
newtop->lower = frameBuffer.top;
newtop->higher = NULL;
@ -146,25 +168,45 @@ void FrameBuffer_Destroy()
void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
{
frameBuffer.drawBuffer = GL_DRAW_FRAMEBUFFER;
FrameBuffer *current = frameBuffer.top;
// Search through saved frame buffers
while (current != NULL)
{
if ((current->startAddress == address) &&
(current->width == width) &&
(current->height == height) &&
(current->size == size))
if ((current->startAddress <= address) &&
(current->endAddress >= address))
{
if ((current->scaleX != OGL.scaleX) ||
if ((current->width != width) ||
(current->height != height) ||
(current->size != size) || // TODO FIX ME
(current->scaleX != OGL.scaleX) ||
(current->scaleY != OGL.scaleY))
{
FrameBuffer_Remove( current );
break;
}
glBindTexture( GL_TEXTURE_2D, current->texture->glName );
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, OGL.height - current->texture->height + OGL.heightOffset, current->texture->width, current->texture->height );
current->startAddress = address;
current->endAddress = address + ((width * height << size >> 1) - 1);
current->texture->address = current->startAddress;
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
if (depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) {
ogl_glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.top->renderbuf);
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.top->renderbuf);
}
// define the index array for the outputs
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, current->texture->glName);
assert(checkFBO());
if (depthBuffer.top != NULL && depthBuffer.top->cleared)
OGL_ClearDepthBuffer();
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_SaveBuffer( 0x%08X ); \n", address);
#endif
*(u32*)&RDRAM[current->startAddress] = current->startAddress;
current->changed = TRUE;
@ -206,7 +248,30 @@ void FrameBuffer_SaveBuffer( u32 address, u16 size, u16 width, u16 height )
cache.cachedBytes += current->texture->textureBytes;
glBindTexture( GL_TEXTURE_2D, current->texture->glName );
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, 0, OGL.height - current->texture->height + OGL.heightOffset, current->texture->realWidth, current->texture->realHeight, 0 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, current->texture->realWidth, current->texture->realHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ogl_glGenFramebuffers(1, &current->fbo);
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo);
ogl_glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, current->texture->glName, 0);
if (depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) {
ogl_glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.top->renderbuf);
ogl_glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.top->renderbuf);
}
GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT };
ogl_glDrawBuffers(2, attachments, current->texture->glName);
assert(checkFBO());
if (depthBuffer.top != NULL && depthBuffer.top->cleared)
OGL_ClearDepthBuffer();
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_SaveBuffer( 0x%08X ); depth buffer is 0x%08X\n",
address, (depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) ? depthBuffer.top->address : 0
);
#endif
*(u32*)&RDRAM[current->startAddress] = current->startAddress;
current->changed = TRUE;
@ -262,6 +327,7 @@ void FrameBuffer_RenderBuffer( u32 address )
u1 = (float)current->texture->width / (float)current->texture->realWidth;
v1 = (float)current->texture->height / (float)current->texture->realHeight;
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer( GL_FRONT );
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
@ -277,24 +343,29 @@ void FrameBuffer_RenderBuffer( u32 address )
glVertex2f( current->texture->width, (GLfloat)(OGL.height - current->texture->height) );
glEnd();
glDrawBuffer( GL_BACK );
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_RenderBuffer( 0x%08X ); \n", address);
#endif
/* glEnable( GL_TEXTURE_2D );
glActiveTextureARB( GL_TEXTURE0_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );*/
glLoadIdentity();
glPopAttrib();
current->changed = FALSE;
FrameBuffer_MoveToTop( current );
gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT;
gDP.changed |= CHANGED_COMBINE;
return;
}
current = current->lower;
}
}
void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width )
{
FrameBuffer *current = frameBuffer.top;
@ -346,6 +417,7 @@ void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width )
u1 = (float)current->texture->width / (float)current->texture->realWidth;
v1 = (float)current->texture->height / (float)current->texture->realHeight;
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBegin(GL_QUADS);
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( 0.0f, OGL.height - current->texture->height );
@ -359,6 +431,10 @@ void FrameBuffer_RestoreBuffer( u32 address, u16 size, u16 width )
glTexCoord2f( u1, 0.0f );
glVertex2f( current->texture->width, OGL.height - current->texture->height );
glEnd();
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo);
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_RestoreBuffer( 0x%08X ); \n", address);
#endif
glLoadIdentity();
glPopAttrib();

View File

@ -9,6 +9,7 @@ struct FrameBuffer
FrameBuffer *higher, *lower;
CachedTexture *texture;
GLuint fbo;
u32 startAddress, endAddress;
u32 size, width, height, changed;
@ -19,6 +20,7 @@ struct FrameBufferInfo
{
FrameBuffer *top, *bottom, *current;
int numBuffers;
GLenum drawBuffer;
};
extern FrameBufferInfo frameBuffer;

View File

@ -496,35 +496,7 @@ void InitGLSLCombiner()
ogl_glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, g_lod_tex, 0);
// check if everything is OK
GLenum e = ogl_glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch (e) {
case GL_FRAMEBUFFER_UNDEFINED:
printf("FBO Undefined\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT :
printf("FBO Incomplete Attachment\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
printf("FBO Missing Attachment\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
printf("FBO Incomplete Draw Buffer\n");
break;
case GL_FRAMEBUFFER_UNSUPPORTED :
printf("FBO Unsupported\n");
break;
case GL_FRAMEBUFFER_COMPLETE:
printf("FBO OK\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
printf("framebuffer FRAMEBUFFER_DIMENSIONS\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
printf("framebuffer INCOMPLETE_FORMATS\n");
break;
default:
printf("FBO Problem?\n");
}
assert(checkFBO());
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
@ -763,7 +735,7 @@ void OGL_UpdateCullFace();
void OGL_UpdateViewport();
void OGL_ClearColorBuffer( float *color );
/*
#if defined(LOD_TEST)
void drawFBO()
{
glUseProgramObjectARB(0);
@ -784,8 +756,8 @@ void drawFBO()
glBindTexture(GL_TEXTURE_2D, g_lod_tex);
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glColor4f( 1, 1, 1, 1 );
const float s0 = 1.0f;//640.0f/1024.0f;
const float t0 = 1.0f;//480.0f/1024.0f;
const float s0 = 0.5f;//640.0f/1024.0f;
const float t0 = 0.5f;//480.0f/1024.0f;
glBegin( GL_QUADS );
@ -807,7 +779,7 @@ void drawFBO()
OGL_UpdateViewport();
}
*/
#endif
void GLSL_CalcLOD() {
glDisable( GL_DEPTH_TEST );
@ -816,13 +788,11 @@ void GLSL_CalcLOD() {
// Set Drawing buffers
GLuint attachments[1] = {GL_COLOR_ATTACHMENT0};
ogl_glDrawBuffers(1, attachments, g_lod_tex);
float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
OGL_ClearColorBuffer(clear_color );
glUseProgramObjectARB(g_lod_program);
glDrawArrays( GL_TRIANGLES, 0, OGL.numVertices );
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top != NULL ? frameBuffer.top->fbo : 0);
// drawFBO();
@ -854,7 +824,7 @@ void GLSL_PostCalcLOD() {
glUseProgramObjectARB(g_lod_clear_program);
glDrawArrays( GL_TRIANGLES, 0, OGL.numVertices );
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
ogl_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top != NULL ? frameBuffer.top->fbo : 0);
Combiner_SetCombine( gDP.combine.mux );
}

View File

@ -8,6 +8,7 @@
# include <GL/glext.h>
# include "SDL.h"
#endif // __LINUX__
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include "GLideN64.h"
@ -98,6 +99,7 @@ PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
@ -109,6 +111,7 @@ PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
#endif // !__LINUX__
BOOL isExtensionSupported( const char *extension )
@ -256,6 +259,7 @@ void OGL_InitExtensions()
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)wglGetProcAddress( "glFramebufferRenderbuffer" );
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)wglGetProcAddress( "glDeleteRenderbuffers" );
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)wglGetProcAddress( "glCheckFramebufferStatus" );
glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)wglGetProcAddress( "glBlitFramebuffer" );
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
@ -268,6 +272,7 @@ void OGL_InitExtensions()
glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)wglGetProcAddress("glBlitFramebufferEXT");
if (glGenFramebuffers != NULL)
OGL.framebuffer_mode = GLInfo::fbFBO;
@ -574,7 +579,7 @@ void OGL_UpdateCullFace()
void OGL_UpdateViewport()
{
glViewport( gSP.viewport.x * OGL.scaleX, (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset,
glViewport( gSP.viewport.x * OGL.scaleX, (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0),
gSP.viewport.width * OGL.scaleX, gSP.viewport.height * OGL.scaleY );
glDepthRange( 0.0f, 1.0f );//gSP.viewport.nearz, gSP.viewport.farz );
}
@ -652,7 +657,7 @@ void OGL_UpdateStates()
if (gDP.changed & CHANGED_SCISSOR)
{
glScissor( gDP.scissor.ulx * OGL.scaleX, (VI.height - gDP.scissor.lry) * OGL.scaleY + OGL.heightOffset,
glScissor( gDP.scissor.ulx * OGL.scaleX, (VI.height - gDP.scissor.lry) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0),
(gDP.scissor.lrx - gDP.scissor.ulx) * OGL.scaleX, (gDP.scissor.lry - gDP.scissor.uly) * OGL.scaleY );
}
@ -925,7 +930,7 @@ void OGL_DrawRect( int ulx, int uly, int lrx, int lry, float *color )
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, VI.width, VI.height, 0, 1.0f, -1.0f );
glViewport( 0, OGL.heightOffset, OGL.width, OGL.height );
glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height );
glDepthRange( 0.0f, 1.0f );
glColor4f( color[0], color[1], color[2], color[3] );
@ -957,7 +962,7 @@ void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, VI.width, VI.height, 0, 1.0f, -1.0f );
glViewport( 0, OGL.heightOffset, OGL.width, OGL.height );
glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height );
if (combiner.usesT0)
{
@ -1115,6 +1120,8 @@ void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls
void OGL_ClearDepthBuffer()
{
if (OGL.frameBufferTextures && frameBuffer.top == NULL)
return;
glDisable( GL_SCISSOR_TEST );
OGL_UpdateStates();
@ -1263,6 +1270,9 @@ void ogl_glBindFramebuffer (GLenum target, GLuint framebuffer) {
case GL_DRAW_FRAMEBUFFER:
target = GL_FRAMEBUFFER_EXT;
break;
case GL_READ_FRAMEBUFFER:
target = GL_READ_FRAMEBUFFER_EXT;
break;
}
glBindFramebufferEXT(target, framebuffer);
break;
@ -1411,6 +1421,7 @@ void ogl_glDrawBuffers (GLsizei n, const GLenum *bufs, GLuint texture) {
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);
break;
}
assert(checkFBO());
}
GLenum ogl_glCheckFramebufferStatus (GLenum target) {
@ -1446,3 +1457,47 @@ GLenum ogl_glCheckFramebufferStatus (GLenum target) {
}
return GL_FRAMEBUFFER_UNSUPPORTED;
}
bool checkFBO() {
GLenum e = ogl_glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
switch (e) {
case GL_FRAMEBUFFER_UNDEFINED:
printf("FBO Undefined\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT :
printf("FBO Incomplete Attachment\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
printf("FBO Missing Attachment\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
printf("FBO Incomplete Draw Buffer\n");
break;
case GL_FRAMEBUFFER_UNSUPPORTED :
printf("FBO Unsupported\n");
break;
case GL_FRAMEBUFFER_COMPLETE:
printf("FBO OK\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
printf("framebuffer FRAMEBUFFER_DIMENSIONS\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
printf("framebuffer INCOMPLETE_FORMATS\n");
break;
default:
printf("FBO Problem?\n");
}
return e == GL_FRAMEBUFFER_COMPLETE;
}
void ogl_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
switch (OGL.framebuffer_mode) {
case GLInfo::fbFBO:
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
break;
case GLInfo::fbFBOEXT:
glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
break;
}
}

View File

@ -165,6 +165,7 @@ extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
@ -176,6 +177,7 @@ extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
#endif // !__LINUX__
bool OGL_Start();
@ -206,5 +208,9 @@ void ogl_glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
void ogl_glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
void ogl_glDrawBuffers (GLsizei n, const GLenum *bufs, GLuint texture);
GLenum ogl_glCheckFramebufferStatus (GLenum target);
void ogl_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
bool checkFBO();
//#define LOD_TEST
#endif

7
VI.cpp
View File

@ -39,16 +39,17 @@ void VI_UpdateScreen()
if (OGL.frameBufferTextures)
{
FrameBuffer *current = FrameBuffer_FindBuffer( *REG.VI_ORIGIN );
//FrameBuffer *current = FrameBuffer_FindBuffer( *REG.VI_ORIGIN );
if ((*REG.VI_ORIGIN != VI.lastOrigin) || ((current) && current->changed))
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;
}
*/
FrameBuffer_RenderBuffer( *REG.VI_ORIGIN );
gDP.colorImage.changed = FALSE;

18
gDP.cpp
View File

@ -348,13 +348,13 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
if (gDP.colorImage.address != address)
{
if (OGL.frameBufferTextures)
if (OGL.frameBufferTextures && address != gDP.depthImageAddress)
{
if (gDP.colorImage.changed)
FrameBuffer_SaveBuffer( gDP.colorImage.address, (u16)gDP.colorImage.size, (u16)gDP.colorImage.width, (u16)gDP.colorImage.height );
//if (gDP.colorImage.changed)
FrameBuffer_SaveBuffer( address, (u16)size, (u16)width, width == VI.width ? (u16)VI.height : 1 );
if (address != gDP.depthImageAddress)
FrameBuffer_RestoreBuffer( address, (u16)size, (u16)width );
//if (address != gDP.depthImageAddress)
//FrameBuffer_RestoreBuffer( address, (u16)size, (u16)width );
//OGL_ClearDepthBuffer();
}
@ -370,7 +370,7 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
gDP.colorImage.format = format;
gDP.colorImage.size = size;
gDP.colorImage.width = width;
gDP.colorImage.address = RSP_SegmentToPhysical( address );
gDP.colorImage.address = address;
#ifdef DEBUG
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "gDPSetColorImage( %s, %s, %i, 0x%08X );\n",
@ -405,8 +405,8 @@ void gDPSetDepthImage( u32 address )
DepthBuffer_SetBuffer( RSP_SegmentToPhysical( address ) );
if (depthBuffer.current->cleared)
OGL_ClearDepthBuffer();
// if (depthBuffer.current->cleared)
// OGL_ClearDepthBuffer();
gDP.depthImageAddress = RSP_SegmentToPhysical( address );
@ -795,7 +795,7 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
OGL_DrawRect( ulx, uly, lrx, lry, (gDP.otherMode.cycleType == G_CYC_FILL) ? &gDP.fillColor.r : &gDP.blendColor.r );
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
if (depthBuffer.top) depthBuffer.top->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = (u32)max( (s32)gDP.colorImage.height, lry );

View File

@ -889,7 +889,7 @@ void gSPTriangle( s32 v0, s32 v1, s32 v2, s32 flag )
DebugMsg( DEBUG_HIGH | DEBUG_ERROR | DEBUG_TRIANGLE, "// Vertex index out of range\n" );
#endif
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
if (depthBuffer.top) depthBuffer.top->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max( gDP.colorImage.height, (u32)gDP.scissor.lry );
}
@ -1652,7 +1652,7 @@ void gSPObjSprite( u32 sp )
OGL_DrawTriangles();
glLoadIdentity();
if (depthBuffer.current) depthBuffer.current->cleared = FALSE;
if (depthBuffer.top) depthBuffer.top->cleared = FALSE;
gDP.colorImage.changed = TRUE;
gDP.colorImage.height = max( gDP.colorImage.height, gDP.scissor.lry );
}