Forum

Doom 3 engine release and game code

Discuss programming topics for any language, any source base. If it is programming related but doesn't fit in one of the below categories, it goes here.

Moderator: InsideQC Admins

Re: Doom 3 engine release and game code

Postby Spike » Mon Jun 18, 2012 7:26 pm

not really looked at it, so no.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: Doom 3 engine release and game code

Postby revelator » Mon Jun 18, 2012 8:03 pm

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 ?
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby motorsep » Mon Jun 18, 2012 11:05 pm

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.
motorsep
 
Posts: 231
Joined: Wed Aug 02, 2006 11:46 pm
Location: Texas, USA

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 5:33 am

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.

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.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby motorsep » Tue Jun 19, 2012 6:23 am

Ahh, you are that guy they talk about on #iodoom3 :D 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?
motorsep
 
Posts: 231
Joined: Wed Aug 02, 2006 11:46 pm
Location: Texas, USA

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 6:39 am

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.

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.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 6:45 am

shot from the hexen mod with glsl

Image

shot from the in hell mod with glsl

Image
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby motorsep » Tue Jun 19, 2012 6:48 am

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?
motorsep
 
Posts: 231
Joined: Wed Aug 02, 2006 11:46 pm
Location: Texas, USA

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 7:09 am

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.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 9:24 am

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
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby motorsep » Tue Jun 19, 2012 3:42 pm

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 :)
motorsep
 
Posts: 231
Joined: Wed Aug 02, 2006 11:46 pm
Location: Texas, USA

Re: Doom 3 engine release and game code

Postby mh » Tue Jun 19, 2012 5:31 pm

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.
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
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Doom 3 engine release and game code

Postby motorsep » Tue Jun 19, 2012 5:53 pm

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?
motorsep
 
Posts: 231
Joined: Wed Aug 02, 2006 11:46 pm
Location: Texas, USA

Re: Doom 3 engine release and game code

Postby revelator » Tue Jun 19, 2012 11:25 pm

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 :)
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Doom 3 engine release and game code

Postby motorsep » Tue Jun 19, 2012 11:30 pm

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

PreviousNext

Return to General Programming

Who is online

Users browsing this forum: No registered users and 1 guest