Alternative player-colour rendering, which probably works with lights
This was SVN commit r1792.
This commit is contained in:
parent
6fa79e0247
commit
225446d648
@ -803,90 +803,103 @@ void CRenderer::RenderModelSubmissions()
|
||||
|
||||
if (! playercolor)
|
||||
{
|
||||
|
||||
// pass one through as alpha; transparent textures handled specially by CTransparencyRenderer
|
||||
// (gl_constant means the colour comes from the environment (glColorxf))
|
||||
|
||||
// TODO: ^^^ no it doesn't (I (Philip) think) - gl_primary_color comes from
|
||||
// glColorxf, gl_constant comes from gl_texture_env_color. Unless I'm
|
||||
// mistaken.
|
||||
// (gl_constant means the colour comes from the gl_texture_env_color)
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_CONSTANT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
float color[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
||||
|
||||
// setup client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
// render models
|
||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Render two passes: first, render the unit as normal. Second,
|
||||
// render it again but modulated with the player-colour, using
|
||||
// the alpha channel as a mask.
|
||||
//
|
||||
// Assume the alpha channel is 1-bit, so there's no need for blending.
|
||||
//
|
||||
// This probably ought to be done in a single pass on hardware that
|
||||
// supports register combiners / fragment programs / etc.
|
||||
|
||||
float color[] = { 1.0, 0.0, 0.0, 1.0 };
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_CONSTANT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pass through the alpha to the second texture unit
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// Second texture unit:
|
||||
//
|
||||
// output = texture*alpha + playercolour*(1-alpha)
|
||||
//
|
||||
// where playercolour = previous stage, texture = colour from texture,
|
||||
// alpha = alpha from texture. Do this using GL_INTERPOLATE, which
|
||||
// performs precisely that calculation.
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Set the proper LOD bias
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, m_Options.m_LodBias);
|
||||
|
||||
// Set this texture unit to calculate arg0*arg2 + arg1*(1-arg2)
|
||||
// using 'interpolate'
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
|
||||
|
||||
// arg0 = texture
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
// TODO: GL_TEXTURE0 requires ARB_texture_env_crossbar, or OpenGL 1.4.
|
||||
// Will that be a problem? Can it be avoided?
|
||||
|
||||
// arg1 = player-colour modulated texture, from previous render stage
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
// arg2 = texture alpha, from previous render stage
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// Set the alpha to be 1.0 (obtained from the environment colour)
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
}
|
||||
|
||||
// setup client states
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if (!playercolor)
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
if (playercolor)
|
||||
// TODO: nicer color
|
||||
glColor4f(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// render models
|
||||
if (playercolor)
|
||||
CModelRData::RenderModels(STREAM_POS|STREAM_UV0);
|
||||
else
|
||||
// Render first pass
|
||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
if (! playercolor)
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
// Set up second pass: first texture unit carries on doing texture*lighting,
|
||||
// but passes alpha through inverted; the second texture unit modulates
|
||||
// with the player colour.
|
||||
|
||||
if (playercolor)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// t1 = t0 * playercolor
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_CONSTANT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
|
||||
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
|
||||
|
||||
// Continue passing through alpha from texture
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
|
||||
|
||||
// Only render high-alpha parts
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER,0.5f);
|
||||
|
||||
// Render second pass
|
||||
CModelRData::RenderModels(STREAM_POS|STREAM_COLOR|STREAM_UV0);
|
||||
|
||||
// Restore states
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// switch off client states
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ void CTransparencyRenderer::Render()
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
|
||||
|
||||
// just pass through texture's alpha
|
||||
|
Loading…
Reference in New Issue
Block a user