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:
parent
263f4fc112
commit
a07555546e
|
@ -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, ¤t->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;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ struct DepthBuffer
|
|||
DepthBuffer *higher, *lower;
|
||||
|
||||
u32 address, cleared;
|
||||
GLuint renderbuf;
|
||||
};
|
||||
|
||||
struct DepthBufferInfo
|
||||
|
|
|
@ -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, ¤t->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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
63
OpenGL.cpp
63
OpenGL.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
6
OpenGL.h
6
OpenGL.h
|
@ -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
7
VI.cpp
|
@ -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
18
gDP.cpp
|
@ -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 );
|
||||
|
||||
|
|
4
gSP.cpp
4
gSP.cpp
|
@ -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 );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user