Doom 3 engine release and game code
Moderator: InsideQC Admins
Re: Doom 3 engine release and game code
Its quite ok though some parts may seem a bit bloated but in general it works as it should.
D3 has its own physics code so might be easier than ODE but i cant say... got code for a version with glsl renderer which works quite ok though it cannot do stuff in the material shaders yet. If someone adds
the remaining code (not a ton of work but i dont dare touch anything else after i got it working lol) you can use it with more modern shading techniques.
Theres a hexen2 total port out there which looks very promissing, maybe something to look at for clues ?
D3 has its own physics code so might be easier than ODE but i cant say... got code for a version with glsl renderer which works quite ok though it cannot do stuff in the material shaders yet. If someone adds
the remaining code (not a ton of work but i dont dare touch anything else after i got it working lol) you can use it with more modern shading techniques.
Theres a hexen2 total port out there which looks very promissing, maybe something to look at for clues ?
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
I have my reservations about GLSL backend. It's been 5 month and it seems all projects are in a coma. Plus Doom 3 shipped with ARB shaders, it's guaranteed to work. Unless really skilled programmer will get to GLSL backend and finish it, and then test it through, I wouldn't trust it for production.
What modern techniques Doom 3 can't handle ?
Hexen mod using stock Doom 3. There is nothing different about their rendering. Or is there? But I will look into their scripting ofc.
What modern techniques Doom 3 can't handle ?
Hexen mod using stock Doom 3. There is nothing different about their rendering. Or is there? But I will look into their scripting ofc.
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Re: Doom 3 engine release and game code
things like ssao
the arb render path does not allow accessing some of the stuff needed for it though so currently it uses a hack (sickmod). it looks dreadfull outside though cause it bugs up the sky.
might be fixable in arb. the glsl renderer works just fine but my version defaults to the arb path so to test it you need to put r_renderer glsl in the console, only thing its lacking is a function for parsing the material shaders currently it only does the render part but allmost all the code needed is there.
nothing different about the hexen mods renderer
but there scripting might be worth a look indeed.
code from the glsl renderer below.
might be fixable in arb. the glsl renderer works just fine but my version defaults to the arb path so to test it you need to put r_renderer glsl in the console, only thing its lacking is a function for parsing the material shaders currently it only does the render part but allmost all the code needed is there.
nothing different about the hexen mods renderer
code from the glsl renderer below.
- Code: Select all
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "tr_local.h"
shaderProgram_t interactionShader = {-1};
shaderProgram_t ambientInteractionShader = {-1};
shaderProgram_t stencilShadowShader = {-1};
/*
=========================================================================================
GENERAL INTERACTION RENDERING
=========================================================================================
*/
/*
====================
GL_SelectTextureNoClient
====================
*/
static void GL_SelectTextureNoClient( int unit ) {
backEnd.glState.currenttmu = unit;
qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
RB_LogComment( "glActiveTextureARB( %i )\n", unit );
}
/*
==================
RB_GLSL_DrawInteraction
==================
*/
static void RB_GLSL_DrawInteraction( const drawInteraction_t *din ) {
// load all the shader parameters
if ( din->ambientLight ) {
qglUniform4fvARB( ambientInteractionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
qglUniform4fvARB( ambientInteractionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
static const float negOne[4] = { -1, -1, -1, -1 };
switch ( din->vertexColor ) {
case SVC_IGNORE:
qglUniform4fARB( ambientInteractionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] );
qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] );
break;
case SVC_MODULATE:
qglUniform4fARB( ambientInteractionShader.colorModulate, one[0], one[1], one[2], one[3] );
qglUniform4fARB( ambientInteractionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] );
break;
case SVC_INVERSE_MODULATE:
qglUniform4fARB( ambientInteractionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] );
qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] );
break;
}
// set the constant color
qglUniform4fvARB( ambientInteractionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
} else {
qglUniform4fvARB( interactionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
qglUniform4fvARB( interactionShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() );
qglUniform4fvARB( interactionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
qglUniform4fvARB( interactionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
qglUniform4fvARB( interactionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
qglUniform4fvARB( interactionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
qglUniform4fvARB( interactionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
qglUniform4fvARB( interactionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
qglUniform4fvARB( interactionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
qglUniform4fvARB( interactionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );
qglUniform4fvARB( interactionShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() );
qglUniform4fvARB( interactionShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() );
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
static const float negOne[4] = { -1, -1, -1, -1 };
switch ( din->vertexColor ) {
case SVC_IGNORE:
qglUniform4fARB( interactionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] );
qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] );
break;
case SVC_MODULATE:
qglUniform4fARB( interactionShader.colorModulate, one[0], one[1], one[2], one[3] );
qglUniform4fARB( interactionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] );
break;
case SVC_INVERSE_MODULATE:
qglUniform4fARB( interactionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] );
qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] );
break;
}
// set the constant colors
qglUniform4fvARB( interactionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
qglUniform4fvARB( interactionShader.specularColor, 1, din->specularColor.ToFloatPtr() );
}
// set the textures
// texture 0 will be the per-surface bump map
GL_SelectTextureNoClient( 0 );
din->bumpImage->Bind();
// texture 1 will be the light falloff texture
GL_SelectTextureNoClient( 1 );
din->lightFalloffImage->Bind();
// texture 2 will be the light projection texture
GL_SelectTextureNoClient( 2 );
din->lightImage->Bind();
// texture 3 is the per-surface diffuse map
GL_SelectTextureNoClient( 3 );
din->diffuseImage->Bind();
if ( !din->ambientLight ) {
// texture 4 is the per-surface specular map
GL_SelectTextureNoClient( 4 );
din->specularImage->Bind();
}
// draw it
RB_DrawElementsWithCounters( din->surf->geo );
}
/*
=============
RB_GLSL_CreateDrawInteractions
=============
*/
static void RB_GLSL_CreateDrawInteractions( const drawSurf_t *surf ) {
if ( !surf ) {
return;
}
// perform setup here that will be constant for all interactions
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );
// bind the vertex and fragment program
if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
if (ambientInteractionShader.program == -1)
qglUseProgramObjectARB( 0 );
else
qglUseProgramObjectARB( ambientInteractionShader.program );
} else {
if (interactionShader.program == -1)
qglUseProgramObjectARB( 0 );
else
qglUseProgramObjectARB( interactionShader.program );
}
// enable the vertex arrays
qglEnableVertexAttribArrayARB( 8 );
qglEnableVertexAttribArrayARB( 9 );
qglEnableVertexAttribArrayARB( 10 );
qglEnableVertexAttribArrayARB( 11 );
qglEnableClientState( GL_COLOR_ARRAY );
for ( /**/ ; surf ; surf=surf->nextOnLight ) {
// perform setup here that will not change over multiple interaction passes
// set the vertex pointers
idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color );
qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
// set model matrix
if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
qglUniformMatrix4fvARB( ambientInteractionShader.modelMatrix, 1, false, surf->space->modelMatrix );
} else {
qglUniformMatrix4fvARB( interactionShader.modelMatrix, 1, false, surf->space->modelMatrix );
}
// this may cause RB_GLSL_DrawInteraction to be executed multiple
// times with different colors and images if the surface or light have multiple layers
RB_CreateSingleDrawInteractions( surf, RB_GLSL_DrawInteraction );
}
qglDisableVertexAttribArrayARB( 8 );
qglDisableVertexAttribArrayARB( 9 );
qglDisableVertexAttribArrayARB( 10 );
qglDisableVertexAttribArrayARB( 11 );
qglDisableClientState( GL_COLOR_ARRAY );
// disable features
GL_SelectTextureNoClient( 4 );
globalImages->BindNull();
GL_SelectTextureNoClient( 3 );
globalImages->BindNull();
GL_SelectTextureNoClient( 2 );
globalImages->BindNull();
GL_SelectTextureNoClient( 1 );
globalImages->BindNull();
backEnd.glState.currenttmu = -1;
GL_SelectTexture( 0 );
qglUseProgramObjectARB( 0 );
}
/*
==================
RB_GLSL_DrawInteractions
==================
*/
void RB_GLSL_DrawInteractions( void ) {
viewLight_t *vLight;
GL_SelectTexture( 0 );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
//
// for each light, perform adding and shadowing
//
for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
backEnd.vLight = vLight;
// do fogging later
if ( vLight->lightShader->IsFogLight() ) {
continue;
}
if ( vLight->lightShader->IsBlendLight() ) {
continue;
}
// if there are no interactions, get out!
if ( !vLight->localInteractions && !vLight->globalInteractions && !vLight->translucentInteractions ) {
continue;
}
// clear the stencil buffer if needed
if ( vLight->globalShadows || vLight->localShadows ) {
backEnd.currentScissor = vLight->scissorRect;
if ( r_useScissor.GetBool() ) {
qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
}
qglClear( GL_STENCIL_BUFFER_BIT );
} else {
// no shadows, so no need to read or write the stencil buffer
// we might in theory want to use GL_ALWAYS instead of disabling
// completely, to satisfy the invarience rules
qglStencilFunc( GL_ALWAYS, 128, 255 );
}
if ( r_useShadowVertexProgram.GetBool() ) {
qglUseProgramObjectARB( stencilShadowShader.program );
RB_StencilShadowPass( vLight->globalShadows );
RB_GLSL_CreateDrawInteractions( vLight->localInteractions );
qglUseProgramObjectARB( stencilShadowShader.program );
RB_StencilShadowPass( vLight->localShadows );
RB_GLSL_CreateDrawInteractions( vLight->globalInteractions );
qglUseProgramObjectARB( 0 ); // if there weren't any globalInteractions, it would have stayed on
} else {
RB_StencilShadowPass( vLight->globalShadows );
RB_GLSL_CreateDrawInteractions( vLight->localInteractions );
RB_StencilShadowPass( vLight->localShadows );
RB_GLSL_CreateDrawInteractions( vLight->globalInteractions );
}
// translucent surfaces never get stencil shadowed
if ( r_skipTranslucent.GetBool() ) {
continue;
}
qglStencilFunc( GL_ALWAYS, 128, 255 );
backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
RB_GLSL_CreateDrawInteractions( vLight->translucentInteractions );
backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
}
// disable stencil shadow test
qglStencilFunc( GL_ALWAYS, 128, 255 );
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
}
//===================================================================================
/*
=================
R_LoadGLSLShader
loads GLSL vertex or fragment shaders
=================
*/
bool R_LoadGLSLShader( const char *name, shaderProgram_t *shaderProgram, GLenum type ) {
idStr fullPath = "glshaders/";
fullPath += name;
char *fileBuffer;
char *buffer;
common->Printf( "%s", fullPath.c_str() );
// load the program even if we don't support it, so
// fs_copyfiles can generate cross-platform data dumps
fileSystem->ReadFile( fullPath.c_str(), (void **)&fileBuffer, NULL );
if ( !fileBuffer ) {
common->Printf( ": File not found\n" );
return false;
}
// copy to stack memory and free
buffer = (char *)_alloca( strlen( fileBuffer ) + 1 );
strcpy( buffer, fileBuffer );
fileSystem->FreeFile( fileBuffer );
if ( !glConfig.isInitialized ) {
return false;
}
GLuint shader;
switch( type ) {
case GL_VERTEX_SHADER_ARB:
// create vertex shader
if (shaderProgram->vertexShader != -1) {
qglDeleteShader(shaderProgram->vertexShader);
}
shaderProgram->vertexShader = -1;
shader = qglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
qglShaderSourceARB( shader, 1, (const GLcharARB **)&buffer, 0 );
qglCompileShaderARB( shader );
break;
case GL_FRAGMENT_SHADER_ARB:
// create fragment shader
if (shaderProgram->fragmentShader != -1) {
qglDeleteShader(shaderProgram->fragmentShader);
}
shaderProgram->fragmentShader = -1;
shader = qglCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
qglShaderSourceARB( shader, 1, (const GLcharARB **)&buffer, 0 );
qglCompileShaderARB( shader );
break;
default:
common->Printf( "R_LoadGLSLShader: no type\n" );
return false;
}
GLint logLength;
qglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 1) {
GLchar *log = (GLchar *)malloc(logLength);
qglGetShaderInfoLog(shader, logLength, &logLength, log);
common->Printf((const char*)log);
free(log);
}
GLint status;
qglGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
qglDeleteShader(shader);
return false;
}
switch( type ) {
case GL_VERTEX_SHADER_ARB:
shaderProgram->vertexShader = shader;
break;
case GL_FRAGMENT_SHADER_ARB:
shaderProgram->fragmentShader = shader;
break;
}
common->Printf( "\n" );
return true;
}
/*
=================
R_LinkGLSLShader
links the GLSL vertex and fragment shaders together to form a GLSL program
=================
*/
bool R_LinkGLSLShader( shaderProgram_t *shaderProgram, bool needsAttributes ) {
GLint linked;
shaderProgram->program = qglCreateProgramObjectARB( );
qglAttachObjectARB( shaderProgram->program, shaderProgram->vertexShader );
qglAttachObjectARB( shaderProgram->program, shaderProgram->fragmentShader );
if( needsAttributes ) {
qglBindAttribLocationARB( shaderProgram->program, 8, "attr_TexCoord" );
qglBindAttribLocationARB( shaderProgram->program, 9, "attr_Tangent" );
qglBindAttribLocationARB( shaderProgram->program, 10, "attr_Bitangent" );
qglBindAttribLocationARB( shaderProgram->program, 11, "attr_Normal" );
}
qglLinkProgramARB( shaderProgram->program );
qglGetObjectParameterivARB( shaderProgram->program, GL_OBJECT_LINK_STATUS_ARB, &linked );
if( !linked ) {
common->Printf( "R_LinkGLSLShader: program failed to link\n" );
return false;
}
return true;
}
/*
=================
R_ValidateGLSLShader
makes sure GLSL shader is valid
=================
*/
bool R_ValidateGLSLShader( shaderProgram_t *shaderProgram ) {
GLint validProgram;
/* use pointers and avoid a load of the same crap */
if (shaderProgram->fragmentShader == -1 || shaderProgram->vertexShader == -1) {
if (shaderProgram->fragmentShader != -1) {
qglDeleteShader(shaderProgram->fragmentShader);
}
if (shaderProgram->vertexShader != -1) {
qglDeleteShader(shaderProgram->vertexShader);
}
shaderProgram->fragmentShader = -1;
shaderProgram->vertexShader = -1;
return false;
}
qglValidateProgramARB( shaderProgram->program );
qglGetObjectParameterivARB( shaderProgram->program, GL_OBJECT_VALIDATE_STATUS_ARB, &validProgram );
if( !validProgram ) {
common->Printf( "R_ValidateGLSLShader: program invalid\n" );
return false;
}
return true;
}
/*
=================
RB_GLSL_InitShaders
=================
*/
static bool RB_GLSL_InitShaders( void ) {
// load interation shaders
R_LoadGLSLShader( "interaction.vs", &interactionShader, GL_VERTEX_SHADER_ARB );
R_LoadGLSLShader( "interaction.fs", &interactionShader, GL_FRAGMENT_SHADER_ARB );
if ( !R_LinkGLSLShader( &interactionShader, true ) && !R_ValidateGLSLShader( &interactionShader ) ) {
common->Printf( "GLSL interactionShader failed to init.\n" );
return false;
} else {
// set uniform locations
interactionShader.u_normalTexture = qglGetUniformLocationARB( interactionShader.program, "u_normalTexture" );
interactionShader.u_lightFalloffTexture = qglGetUniformLocationARB( interactionShader.program, "u_lightFalloffTexture" );
interactionShader.u_lightProjectionTexture = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionTexture" );
interactionShader.u_diffuseTexture = qglGetUniformLocationARB( interactionShader.program, "u_diffuseTexture" );
interactionShader.u_specularTexture = qglGetUniformLocationARB( interactionShader.program, "u_specularTexture" );
interactionShader.modelMatrix = qglGetUniformLocationARB( interactionShader.program, "u_modelMatrix" );
interactionShader.localLightOrigin = qglGetUniformLocationARB( interactionShader.program, "u_lightOrigin" );
interactionShader.localViewOrigin = qglGetUniformLocationARB( interactionShader.program, "u_viewOrigin" );
interactionShader.lightProjectionS = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionS" );
interactionShader.lightProjectionT = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionT" );
interactionShader.lightProjectionQ = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionQ" );
interactionShader.lightFalloff = qglGetUniformLocationARB( interactionShader.program, "u_lightFalloff" );
interactionShader.bumpMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_bumpMatrixS" );
interactionShader.bumpMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_bumpMatrixT" );
interactionShader.diffuseMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_diffuseMatrixS" );
interactionShader.diffuseMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_diffuseMatrixT" );
interactionShader.specularMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_specularMatrixS" );
interactionShader.specularMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_specularMatrixT" );
interactionShader.colorModulate = qglGetUniformLocationARB( interactionShader.program, "u_colorModulate" );
interactionShader.colorAdd = qglGetUniformLocationARB( interactionShader.program, "u_colorAdd" );
interactionShader.diffuseColor = qglGetUniformLocationARB( interactionShader.program, "u_diffuseColor" );
interactionShader.specularColor = qglGetUniformLocationARB( interactionShader.program, "u_specularColor" );
// set texture locations
qglUseProgramObjectARB( interactionShader.program );
qglUniform1iARB( interactionShader.u_normalTexture, 0 );
qglUniform1iARB( interactionShader.u_lightFalloffTexture, 1 );
qglUniform1iARB( interactionShader.u_lightProjectionTexture, 2 );
qglUniform1iARB( interactionShader.u_diffuseTexture, 3 );
qglUniform1iARB( interactionShader.u_specularTexture, 4 );
qglUseProgramObjectARB( 0 );
}
// load ambient interation shaders
R_LoadGLSLShader( "ambientInteraction.vs", &ambientInteractionShader, GL_VERTEX_SHADER_ARB );
R_LoadGLSLShader( "ambientInteraction.fs", &ambientInteractionShader, GL_FRAGMENT_SHADER_ARB );
if ( !R_LinkGLSLShader( &ambientInteractionShader, true ) && !R_ValidateGLSLShader( &ambientInteractionShader ) ) {
common->Printf( "GLSL ambientInteractionShader failed to init.\n" );
return false;
} else {
// set uniform locations
ambientInteractionShader.u_normalTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_normalTexture" );
ambientInteractionShader.u_lightFalloffTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightFalloffTexture" );
ambientInteractionShader.u_lightProjectionTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionTexture" );
ambientInteractionShader.u_diffuseTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseTexture" );
ambientInteractionShader.modelMatrix = qglGetUniformLocationARB( ambientInteractionShader.program, "u_modelMatrix" );
ambientInteractionShader.localLightOrigin = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightOrigin" );
ambientInteractionShader.lightProjectionS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionS" );
ambientInteractionShader.lightProjectionT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionT" );
ambientInteractionShader.lightProjectionQ = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionQ" );
ambientInteractionShader.lightFalloff = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightFalloff" );
ambientInteractionShader.bumpMatrixS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_bumpMatrixS" );
ambientInteractionShader.bumpMatrixT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_bumpMatrixT" );
ambientInteractionShader.diffuseMatrixS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseMatrixS" );
ambientInteractionShader.diffuseMatrixT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseMatrixT" );
ambientInteractionShader.colorModulate = qglGetUniformLocationARB( ambientInteractionShader.program, "u_colorModulate" );
ambientInteractionShader.colorAdd = qglGetUniformLocationARB( ambientInteractionShader.program, "u_colorAdd" );
ambientInteractionShader.diffuseColor = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseColor" );
// set texture locations
qglUseProgramObjectARB( ambientInteractionShader.program );
qglUniform1iARB( ambientInteractionShader.u_normalTexture, 0 );
qglUniform1iARB( ambientInteractionShader.u_lightFalloffTexture, 1 );
qglUniform1iARB( ambientInteractionShader.u_lightProjectionTexture, 2 );
qglUniform1iARB( ambientInteractionShader.u_diffuseTexture, 3 );
qglUseProgramObjectARB( 0 );
}
// load stencil shadow extrusion shaders
R_LoadGLSLShader( "stencilshadow.vs", &stencilShadowShader, GL_VERTEX_SHADER_ARB );
R_LoadGLSLShader( "stencilshadow.fs", &stencilShadowShader, GL_FRAGMENT_SHADER_ARB );
if ( !R_LinkGLSLShader( &stencilShadowShader, false ) && !R_ValidateGLSLShader( &stencilShadowShader ) ) {
common->Printf( "GLSL stencilShadowShader failed to init.\n" );
return false;
} else {
// set uniform locations
stencilShadowShader.localLightOrigin = qglGetUniformLocationARB( stencilShadowShader.program, "u_lightOrigin" );
}
return true;
}
/*
==================
R_ReloadGLSLShaders_f
==================
*/
void R_ReloadGLSLShaders_f( const idCmdArgs &args ) {
glConfig.allowGLSLPath = false;
common->Printf( "----- R_ReloadGLSLShaders -----\n" );
if ( !glConfig.GLSLAvailable ) {
common->Printf( "Not available.\n" );
return;
} else if ( !RB_GLSL_InitShaders() ) {
common->Printf( "GLSL shaders failed to reload.\n" );
return;
}
common->Printf( "Available.\n" );
common->Printf( "-------------------------------\n" );
// see if we messed anything up
GL_CheckErrors();
glConfig.allowGLSLPath = true;
}
/*
==================
R_GLSL_Init
==================
*/
void R_GLSL_Init( void ) {
glConfig.allowGLSLPath = false;
common->Printf( "---------- R_GLSL_Init -----------\n" );
if ( !glConfig.GLSLAvailable ) {
common->Printf( "Not available.\n" );
return;
} else if ( !RB_GLSL_InitShaders() ) {
common->Printf( "GLSL shaders failed to init.\n" );
return;
}
common->Printf( "Available.\n" );
common->Printf( "---------------------------------\n" );
// see if we messed anything up
GL_CheckErrors();
glConfig.allowGLSLPath = true;
}
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
Ahh, you are that guy they talk about on #iodoom3
Cool stuff. What's stopping you from hooking up GLSL backport to material system ? (and why is it needed)
Also, I am trying to understand what can be done with scripting without messing with C++ game code? And where to get documentation for C++ code of Doom 3 to be able to figure out how to add new gameplay elements?
Also, I am trying to understand what can be done with scripting without messing with C++ game code? And where to get documentation for C++ code of Doom 3 to be able to figure out how to add new gameplay elements?
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Re: Doom 3 engine release and game code
actually im not i just did some more work on his glsl backend
the problem is that the material shaders uses a function to parse the vertex and fragment program names out of the game scripts. arb2 shaders are easy cause the have an identifier at top but glsl shaders dont so
im not sure how to go about that one.
heres the function from the arb2 path.
it loads shaders like this
the problem is that the material shaders uses a function to parse the vertex and fragment program names out of the game scripts. arb2 shaders are easy cause the have an identifier at top but glsl shaders dont so
im not sure how to go about that one.
heres the function from the arb2 path.
- Code: Select all
/*
==================
R_FindARBProgram
Returns a GL identifier that can be bound to the given target, parsing
a text file if it hasn't already been loaded.
==================
*/
int R_FindARBProgram( GLenum target, const char *program ) {
int i;
idStr stripped = program;
stripped.StripFileExtension();
// see if it is already loaded
for ( i = 0 ; progs[i].name[0] ; i++ ) {
if ( progs[i].target != target ) {
continue;
}
idStr compare = progs[i].name;
compare.StripFileExtension();
if ( !idStr::Icmp( stripped.c_str(), compare.c_str() ) ) {
return progs[i].ident;
}
}
if ( i == MAX_GLPROGS ) {
common->Error( "R_FindARBProgram: MAX_GLPROGS" );
}
// add it to the list and load it
progs[i].ident = (program_t)0; // will be gen'd by R_LoadARBProgram
progs[i].target = target;
strncpy( progs[i].name, program, sizeof( progs[i].name ) - 1 );
R_LoadARBProgram( i );
return progs[i].ident;
}
it loads shaders like this
- Code: Select all
if ( !token.Icmp( "program" ) ) {
if ( src.ReadTokenOnLine( &token ) ) {
newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() );
newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() );
}
continue;
}
if ( !token.Icmp( "fragmentProgram" ) ) {
if ( src.ReadTokenOnLine( &token ) ) {
newStage.fragmentProgram = R_FindARBProgram( GL_FRAGMENT_PROGRAM_ARB, token.c_str() );
}
continue;
}
if ( !token.Icmp( "vertexProgram" ) ) {
if ( src.ReadTokenOnLine( &token ) ) {
newStage.vertexProgram = R_FindARBProgram( GL_VERTEX_PROGRAM_ARB, token.c_str() );
}
continue;
}
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
shot from the hexen mod with glsl

shot from the in hell mod with glsl


shot from the in hell mod with glsl

Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
Oh man, I have no clue about coding
(besides basic QuakeC stuff)
Btw, I don't know why people care for SSAO.. It's slow and doesn't add much to the game.
I am looking for someone who can make NPR ARB shader instead (ink outlines are not possible in Doom 3 as there is no way to access depth buffer, so I guess I can live with NPR surface shading / lighting only). I am after Vakyria Chrinicles / Prince of Persia 2008 / Ghost in the Shell look. Would you be able to create something like that?
Btw, I don't know why people care for SSAO.. It's slow and doesn't add much to the game.
I am looking for someone who can make NPR ARB shader instead (ink outlines are not possible in Doom 3 as there is no way to access depth buffer, so I guess I can live with NPR surface shading / lighting only). I am after Vakyria Chrinicles / Prince of Persia 2008 / Ghost in the Shell look. Would you be able to create something like that?
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Re: Doom 3 engine release and game code
should be possible if i can finish the glsl backend but im also learning so might take me a while
biggest thing on the todo is getting the material shader parser working as without it its impossible atleast with glsl (the glsl backend only does the basic render and you cannot mix arb2 with glsl unfortunatly).
the arb2 backend should be able to do it though.
ssao has the same problem cannot access the depth buffer though it might be possible to fix that now that the source is released.
biggest thing on the todo is getting the material shader parser working as without it its impossible atleast with glsl (the glsl backend only does the basic render and you cannot mix arb2 with glsl unfortunatly).
the arb2 backend should be able to do it though.
ssao has the same problem cannot access the depth buffer though it might be possible to fix that now that the source is released.
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
an outline or cellshading mod for doom3 can be downloaded from here
http://doom3.filefront.com/file/Rotosco ... 4#Download
an upcomming backend for glsl in the works and an explanation why the arb2 backend is a problem here -> http://www.phoronix.com/scan.php?page=n ... px=MTA5MTI
an upcomming backend for glsl in the works and an explanation why the arb2 backend is a problem here -> http://www.phoronix.com/scan.php?page=n ... px=MTA5MTI
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
There is no clear indication to why GLSL has to be implemented. I bet rewriting ARB shaders to replace the original ones would be way less work.
That outline and cel shading is exactly what I don't want - it look bad
My point is that ARB backend just works. It's been tested for years and that means you have stable platform for the development already. Doom 3 won't become next CryEngine so I don't really understand why people are after more advanced rendering features. Anyhow, still wondering if you could create ARB shaders for manga looks
That outline and cel shading is exactly what I don't want - it look bad
My point is that ARB backend just works. It's been tested for years and that means you have stable platform for the development already. Doom 3 won't become next CryEngine so I don't really understand why people are after more advanced rendering features. Anyhow, still wondering if you could create ARB shaders for manga looks
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Re: Doom 3 engine release and game code
What's really needed is a translator from ARB to GLSL so that it can handle any arbitrary material shaders. Otherwise you'd need to flip between the two different types of shader at runtime, which is likely supported OK but I have no idea how well it would run.
Such a translator should be easy enough to write - you just take an ARB instruction, grab it's params and generate a line of GLSL. Buffer up program.env/program.local and vertex.attrib values used while doing so, then pre-pend them as uniforms and attributes. output.whatever in the VS stage and input.whatever in the FS stage become attributes for passing between the shaders, output.whatever in the FS stage is your final output. Mostly code-grinding.
ARB shaders are not difficult to write but are sadly limited. You've got a limited amount of program.env and program.local slots (some drivers may extend them in line with more modern hardware capabilities), you can't use modern features such as branching and texture arrays (the latter in particular are great for saving on state changes - you could see all textures used for a Doom 3 material going into a single texture array), and a modern implementation of the renderer would use a geometry shader and transform feedback for generating shadow volumes instead of doing so on the CPU - again, more performance but not possible with ARB shaders.
You can do instancing with ARB shaders but you don't have access to gl_VertexID/gl_InstanceID which can come in really handy at times (I use the D3D11 variants in DirectQ for a few things in the particle system).
Otherwise it's more instructions and more generalised shading capabilities - such as vertex texture fetch, for example, which is also really really useful.
Such a translator should be easy enough to write - you just take an ARB instruction, grab it's params and generate a line of GLSL. Buffer up program.env/program.local and vertex.attrib values used while doing so, then pre-pend them as uniforms and attributes. output.whatever in the VS stage and input.whatever in the FS stage become attributes for passing between the shaders, output.whatever in the FS stage is your final output. Mostly code-grinding.
ARB shaders are not difficult to write but are sadly limited. You've got a limited amount of program.env and program.local slots (some drivers may extend them in line with more modern hardware capabilities), you can't use modern features such as branching and texture arrays (the latter in particular are great for saving on state changes - you could see all textures used for a Doom 3 material going into a single texture array), and a modern implementation of the renderer would use a geometry shader and transform feedback for generating shadow volumes instead of doing so on the CPU - again, more performance but not possible with ARB shaders.
You can do instancing with ARB shaders but you don't have access to gl_VertexID/gl_InstanceID which can come in really handy at times (I use the D3D11 variants in DirectQ for a few things in the particle system).
Otherwise it's more instructions and more generalised shading capabilities - such as vertex texture fetch, for example, which is also really really useful.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for
-

mh - Posts: 2292
- Joined: Sat Jan 12, 2008 1:38 am
Re: Doom 3 engine release and game code
Well, the question is what is in it for a small indie developer
In other words, if Doom 3 runs on most of the hardware (it runs pretty fast on my old PC), and the developer isn't going for CE3 / UDK features, is it worth waiting for GLSL backend being completed?
Personally I need anime / manga look for one of my games. And since there is no way to access depth buffer, nice inking isn't going to happened with neither ARB nor GLSL backend.
mh, do you have a theory on why ARB to GLSL translator hasn't been implemented yet?
Personally I need anime / manga look for one of my games. And since there is no way to access depth buffer, nice inking isn't going to happened with neither ARB nor GLSL backend.
mh, do you have a theory on why ARB to GLSL translator hasn't been implemented yet?
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Re: Doom 3 engine release and game code
the cell shader could probably be done in code instead of in shaders but then you would need a modded engine.
the cell shading script i posted a link to uses a few tricks to get around the depth buffer problem so might work, only way to know is test it out
as for arb shading most of the problem is that you cannot use id's shaders as a template (copyright) so would have to write them from scratch.
if you can then theres no problem in that regard but the restrictions of what you can do with arb shaders might be a problem.
an arb to glsl translator would indeed be nice
the cell shading script i posted a link to uses a few tricks to get around the depth buffer problem so might work, only way to know is test it out
as for arb shading most of the problem is that you cannot use id's shaders as a template (copyright) so would have to write them from scratch.
if you can then theres no problem in that regard but the restrictions of what you can do with arb shaders might be a problem.
an arb to glsl translator would indeed be nice
Productivity is a state of mind.
-

revelator - Posts: 2567
- Joined: Thu Jan 24, 2008 12:04 pm
- Location: inside tha debugger
Re: Doom 3 engine release and game code
I already have re-written ARB shaders (someone skilled at writing those did it, not me
) that are compatible with Doom 3 (math part of them is about the same as it's just math, it can't really be much different).
- motorsep
- Posts: 231
- Joined: Wed Aug 02, 2006 11:46 pm
- Location: Texas, USA
Who is online
Users browsing this forum: No registered users and 1 guest