Permalink
Browse files

Upload dynamic lights to uniform buffer.

  • Loading branch information...
gimhael committed Feb 1, 2016
1 parent 6340f23 commit 55ce562698d7b9e656280349bfd2b22a4abfc2fa
@@ -458,6 +458,7 @@ std::string GLShaderManager::BuildGPUShaderText( Str::StringRef mainShaderNa
AddDefine( env, "M_PI", static_cast<float>( M_PI ) );
AddDefine( env, "MAX_SHADOWMAPS", MAX_SHADOWMAPS );
AddDefine( env, "MAX_REF_LIGHTS", MAX_REF_LIGHTS );
float fbufWidthScale = 1.0f / glConfig.vidWidth;
float fbufHeightScale = 1.0f / glConfig.vidHeight;
@@ -2212,6 +2212,36 @@ class u_zFar :
}
};
class u_numLights :
GLUniform1i
{
public:
u_numLights( GLShader *shader ) :
GLUniform1i( shader, "u_numLights" )
{
}
void SetUniform_numLights( int value )
{
this->SetValue( value );
}
};
class u_Lights :
GLUniformBlock
{
public:
u_Lights( GLShader *shader ) :
GLUniformBlock( shader, "u_Lights" )
{
}
void SetUniformBlock_Lights( GLuint buffer )
{
this->SetBuffer( buffer );
}
};
class GLShader_generic :
public GLShader,
public u_ColorTextureMatrix,
@@ -5183,6 +5183,58 @@ const void *RB_StretchPicGradient( const void *data )
return ( const void * )( cmd + 1 );
}
/*
=============
RB_SetupLights
=============
*/
static const void *RB_SetupLights( const void *data )
{
const setupLightsCommand_t *cmd;
int numLights;
GLimp_LogComment( "--- RB_SetupLights ---\n" );
cmd = ( const setupLightsCommand_t * ) data;
if( GLEW_ARB_uniform_buffer_object &&
(numLights = cmd->refdef.numLights) > 0 ) {
shaderLight_t *buffer;
glBindBuffer( GL_UNIFORM_BUFFER, tr.dlightUBO );
buffer = (shaderLight_t *)glMapBufferRange( GL_UNIFORM_BUFFER,
0, numLights * sizeof( shaderLight_t ),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT );
for( int i = 0; i < numLights; i++ ) {
trRefLight_t *light = &cmd->refdef.lights[i];
VectorCopy( light->l.origin, buffer[i].center );
buffer[i].radius = light->l.radius;
VectorCopy( light->l.color, buffer[i].color );
buffer[i].type = Util::ordinal( light->l.rlType );
switch( light->l.rlType ) {
case refLightType_t::RL_PROJ:
VectorCopy( light->l.projTarget,
buffer[i].direction );
buffer[i].angle = cosf( atan2f( VectorLength( light->l.projUp), VectorLength( light->l.projTarget ) ) );
break;
case refLightType_t::RL_DIRECTIONAL:
VectorCopy( light->l.projTarget,
buffer[i].direction );
break;
default:
break;
}
}
glUnmapBuffer( GL_UNIFORM_BUFFER );
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
}
return ( const void * )( cmd + 1 );
}
/*
=============
RB_DrawView
@@ -5600,6 +5652,10 @@ void RB_ExecuteRenderCommands( const void *data )
data = RB_StretchPicGradient( data );
break;
case Util::ordinal(renderCommand_t::RC_SETUP_LIGHTS):
data = RB_SetupLights( data );
break;
case Util::ordinal(renderCommand_t::RC_DRAW_VIEW):
data = RB_DrawView( data );
break;
@@ -248,6 +248,27 @@ void *R_GetCommandBuffer( unsigned bytes )
return cmdList->cmds + cmdList->used - bytes;
}
/*
=============
R_AddSetupLightsCmd
=============
*/
void R_AddSetupLightsCmd()
{
setupLightsCommand_t *cmd;
cmd = (setupLightsCommand_t*) R_GetCommandBuffer( sizeof( *cmd ) );
if ( !cmd )
{
return;
}
cmd->commandId = renderCommand_t::RC_SETUP_LIGHTS;
cmd->refdef = tr.refdef;
}
/*
=============
R_AddDrawViewCmd
@@ -451,6 +451,16 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
int visCounts[ MAX_VISCOUNTS ]; // node needs to be traversed if current
};
// a structure matching the GLSL struct shaderLight in std140 layout
struct shaderLight_t {
vec3_t center;
float radius;
vec3_t color;
float type;
vec3_t direction;
float angle;
};
// a trRefEntity_t has all the information passed in by
// the client game, as well as some locally derived info
struct trRefEntity_t
@@ -2705,6 +2715,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
FBO_t *fbos[ MAX_FBOS ];
GLuint vao;
GLuint dlightUBO;
growList_t vbos;
growList_t ibos;
@@ -3703,6 +3714,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
RC_SCISSORSET,
RC_ROTATED_PIC,
RC_STRETCH_PIC_GRADIENT, // (SA) added
RC_SETUP_LIGHTS,
RC_DRAW_VIEW,
RC_DRAW_BUFFER,
RC_RUN_VISTESTS,
@@ -3800,6 +3812,12 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
viewParms_t viewParms;
};
struct setupLightsCommand_t
{
renderCommand_t commandId;
trRefdef_t refdef;
};
struct runVisTestsCommand_t
{
renderCommand_t commandId;
@@ -3885,6 +3903,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
void R_SyncRenderThread();
void R_AddSetupLightsCmd();
void R_AddDrawViewCmd();
void RE_SetColor( const Color::Color& rgba );
@@ -2495,6 +2495,8 @@ void R_RenderView( viewParms_t *parms )
tr.viewParms.interactions = tr.refdef.interactions + firstInteraction;
tr.viewParms.numInteractions = tr.refdef.numInteractions - firstInteraction;
R_AddSetupLightsCmd();
R_SortDrawSurfs();
R_AddRunVisTestsCmd();
@@ -951,6 +951,13 @@ void R_InitVBOs()
nullptr, GL_STREAM_COPY );
glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );
if( GLEW_ARB_uniform_buffer_object ) {
glGenBuffers( 1, &tr.dlightUBO );
glBindBuffer( GL_UNIFORM_BUFFER, tr.dlightUBO );
glBufferData( GL_UNIFORM_BUFFER, MAX_REF_LIGHTS * sizeof( shaderLight_t ), nullptr, GL_DYNAMIC_DRAW );
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
}
GL_CheckErrors();
}
@@ -1022,6 +1029,11 @@ void R_ShutdownVBOs()
Com_Free_Aligned( tess.vertsBuffer );
Com_Free_Aligned( tess.indexesBuffer );
if( GLEW_ARB_uniform_buffer_object ) {
glDeleteBuffers( 1, &tr.dlightUBO );
tr.dlightUBO = 0;
}
tess.verts = tess.vertsBuffer = nullptr;
tess.indexes = tess.indexesBuffer = nullptr;
}

0 comments on commit 55ce562

Please sign in to comment.