Esempio n. 1
0
//Set up variables
bool DemoInit() {
	//hide cursor
	glutSetCursor(GLUT_CURSOR_NONE);

//	SetUpARB_multitexture();
	SetUpEXT_texture_env_combine();
	SetUpEXT_draw_range_elements();
	SetUpEXT_multi_draw_arrays();

//	if(!ARB_multitexture_supported ||  !EXT_texture_env_combine_supported)
//		return false;

	//read in the map name etc from config.txt
	FILE * configFile = fopen("config.txt", "rt");
	if (!configFile) {
		Util::log("Cannot open \"config.txt\"");
		return false;
	}

	char levelName[256];
	fscanf(configFile, "Map: %s\n", levelName);
	int curveTesselation;
	fscanf(configFile, "Curve Tesselation: %d\n", &curveTesselation);
	VECTOR3D cameraPosition;
	float angleYaw, anglePitch;
	fscanf(configFile, "Camera Position: (%f %f %f)\n", &cameraPosition.x,
			&cameraPosition.y, &cameraPosition.z);
	fscanf(configFile, "Camera Orientation: %f %f\n", &angleYaw, &anglePitch);

	fclose(configFile);

	if (!bsp.Load(levelName, curveTesselation))
		return false;

	camera.Init(4.0f, cameraPosition, angleYaw, anglePitch);

	//reset timer for start
//	timer.Reset();

	return true;
}
void PPFXLightData::Update(float updateTime, const BSP &collideBSP, LightData &setLight){

  // Update particle lifetimes
  lifeTime    += updateTime;
  dirLifeTime += updateTime;

/*
  // Attenuate size over time
  if(lifeTime > (SECONDARY_LIGHT_LIFETIME*0.75f)){
    setLight.size = 75.0f * (1.0f - (lifeTime - (SECONDARY_LIGHT_LIFETIME*0.75f)) / (SECONDARY_LIGHT_LIFETIME*0.25f));
  }
  else{
    setLight.size = 75.0f; 
  }
*/

  // Calculate the new position using s = ut + 0.5at^2
  vec3 newPosition = spawnPosition + (direction * dirLifeTime) + (vec3(0.0f, -100.0f, 0.0f) * dirLifeTime * dirLifeTime * 0.5f);

  // Check for a collision between the last and new position
  vec3 colPoint;
  const BTri *colTriangle;
  if(collideBSP.intersects(setLight.position, newPosition, &colPoint, &colTriangle))
  {
    // Don't land exactly on the plane, 
    spawnPosition = colPoint + 10.0f * colTriangle->plane.xyz();

    // Calculate the new direction, with 95% of the origional velocity
    direction = reflect(direction, colTriangle->plane.xyz()); 
    direction *= 0.95f;
    dirLifeTime = 0.0f;

    // Don't worry about calculating the directional 
    newPosition = spawnPosition;
  }

  // Assign the new position
  setLight.position = newPosition;
}
Esempio n. 3
0
ImportAsset::ImportAsset(const char* resourcePath)
{
    import::IImport* iImport = NULL;
    queryInterface( "Import", &iImport );

    import::IImportStream* iImportStream = iImport->importRws( resourcePath );
    
    while( iImportStream->getType() != import::itNULL )
    switch( iImportStream->getType() )
    {
    case import::itTexture:
        {
            import::ImportTexture* importData = iImportStream->importTexture();
            // search for texture in current dictionary
            if( Texture::textures.find( importData->name ) == Texture::textures.end() )
            {
                if( strcmp( importData->name, "House01" ) == 0 )
                {
                    int iiii=0;
                }
                // create compatible texture
                Texture* texture = Texture::createDynamicTexture( 
                    importData->width, 
                    importData->height, 
                    importData->depth, 
                    importData->name
                );
                // lock texture top-level surface
                D3DLOCKED_RECT lockedRect;
                texture->iDirect3DTexture()->LockRect( 0, &lockedRect, NULL, 0 );
                // copy pixels
                int offset = 0;
                unsigned char* destPixels = (unsigned char*)(lockedRect.pBits);    
                for( int i=0; i<importData->width*importData->height; i++ )
                {
                    destPixels[offset + 0] = importData->pixels[offset + 2],
                    destPixels[offset + 1] = importData->pixels[offset + 1],
                    destPixels[offset + 2] = importData->pixels[offset + 0],
                    destPixels[offset + 3] = importData->pixels[offset + 3];
                    offset += 4;
                }
                texture->iDirect3DTexture()->UnlockRect( 0 );
                // setup filetering, addressing, etc
                switch( importData->addressMode )
                {
                case import::iamWrap: 
                    texture->setAddressTypeU( engine::atWrap );
                    texture->setAddressTypeV( engine::atWrap );
                    break;
                case import::iamMirror:
                    texture->setAddressTypeU( engine::atMirror );
                    texture->setAddressTypeV( engine::atMirror );
                    break;
                case import::iamClamp:
                    texture->setAddressTypeU( engine::atClamp );
                    texture->setAddressTypeV( engine::atClamp );
                    break;
                case import::iamBorder:
                    texture->setAddressTypeU( engine::atBorder );
                    texture->setAddressTypeV( engine::atBorder );
                    break;
                }
                switch( importData->filterMode )
                {
                case import::ifmNearest:
                    texture->setMagFilter( engine::ftPoint );
                    texture->setMinFilter( engine::ftPoint );
                    texture->setMipFilter( engine::ftNone );
                    break;
                case import::ifmLinear:
                    texture->setMagFilter( engine::ftLinear );
                    texture->setMinFilter( engine::ftLinear );
                    texture->setMipFilter( engine::ftNone );
                    break;
                case import::ifmMipNearest:
                    texture->setMagFilter( engine::ftPoint );
                    texture->setMinFilter( engine::ftPoint );
                    texture->setMipFilter( engine::ftPoint );
                    break;
                case import::ifmMipLinear:
                    texture->setMagFilter( engine::ftPoint );
                    texture->setMinFilter( engine::ftPoint );
                    texture->setMipFilter( engine::ftLinear );
                    break;
                case import::ifmLinearMipNearest:
                    texture->setMagFilter( engine::ftLinear );
                    texture->setMinFilter( engine::ftLinear );
                    texture->setMipFilter( engine::ftPoint );
                    break;
                case import::ifmLinearMipLinear:
                    texture->setMagFilter( engine::ftLinear );
                    texture->setMinFilter( engine::ftLinear );
                    texture->setMipFilter( engine::ftLinear );
                    break;
                }
                // override filtering
                texture->setMagFilter( engine::ftLinear );
                texture->setMinFilter( engine::ftLinear );
                texture->setMipFilter( engine::ftLinear );
                texture->setMaxAnisotropy( 8 );
                /*
                // create normal map
                iImport->createNormalMap(
                    importData->width, 
                    importData->height, 
                    importData->depth, 
                    importData->pixels,
                    importData->stride,
                    true,
                    5.0f
                );
                // create compatible texture
                Texture* normalMap = Texture::createDynamicTexture(
                    importData->width, 
                    importData->height, 
                    importData->depth, 
                    ( std::string( importData->name ) + "_nmap" ).c_str()
                );
                normalMap->setMagFilter( engine::ftLinear );
                normalMap->setMinFilter( engine::ftLinear );
                normalMap->setMipFilter( engine::ftLinear );
                // lock texture top-level surface
                lockedRect;
                normalMap->iDirect3DTexture()->LockRect( 0, &lockedRect, NULL, 0 );
                // copy pixels
                offset = 0;
                destPixels = (unsigned char*)(lockedRect.pBits);    
                for( i=0; i<importData->width*importData->height; i++ )
                {
                    destPixels[offset + 0] = importData->pixels[offset + 2],
                    destPixels[offset + 1] = importData->pixels[offset + 1],
                    destPixels[offset + 2] = importData->pixels[offset + 0],
                    destPixels[offset + 3] = importData->pixels[offset + 3];
                    offset += 4;
                }
                normalMap->iDirect3DTexture()->UnlockRect( 0 );
                */
                // put texture into importer storage
                _textures.insert( TextureT( importData->id, texture ) );
            }
            // release import data
            iImport->release( importData );
        }
        break;
    case import::itMaterial:
        {
            import::ImportMaterial* importData = iImportStream->importMaterial();

            Shader* shader = NULL;
            
            if( importData->textureId == 0 && importData->dualPassTextureId == 0 )
            {
                shader = new Shader( 0, importData->name );
            }
            else if( importData->textureId != 0 && importData->dualPassTextureId == 0 )
            {
                shader = new Shader( 1, importData->name );
                TextureI textureI = _textures.find( importData->textureId );
                if( textureI != _textures.end() ) 
                {
                    shader->setLayerTexture( 0, textureI->second );
                }
                shader->setLayerUV( 0,0 );
                /*
                ::TextureI normalMapI = Texture::textures.find( ( std::string( textureI->second->getName() ) + "_nmap" ).c_str() );
                if( normalMapI != Texture::textures.end() )
                {
                    shader->setNormalMap( normalMapI->second );
                    shader->setNormalMapUV( 0 );
                }
                */
            }
            else
            {
                shader = new Shader( 2, importData->name );
                TextureI textureI = _textures.find( importData->textureId );
                if( textureI != _textures.end() ) 
                {
                    shader->setLayerTexture( 0, textureI->second );
                }
                textureI = _textures.find( importData->dualPassTextureId );
                if( textureI != _textures.end() ) 
                {
                    shader->setLayerTexture( 1, textureI->second );
                }
                shader->setLayerUV( 1,1 );
                switch( importData->dualPassBlendType )
                {
                case import::ImportMaterial::btAdd:
                    shader->setLayerBlending( 1, engine::btAdd );
                    break;
                case import::ImportMaterial::btModulate:
                    shader->setLayerBlending( 1, engine::btModulate );
                    break;
                case import::ImportMaterial::btBlendTextureAlpha:
                    shader->setLayerBlending( 1, engine::btBlendTextureAlpha );
                    break;
                default:
                    shader->setLayerBlending( 1, engine::btOver );
                }

                textureI = _textures.find( importData->textureId );
                assert( textureI != _textures.end() );
                ::TextureI normalMapI = Texture::textures.find( ( std::string( textureI->second->getName() ) + "_nmap" ).c_str() );
                if( normalMapI != Texture::textures.end() )
                {
                    shader->setNormalMap( normalMapI->second );
                    shader->setNormalMapUV( 0 );
                }
            }

            shader->setDiffuseColor( importData->color );
            // put texture into importer storage
            _shaders.insert( ShaderT( importData->id, shader ) );
            // release import data
            iImport->release( importData );
        }
        break;
    case import::itFrame:
        {
            import::ImportFrame* importData = iImportStream->importFrame();

            Frame* frame = new Frame( importData->name );
            frame->TransformationMatrix = wrap( importData->modeling );	
			
            FrameI parentI = _frames.find( importData->parentId );
            if( parentI != _frames.end() ) 
            {
                frame->setParent( parentI->second );
            }
            _frames.insert( FrameT( importData->id, frame ) );
            iImport->release( importData );
        }
        break;
    case import::itGeometry:
        {
            import::ImportGeometry* importData = iImportStream->importGeometry();

            Geometry* geometry = new Geometry(
                importData->numVertices,
                importData->numTriangles,
                importData->numUVs,
                importData->numMaterials,
                ( importData->prelights != NULL ) ? 1 : 0,
                false,
                importData->name
            );

            for( int i=0; i<importData->numVertices; i++ )
            {
                geometry->getVertices()[i] = wrap( importData->vertices[i] );				
                geometry->getNormals()[i] = wrap( importData->normals[i] );
				// rh2lh conversion
                /*
				geometry->getVertices()[i][2] *= -1;
				geometry->getNormals()[i][2] *= -1;
                */
                geometry->getUVSet(0)[i] = wrap( importData->uvs[0][i] );
                if( importData->numUVs > 1 ) 
                {
                    geometry->getUVSet(1)[i] = wrap( importData->uvs[1][i] );
                }
                if( importData->prelights )
                {
                    geometry->getPrelights(0)[i] = wrap( importData->prelights[i] );
                }
            }
            for( i=0; i<importData->numTriangles; i++ )
            {
                /*
                geometry->getTriangles()[i].set(
                    importData->triangles[i].vertexId[0],
					importData->triangles[i].vertexId[2],
					importData->triangles[i].vertexId[1],					
                    importData->triangles[i].materialId
                );
                */
                geometry->getTriangles()[i].set(
                    importData->triangles[i].vertexId[0],
                    importData->triangles[i].vertexId[1],
					importData->triangles[i].vertexId[2],					
                    importData->triangles[i].materialId
                );
            }
            for( i=0; i<importData->numMaterials; i++ )
            {
                ShaderI shaderI = _shaders.find( importData->materials[i] );
                assert( shaderI != _shaders.end() );
                geometry->setShader( i, shaderI->second );
            }
            geometry->instance();
            _geometries.insert( GeometryT( importData->id, geometry ) );
            iImport->release( importData );
        }
        break;
    case import::itAtomic:
        {
            import::ImportAtomic* importData = iImportStream->importAtomic();
            Atomic* atomic = new Atomic;
            FrameI frameI = _frames.find( importData->frameId );
            assert( frameI != _frames.end() );
            atomic->setFrame( frameI->second );
            GeometryI geometryI = _geometries.find( importData->geometryId );
            assert( geometryI != _geometries.end() );
            atomic->setGeometry( geometryI->second );            
            TextureI textureI = _textures.find( importData->lightmapId );
            if( textureI != _textures.end() ) 
            {
                atomic->setLightMap( textureI->second );
            }
            _atomics.insert( AtomicT( importData->id, atomic ) );
            iImport->release( importData );
        }
        break;
    case import::itClump:
        {
            import::ImportClump* importData = iImportStream->importClump();
            Clump* clump = new Clump( importData->name );
            FrameI frameI = _frames.find( importData->frameId );
            assert( frameI != _frames.end() );
            clump->setFrame( frameI->second );
            frameI->second->dirty();
            for( int i=0; i<importData->numAtomics; i++ )
            {
                AtomicI atomicI = _atomics.find( importData->atomics[i] );
                assert( atomicI != _atomics.end() );
                clump->add( atomicI->second );
            }
            for( i=0; i<importData->numLights; i++ )
            {
                LightI lightI = _lights.find( importData->lights[i] );
                assert( lightI != _lights.end() );
                clump->add( lightI->second );
            }
            iImport->release( importData );
            /*
			rh2lh( clump->frame() );
            */
            _clumps.push_back( clump );
        }
        break;
    case import::itWorldSector:
        {
            import::ImportWorldSector* importData = iImportStream->importWorldSector();
            
            BSPI bspI = _bspM.find( importData->worldId ); assert( bspI != _bspM.end() );
            BSPSectorI parentSectorI = _bspSectorM.find( importData->parentId );
            BSPSector* parentSector = NULL;
            if( parentSectorI != _bspSectorM.end() ) parentSector = parentSectorI->second;
            AABB boundingBox;
            boundingBox.inf = wrap( importData->aabbInf );
            boundingBox.sup = wrap( importData->aabbSup );
			// rh2lh conversion
            /*
			float temp = boundingBox.inf[2] * -1;
			boundingBox.inf[2] = boundingBox.sup[2] * -1;
			boundingBox.sup[2] = temp;
            */

            int numPrelights = 0; if( importData->prelights ) numPrelights++;

            Geometry* geometry = NULL;

            if( importData->numVertices && importData->numTriangles )
            {
                geometry = new Geometry( 
                    importData->numVertices, 
                    importData->numTriangles, 
                    importData->numUVs, 
                    bspI->second->getNumShaders(),
                    numPrelights,
                    true,
                    strformat( "BSPSector_%x_Shape", importData->id ).c_str()
                );

                geometry->setShaders( bspI->second->getShaders() );

                for( int i=0; i<importData->numVertices; i++ )
                {
                    geometry->getVertices()[i] = wrap( importData->vertices[i] );
                    geometry->getNormals()[i] = wrap( importData->normals[i] );
					// rh2lh conversion
                    /*
					geometry->getVertices()[i][2] *= -1;
                    geometry->getNormals()[i][2] *= -1;
                    */
                    for( int j=0; j<importData->numUVs; j++ ) geometry->getUVSet(j)[i] = wrap( importData->uvs[j][i] );
                    if( numPrelights ) geometry->getPrelights(0)[i] = wrap( importData->prelights[i] );
                }
                for( i=0; i<importData->numTriangles; i++ )
                {
                    /*
                    geometry->getTriangles()[i].set(
                        importData->triangles[i].vertexId[0],
                        importData->triangles[i].vertexId[2],
						importData->triangles[i].vertexId[1],
                        importData->triangles[i].materialId
                    );
                    */
                    geometry->getTriangles()[i].set(
                        importData->triangles[i].vertexId[0],
                        importData->triangles[i].vertexId[1],
                        importData->triangles[i].vertexId[2],
                        importData->triangles[i].materialId
                    );
                }
                geometry->instance();
            }
            BSPSector* sector = new BSPSector( bspI->second, parentSector, boundingBox, geometry );

            TextureI textureI = _textures.find( importData->lightmapId );
            if( textureI != _textures.end() ) 
            {
                sector->setLightMap( textureI->second );
            }

            _bspSectorM.insert( BSPSectorT( importData->id, sector ) );
            iImport->release( importData );
        };
        break;
    case import::itWorld:
        {
            import::ImportWorld* importData = iImportStream->importWorld();
			AABB boundingBox; 
			boundingBox.inf = wrap( importData->aabbInf );
			boundingBox.sup = wrap( importData->aabbSup );			
			// rh2lh conversion
            /*
			float temp = boundingBox.inf[2] * -1;
			boundingBox.inf[2] = boundingBox.sup[2] * -1;
			boundingBox.sup[2] = temp;
            */

            BSP* bsp = new BSP( 
                importData->name,
                boundingBox, 
                importData->numMaterials 
            );
            for( int i=0; i<importData->numMaterials; i++ )
            {
                ShaderI shaderI = _shaders.find( importData->materials[i] );
                assert( shaderI != _shaders.end() );
                bsp->setShader( i, shaderI->second );
            }
            _bspM.insert( BSPT( importData->id, bsp ) );
            _bsps.push_back( bsp );
            iImport->release( importData );
        };
        break;
    case import::itLight:
        {
            import::ImportLight* importData = iImportStream->importLight();

            engine::LightType lightType;
            switch( importData->type )
            {
            case import::ImportLight::ltAmbient:
                lightType = engine::ltAmbient;
                break;
            case import::ImportLight::ltDirectional:
                lightType = engine::ltDirectional;
                break;
            case import::ImportLight::ltPoint:
                lightType = engine::ltPoint;
                break;
            case import::ImportLight::ltSpot:
                lightType = engine::ltSpot;
                break;
            default:
                assert( !"shouldn't be here!" );
            }

            Light* light = new Light( lightType );
            light->setRange( importData->radius );
            light->setDiffuseColor( importData->color );
            light->setSpecularColor( importData->color );
            light->setPhi( importData->coneAngle );
            light->setTheta( importData->coneAngle );
            light->setAttenuation( Vector3f( 0,0.0001f,0 ) );
            
            FrameI frameI = _frames.find( importData->frameId );
            assert( frameI != _frames.end() );
            light->setFrame( frameI->second );

            _lights.insert( LightT( importData->id, light ) );

            iImport->release( importData );
        }
        break;
    default:
        assert( !"shouldn't be here!" );
    }

    iImport->release( iImportStream );
}
Esempio n. 4
0
//draw a frame
void RenderFrame() {
	//Clear buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();									//reset modelview matrix

	glRotatef(camera.anglePitch, 1.0f, 0.0f, 0.0f);
	glRotatef(camera.angleYaw, 0.0f, 1.0f, 0.0f);
	glTranslatef(-camera.position.x, -camera.position.y, -camera.position.z);

	frustum.Update();

	glPushAttrib(GL_ALL_ATTRIB_BITS);

	//Set states for drawing map
	//Set up texture units

	//Unit 0 - replace with decal textures
	glEnable(GL_TEXTURE_2D);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

	//Unit 1
	glActiveTextureARB(GL_TEXTURE1_ARB);
	glEnable(GL_TEXTURE_2D);

	if (renderMethod == MODULATE_TEXTURES)//Then modulate by lightmap, then double
			{
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);

		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);

		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

		glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2.0f);
	}

	if (renderMethod == SHOW_TEXTURES)	//Then replace with previous
			{
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);

		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
	}

	if (renderMethod == SHOW_LIGHTMAPS)	//Then replace with lightmaps
			{
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);

		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_REPLACE);
	}

	glActiveTextureARB(GL_TEXTURE0_ARB);

	if (updatePVS)
		bsp.CalculateVisibleFaces(camera.position, frustum);

	bsp.Draw();

	glPopAttrib();

	fpsCounter.Update();					//update frames per second counter
	//window.StartTextMode();
//	glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
	//window.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps());		//print the fps
//	glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
//	if (renderMethod == SHOW_TEXTURES)
//		window.Print(0, 48, "Showing Textures");
//	if (renderMethod == SHOW_LIGHTMAPS)
//		window.Print(0, 48, "Showing Lightmaps");
//	if (renderMethod == MODULATE_TEXTURES)
//		window.Print(0, 48, "Showing Lit Textures");
//	glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
//	if (!updatePVS)
//		window.Print(0, 68, "PVS/Frustum Cull paused");
//	window.EndTextMode();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

//	if(window.isKeyPressed(VK_F1))
//	{
//		window.SaveScreenshot();
//		window.SetKeyReleased(VK_F1);
//	}

	// All done drawing.  Let's show it.
	glutSwapBuffers();									//swap buffers

	//check for any opengl errors
//	window.CheckGLError();
}
void Geometry::render(void)
{
	// add "false &&" to enable lights for all geometry
    if( _numPrelights )
    {
        _dxCR( dxSetRenderState( D3DRS_LIGHTING, FALSE ) );
        _dxCR( dxSetRenderState( D3DRS_COLORVERTEX, TRUE ) );
        _dxCR( dxSetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1 ) );
    }
    else
    {
        _dxCR( dxSetRenderState( D3DRS_LIGHTING, TRUE ) );
        _dxCR( dxSetRenderState( D3DRS_COLORVERTEX, FALSE ) );
        _dxCR( dxSetRenderState( D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL ) );
        _dxCR( dxSetRenderState( D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL ) );
    }

    int shaderId;
    int numAttributes = _mesh->NumAttributeGroups;
    for( int i=0; i<numAttributes; i++ )
    {
        shaderId = _mesh->getAttributeId( i );

        if( !shader( shaderId )->isInvisible() )
        {
            // shading technique contains alpha blending/testing?
            if( ( _shaders[shaderId]->getFlags() & engine::sfAlphaBlending || 
                  _shaders[shaderId]->getFlags() & engine::sfAlphaTesting 
                ) &&
                ( Atomic::currentAtomic || 
                  BSPSector::currentSector 
                )
              )
            {
                if( Atomic::currentAtomic )
                {
                    BSP* bsp = getAtomicBSP( Atomic::currentAtomic );
                    if( bsp ) bsp->addAlphaGeometry( Atomic::currentAtomic, i );
                }
                else if( BSPSector::currentSector )
                {
                    BSP* bsp = BSPSector::currentSector->bsp(); assert( bsp );
                    bsp->addAlphaGeometry( BSPSector::currentSector, i );
                }
            }
            else if( _shaders[shaderId]->effect() )
            {
                reinterpret_cast<Effect*>( _shaders[shaderId]->effect() )->render( 
                    _mesh, i, _shaders[shaderId]
                );
                dxSetVertexShader( NULL );
                dxSetPixelShader( NULL );
            }
            else
            {
                if( _mesh->pSkinInfo )
                {
                    int i=0;
                }
                _shaders[shaderId]->apply();
                _mesh->renderSubset( i, _shaders[shaderId] );
                // if shader use non-default lightset, then recalculate 
                // lighting back to default lightset
                if( _shaders[shaderId]->getLightset() )
                {
                    BSP::currentBSP->calculateGlobalAmbient( 0 );
                    BSPSector::currentSector->illuminate( 0 );
                }
            }
        }
    }
}