mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-01-23 18:10:42 +00:00
Multisampling
This commit is contained in:
parent
14ffe063ea
commit
36bf6c2d9e
3 changed files with 231 additions and 47 deletions
|
@ -4,22 +4,60 @@
|
||||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_FBO_COLOR_BUFFERS 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Render buffer
|
||||||
|
Can be either a zbuffer, a stencil buffer or a multisampled color buffer
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct fboRenderBuffer_s {
|
typedef struct fboRenderBuffer_s {
|
||||||
GLuint id;
|
GLuint id;
|
||||||
int internalFormat;
|
int internalFormat;
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
qboolean msaa;
|
||||||
} fboRenderBuffer_t;
|
} fboRenderBuffer_t;
|
||||||
|
|
||||||
#define MAX_FBO_COLOR_BUFFERS 8
|
typedef fboRenderBuffer_t fboZBuffer_t;
|
||||||
|
typedef fboRenderBuffer_t fboStencilBuffer_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Color buffer
|
||||||
|
|
||||||
|
If anti-aliased we'll have a texture, a render buffer
|
||||||
|
and two frame buffers needed for the MSAA resolve.
|
||||||
|
|
||||||
|
Otherwise, only the texture is initialized.
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct fboColorBuffer_s {
|
||||||
|
fboRenderBuffer_t *buf;
|
||||||
|
image_t *tex;
|
||||||
|
GLuint fboResolve[2];
|
||||||
|
qboolean dirty;
|
||||||
|
} fboColorBuffer_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Frame buffer
|
||||||
|
|
||||||
|
Has one or more color buffers, an optional zbuffer
|
||||||
|
and an optional stencil buffer
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct fbo_s {
|
typedef struct fbo_s {
|
||||||
GLuint id;
|
GLuint id;
|
||||||
|
|
||||||
int numColorBufs;
|
int numColorBufs;
|
||||||
|
|
||||||
image_t* color[MAX_FBO_COLOR_BUFFERS];
|
fboColorBuffer_t* color[MAX_FBO_COLOR_BUFFERS];
|
||||||
fboZBuffer_t* depth;
|
fboZBuffer_t* depth;
|
||||||
fboStencilBuffer_t* stencil;
|
fboStencilBuffer_t* stencil;
|
||||||
|
|
||||||
|
@ -32,7 +70,14 @@ void R_FBO_InitRenderBuffer(fboRenderBuffer_t* buf)
|
||||||
buf->id = 0;
|
buf->id = 0;
|
||||||
qglGenRenderbuffersEXT(1, &buf->id);
|
qglGenRenderbuffersEXT(1, &buf->id);
|
||||||
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, buf->id);
|
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, buf->id);
|
||||||
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, buf->internalFormat, buf->width, buf->height);
|
if (buf->msaa)
|
||||||
|
{
|
||||||
|
qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, tr.fbo.maxSamples, buf->internalFormat, buf->width, buf->height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, buf->internalFormat, buf->width, buf->height);
|
||||||
|
}
|
||||||
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +90,7 @@ void R_FBO_ReleaseRenderBuffer(fboRenderBuffer_t* buf)
|
||||||
buf->id = 0;
|
buf->id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fboRenderBuffer_t* R_FBO_CreateRenderBuffer(int width, int height, int pixelformat)
|
fboRenderBuffer_t *R_FBO_CreateRenderBuffer(int width, int height, int pixelformat, qboolean msaa)
|
||||||
{
|
{
|
||||||
fboRenderBuffer_t* ret = NULL;
|
fboRenderBuffer_t* ret = NULL;
|
||||||
if (tr.fbo.numRenderBuffers >= ARRAY_SIZE(tr.fbo.renderBuffers))
|
if (tr.fbo.numRenderBuffers >= ARRAY_SIZE(tr.fbo.renderBuffers))
|
||||||
|
@ -60,6 +105,7 @@ fboRenderBuffer_t* R_FBO_CreateRenderBuffer(int width, int height, int pixelform
|
||||||
ret->width = width;
|
ret->width = width;
|
||||||
ret->height = height;
|
ret->height = height;
|
||||||
ret->internalFormat = pixelformat;
|
ret->internalFormat = pixelformat;
|
||||||
|
ret->msaa = (msaa && tr.fbo.maxSamples > 1);
|
||||||
|
|
||||||
R_FBO_InitRenderBuffer(ret);
|
R_FBO_InitRenderBuffer(ret);
|
||||||
|
|
||||||
|
@ -68,38 +114,6 @@ fboRenderBuffer_t* R_FBO_CreateRenderBuffer(int width, int height, int pixelform
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
fboZBuffer_t* R_FBO_CreateZBuffer(int width, int height)
|
|
||||||
{
|
|
||||||
return R_FBO_CreateRenderBuffer(width, height, GL_DEPTH_COMPONENT24);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_FBO_Init(fbo_t* fbo)
|
|
||||||
{
|
|
||||||
memset(fbo, 0, sizeof(*fbo));
|
|
||||||
qglGenFramebuffersEXT(1, &fbo->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_FBO_Release(fbo_t* fbo)
|
|
||||||
{
|
|
||||||
if (fbo->id == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
qglDeleteFramebuffersEXT(1, &fbo->id);
|
|
||||||
fbo->id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_FBO_AddColorBuffer(fbo_t* fbo, image_t* image)
|
|
||||||
{
|
|
||||||
if (fbo->numColorBufs >= ARRAY_SIZE(fbo->color))
|
|
||||||
{
|
|
||||||
ri.Error(ERR_FATAL, "Max FBO color buffers exceeded.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fbo->color[fbo->numColorBufs++] = image;
|
|
||||||
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->id);
|
|
||||||
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, (GLenum)(GL_COLOR_ATTACHMENT0_EXT + fbo->numColorBufs - 1), GL_TEXTURE_2D, image->texnum, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
qboolean R_FBO_Check()
|
qboolean R_FBO_Check()
|
||||||
{
|
{
|
||||||
GLenum status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
GLenum status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||||
|
@ -138,6 +152,10 @@ qboolean R_FBO_Check()
|
||||||
msg = "incomplete read buffer";
|
msg = "incomplete read buffer";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
||||||
|
msg = "mismatched multisample settings";
|
||||||
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||||
msg = "unsupported";
|
msg = "unsupported";
|
||||||
break;
|
break;
|
||||||
|
@ -147,11 +165,106 @@ qboolean R_FBO_Check()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ri.Error(ERR_FATAL, "Bad framebuffer setup for '%s': %s\n", glState.currentFBO->name, msg);
|
ri.Error(ERR_FATAL, "Framebuffer setup error: %s\n", msg);
|
||||||
|
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fboColorBuffer_t *R_FBO_CreateColorBuffer(const char* name, int width, int height, qboolean msaa, qboolean mipmap, int clamp)
|
||||||
|
{
|
||||||
|
if (tr.fbo.numColorBuffers>= ARRAY_SIZE(tr.fbo.colorBuffers))
|
||||||
|
{
|
||||||
|
ri.Error(ERR_FATAL, "Too many FBO color buffers\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qboolean realmsaa = msaa && tr.fbo.maxSamples > 1;
|
||||||
|
image_t *texture = R_CreateImage(name, NULL, width, height, mipmap, qfalse, clamp);
|
||||||
|
fboRenderBuffer_t *buf = realmsaa ? R_FBO_CreateRenderBuffer(width, height, texture->internalFormat, qtrue) : NULL;
|
||||||
|
fboColorBuffer_t *ret = ri.Hunk_Alloc(sizeof(*ret), h_low);
|
||||||
|
|
||||||
|
Com_Memset(ret, 0, sizeof(*ret));
|
||||||
|
|
||||||
|
ret->buf = buf;
|
||||||
|
ret->tex = texture;
|
||||||
|
ret->dirty = qfalse;
|
||||||
|
|
||||||
|
if (realmsaa)
|
||||||
|
{
|
||||||
|
qglGenFramebuffersEXT(2, ret->fboResolve);
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ret->fboResolve[0]);
|
||||||
|
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, ret->buf->id);
|
||||||
|
R_FBO_Check();
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ret->fboResolve[1]);
|
||||||
|
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ret->tex->texnum, 0);
|
||||||
|
R_FBO_Check();
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret->fboResolve[0] = ret->fboResolve[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.fbo.colorBuffers[tr.fbo.numColorBuffers++] = ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_FBO_ReleaseColorBuffer(fboColorBuffer_t* color)
|
||||||
|
{
|
||||||
|
if (color->buf)
|
||||||
|
{
|
||||||
|
qglDeleteFramebuffersEXT(2, color->fboResolve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fboZBuffer_t *R_FBO_CreateZBuffer(int width, int height, qboolean msaa)
|
||||||
|
{
|
||||||
|
return R_FBO_CreateRenderBuffer(width, height, GL_DEPTH_COMPONENT24, msaa);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_FBO_Init(fbo_t* fbo)
|
||||||
|
{
|
||||||
|
memset(fbo, 0, sizeof(*fbo));
|
||||||
|
qglGenFramebuffersEXT(1, &fbo->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_FBO_Release(fbo_t* fbo)
|
||||||
|
{
|
||||||
|
if (fbo->id == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qglDeleteFramebuffersEXT(1, &fbo->id);
|
||||||
|
fbo->id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void R_FBO_AddColorBuffer(fbo_t* fbo, fboColorBuffer_t* color)
|
||||||
|
{
|
||||||
|
GLenum attach;
|
||||||
|
if (fbo->numColorBufs >= ARRAY_SIZE(fbo->color))
|
||||||
|
{
|
||||||
|
ri.Error(ERR_FATAL, "Max FBO color buffers exceeded.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fbo->color[fbo->numColorBufs++] = color;
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->id);
|
||||||
|
attach = GL_COLOR_ATTACHMENT0_EXT + fbo->numColorBufs - 1;
|
||||||
|
if (color->buf)
|
||||||
|
{
|
||||||
|
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attach, GL_RENDERBUFFER_EXT, color->buf->id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attach, GL_TEXTURE_2D, color->tex->texnum, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fbo_t* R_FBO_Bind(fbo_t* fbo)
|
fbo_t* R_FBO_Bind(fbo_t* fbo)
|
||||||
{
|
{
|
||||||
fbo_t* old = glState.currentFBO;
|
fbo_t* old = glState.currentFBO;
|
||||||
|
@ -170,6 +283,13 @@ fbo_t* R_FBO_Bind(fbo_t* fbo)
|
||||||
|
|
||||||
if (fbo)
|
if (fbo)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<fbo->numColorBufs; ++i)
|
||||||
|
{
|
||||||
|
fboColorBuffer_t* color = fbo->color[i];
|
||||||
|
color->dirty = (color->buf != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
R_FBO_Check();
|
R_FBO_Check();
|
||||||
}
|
}
|
||||||
|
@ -179,10 +299,35 @@ fbo_t* R_FBO_Bind(fbo_t* fbo)
|
||||||
|
|
||||||
void R_FBO_BindColorBuffer(fbo_t* fbo, int index)
|
void R_FBO_BindColorBuffer(fbo_t* fbo, int index)
|
||||||
{
|
{
|
||||||
GL_Bind(fbo->color[index]);
|
fboColorBuffer_t* color = fbo->color[index];
|
||||||
|
if (color->dirty)
|
||||||
|
{
|
||||||
|
color->dirty = qfalse;
|
||||||
|
|
||||||
|
// resolve
|
||||||
|
if (color->buf)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
int width = color->buf->width;
|
||||||
|
int height = color->buf->height;
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, color->fboResolve[0]);
|
||||||
|
qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, color->fboResolve[1]);
|
||||||
|
qglBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||||
|
|
||||||
|
if (glState.currentFBO)
|
||||||
|
id = glState.currentFBO->id;
|
||||||
|
else
|
||||||
|
id = 0;
|
||||||
|
|
||||||
|
qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, id);
|
||||||
|
qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL_Bind(color->tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
fbo_t* R_FBO_CreateEx(const char* name, int numColorBuffers, image_t** colorBuffers, fboZBuffer_t* depth, fboStencilBuffer_t* stencil)
|
fbo_t* R_FBO_CreateEx(const char* name, int numColorBuffers, fboColorBuffer_t** colorBuffers, fboZBuffer_t* depth, fboStencilBuffer_t* stencil)
|
||||||
{
|
{
|
||||||
fbo_t* fbo = NULL;
|
fbo_t* fbo = NULL;
|
||||||
|
|
||||||
|
@ -221,45 +366,75 @@ fbo_t* R_FBO_CreateEx(const char* name, int numColorBuffers, image_t** colorBuff
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbo_t* R_FBO_CreateSimple(const char* name, image_t* color, fboZBuffer_t* depth, fboStencilBuffer_t* stencil)
|
fbo_t* R_FBO_CreateSimple(const char* name, fboColorBuffer_t* color, fboZBuffer_t* depth, fboStencilBuffer_t* stencil)
|
||||||
{
|
{
|
||||||
return R_FBO_CreateEx(name, color != NULL, &color, depth, stencil);
|
return R_FBO_CreateEx(name, color != NULL, &color, depth, stencil);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
R_InitFBOs
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
void R_InitFBOs(void)
|
void R_InitFBOs(void)
|
||||||
{
|
{
|
||||||
|
qboolean msaa;
|
||||||
if (!glRefConfig.framebufferObject)
|
if (!glRefConfig.framebufferObject)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ri.Printf(PRINT_ALL, "------- R_InitFBOs -------\n");
|
ri.Printf(PRINT_ALL, "------- R_InitFBOs -------\n");
|
||||||
|
|
||||||
|
if (glRefConfig.framebufferMultisample && glRefConfig.framebufferBlit)
|
||||||
|
{
|
||||||
|
GLint maxSupported = 0;
|
||||||
|
qglGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSupported);
|
||||||
|
tr.fbo.maxSamples = maxSupported < r_ext_multisample->integer ? maxSupported : r_ext_multisample->integer;
|
||||||
|
if (tr.fbo.maxSamples < 2)
|
||||||
|
tr.fbo.maxSamples = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tr.fbo.maxSamples = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("Samples: %d\n", tr.fbo.maxSamples);
|
||||||
|
msaa = tr.fbo.maxSamples > 1;
|
||||||
|
|
||||||
tr.fbo.full[0] = R_FBO_CreateSimple(
|
tr.fbo.full[0] = R_FBO_CreateSimple(
|
||||||
"main",
|
"main",
|
||||||
R_CreateImage("*framebuffer", NULL, glConfig.vidWidth, glConfig.vidHeight, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
R_FBO_CreateColorBuffer("*framebuffer0", glConfig.vidWidth, glConfig.vidHeight, msaa, qfalse, GL_CLAMP_TO_EDGE),
|
||||||
R_FBO_CreateZBuffer(glConfig.vidWidth, glConfig.vidHeight),
|
R_FBO_CreateZBuffer(glConfig.vidWidth, glConfig.vidHeight, msaa),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
tr.fbo.full[1] = R_FBO_CreateSimple(
|
tr.fbo.full[1] = R_FBO_CreateSimple(
|
||||||
"postprocess",
|
"postprocess",
|
||||||
R_CreateImage("*framebuffer", NULL, glConfig.vidWidth, glConfig.vidHeight, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
R_FBO_CreateColorBuffer("*framebuffer1", glConfig.vidWidth, glConfig.vidHeight, msaa, qfalse, GL_CLAMP_TO_EDGE),
|
||||||
tr.fbo.full[0]->depth,
|
tr.fbo.full[0]->depth,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
tr.fbo.quarter[0] = R_FBO_CreateSimple(
|
tr.fbo.quarter[0] = R_FBO_CreateSimple(
|
||||||
"quarter0",
|
"quarter0",
|
||||||
R_CreateImage("*quarterBuffer0", NULL, glConfig.vidWidth/2, glConfig.vidHeight/2, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
R_FBO_CreateColorBuffer("*quarterBuffer0", glConfig.vidWidth/2, glConfig.vidHeight/2, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
tr.fbo.quarter[1] = R_FBO_CreateSimple(
|
tr.fbo.quarter[1] = R_FBO_CreateSimple(
|
||||||
"quarter1",
|
"quarter1",
|
||||||
R_CreateImage("*quarterBuffer1", NULL, glConfig.vidWidth/2, glConfig.vidHeight/2, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
R_FBO_CreateColorBuffer("*quarterBuffer1", glConfig.vidWidth/2, glConfig.vidHeight/2, qfalse, qfalse, GL_CLAMP_TO_EDGE),
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
ri.Printf(PRINT_DEVELOPER, "Created %d FBOs\n", tr.fbo.numFBOs);
|
ri.Printf(PRINT_DEVELOPER, "Created %d FBOs\n", tr.fbo.numFBOs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
R_ShutDownFBOs
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
void R_ShutDownFBOs(void)
|
void R_ShutDownFBOs(void)
|
||||||
{
|
{
|
||||||
if (!glRefConfig.framebufferObject)
|
if (!glRefConfig.framebufferObject)
|
||||||
|
@ -272,6 +447,9 @@ void R_ShutDownFBOs(void)
|
||||||
while (tr.fbo.numRenderBuffers>0)
|
while (tr.fbo.numRenderBuffers>0)
|
||||||
R_FBO_ReleaseRenderBuffer(tr.fbo.renderBuffers[--tr.fbo.numRenderBuffers]);
|
R_FBO_ReleaseRenderBuffer(tr.fbo.renderBuffers[--tr.fbo.numRenderBuffers]);
|
||||||
|
|
||||||
|
while (tr.fbo.numColorBuffers>0)
|
||||||
|
R_FBO_ReleaseColorBuffer(tr.fbo.colorBuffers[--tr.fbo.numColorBuffers]);
|
||||||
|
|
||||||
while (tr.fbo.numFBOs>0)
|
while (tr.fbo.numFBOs>0)
|
||||||
R_FBO_Release(tr.fbo.fbos[--tr.fbo.numFBOs]);
|
R_FBO_Release(tr.fbo.fbos[--tr.fbo.numFBOs]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,7 @@ typedef struct IBO_s
|
||||||
} IBO_t;
|
} IBO_t;
|
||||||
|
|
||||||
typedef struct fboRenderBuffer_s fboRenderBuffer_t;
|
typedef struct fboRenderBuffer_s fboRenderBuffer_t;
|
||||||
typedef fboRenderBuffer_t fboZBuffer_t;
|
typedef struct fboColorBuffer_s fboColorBuffer_t;
|
||||||
typedef fboRenderBuffer_t fboStencilBuffer_t;
|
|
||||||
typedef struct fbo_s fbo_t;
|
typedef struct fbo_s fbo_t;
|
||||||
|
|
||||||
fbo_t *R_FBO_Bind(fbo_t* fbo);
|
fbo_t *R_FBO_Bind(fbo_t* fbo);
|
||||||
|
@ -2224,6 +2223,8 @@ typedef struct {
|
||||||
} backEndState_t;
|
} backEndState_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int maxSamples;
|
||||||
|
|
||||||
fbo_t *full[2]; // full resolution, shared zbuffer
|
fbo_t *full[2]; // full resolution, shared zbuffer
|
||||||
fbo_t *quarter[2]; // quarter resolution, no zbuffer
|
fbo_t *quarter[2]; // quarter resolution, no zbuffer
|
||||||
|
|
||||||
|
@ -2232,6 +2233,9 @@ typedef struct {
|
||||||
|
|
||||||
int numRenderBuffers;
|
int numRenderBuffers;
|
||||||
fboRenderBuffer_t *renderBuffers[1024];
|
fboRenderBuffer_t *renderBuffers[1024];
|
||||||
|
|
||||||
|
int numColorBuffers;
|
||||||
|
fboColorBuffer_t *colorBuffers[1024];
|
||||||
} fboState_t;
|
} fboState_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -425,6 +425,8 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
|
||||||
depthbits = r_depthbits->value;
|
depthbits = r_depthbits->value;
|
||||||
stencilbits = r_stencilbits->value;
|
stencilbits = r_stencilbits->value;
|
||||||
samples = r_ext_multisample->value;
|
samples = r_ext_multisample->value;
|
||||||
|
if (r_ext_framebuffer_object->integer)
|
||||||
|
samples = 0;
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue