specular mapping in one pass

Started by
1 comment, last by Bobboau 20 years, 8 months ago
I have a rendering engine in wich I render polys with the following 1)defuse light 2)texture map 3)glow map (then in a second pass) 4)specular light 5)specular map the reason for the second pass is becase as far as I can tell there is now way to add specular light * the specular map in other words what I am doing is ( (defuse light)*(hull texture color)+(glowmap texture color) ) + ( (specular light)*(specmap) ) and I want to know if there is a way of doing this useing only texture stages if you want code it looks something like this

enum stage_state{INITAL, DEFUSE, GLOW_MAPPED_DEFUSE, NONMAPPED_SPECULAR, GLOWMAPPED_NONMAPPED_SPECULAR, MAPPED_SPECULAR};
stage_state state;

// This function calls these render state one when the device is initialised and when the device is lost.

void d3d_set_initial_render_state()
{
	if(state == INITAL)return;
	d3d_SetRenderState(D3DRS_DITHERENABLE, TRUE );

	d3d_SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE);

	d3d_SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
	d3d_SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

	d3d_SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
	d3d_SetRenderState(D3DRS_SPECULARENABLE, FALSE ); 

	// Turn lighting off here, its on by default!

	d3d_SetRenderState(D3DRS_LIGHTING , FALSE);

	//new glowmapping code,yay!!!-Bobboau

	d3d_SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
	
	d3d_SetTexture(1, NULL);
	d3d_SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	
	d3d_SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0);

	d3d_SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
	d3d_SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

	d3d_SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 0);

	d3d_SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
	d3d_SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
	d3d_SetTextureStageState( 4, D3DTSS_COLOROP, D3DTOP_DISABLE);

	state = INITAL;
}

extern bool env_enabled;

void set_stage_for_defuse(){
	if(state == DEFUSE)return;
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);

	state = DEFUSE;
		
}

void set_stage_for_glow_mapped_defuse(){
	if(state == GLOW_MAPPED_DEFUSE)return;
	if(GLOWMAP < 0){
		set_stage_for_defuse();
		return;
	}
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);

	d3d_SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0);
		
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADD);
//	d3d_SetTexture(1, GLOWMAP);


	state = GLOW_MAPPED_DEFUSE;
}

void set_stage_for_defuse_and_non_mapped_spec(){
	if(state == NONMAPPED_SPECULAR)return;
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);

	d3d_SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_SPECULAR);
	d3d_SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADD);

	state = NONMAPPED_SPECULAR;
}

void set_stage_for_glow_mapped_defuse_and_non_mapped_spec(){
	if(state == GLOWMAPPED_NONMAPPED_SPECULAR)return;
	if(GLOWMAP < 0){
		set_stage_for_defuse_and_non_mapped_spec();
		return;
	}
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE);

	d3d_SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 0);
		
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
	d3d_SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_ADD);
//	d3d_SetTexture(1, GLOWMAP);


	d3d_SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
	d3d_SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_SPECULAR);
	d3d_SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_ADD);

	state = GLOWMAPPED_NONMAPPED_SPECULAR;
}

bool set_stage_for_spec_mapped(){
	if(state == MAPPED_SPECULAR)return;
	if(SPECMAP < 0){
		false;
	}

	d3d_SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_SPECULAR);
	d3d_SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TEXTURE);
	d3d_SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE4X);
//	d3d_SetTexture(0, SPECMAP);


	//spec mapping is always done on a second pass

	gr_d3d_set_state( TEXTURE_SOURCE_DECAL, ALPHA_BLEND_ALPHA_ADDITIVE, ZBUFFER_TYPE_READ );

	state = MAPPED_SPECULAR;
	return true;
}

 
and the actual redering code though this is probly less important, just adding it so you have some idea what I'm doing

	//BEGIN FINAL SETTINGS


	//set for the most basic rendering type, change it later if needed

//	set_stage_for_defuse();


	//a bit of optomiseation, if there is no specular highlights don't bother waisting the recorses on trying to render them

	bool has_spec = false;
	for (i=0; i<nverts; i++ )	{
		if((verts[i]->spec_r > 0) || (verts[i]->spec_g > 0) || (verts[i]->spec_b > 0)){
			has_spec = true;
			break;
		}
	}

	//if this poly has specular but no spec map has been set

	if(has_spec && (SPECMAP < 0)){
		//if there is a glow map also

		if(GLOWMAP > -1){
			gr_screen.gf_set_bitmap(GLOWMAP, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, 0.0);
			if ( !d3d_tcache_set_internal(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0, 1))	{
				mprintf(( "Not rendering glowmap texture because it didn't fit in VRAM!\n" ));
				return;
			}

			set_stage_for_glow_mapped_defuse_and_non_mapped_spec();
		}else{
			set_stage_for_defuse_and_non_mapped_spec();
		}
	}


	//if this poly has no specular of any kind

	if(!has_spec){
		//if there is a glow map also

		if(GLOWMAP > -1){
			gr_screen.gf_set_bitmap(GLOWMAP, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, 0.0);
			if ( !d3d_tcache_set_internal(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0, 1))	{
				mprintf(( "Not rendering glowmap texture because it didn't fit in VRAM!\n" ));
				return;
			}
			
			set_stage_for_glow_mapped_defuse();
		}else{
			set_stage_for_defuse();
		}
	}else{
			//if there is a glow map also

		if(GLOWMAP > -1){
			gr_screen.gf_set_bitmap(GLOWMAP, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, 0.0);
			if ( !d3d_tcache_set_internal(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0, 1))	{
				mprintf(( "Not rendering glowmap texture because it didn't fit in VRAM!\n" ));
				return;
			}
			set_stage_for_glow_mapped_defuse();
		}else{
			set_stage_for_defuse();
		}
	}


	// Draws just about everything except stars and lines

 	d3d_DrawPrimitive(D3DVT_TLVERTEX, D3DPT_TRIANGLEFAN, (LPVOID)d3d_verts, nverts);

	//spec mapping

	if(has_spec && (SPECMAP > 0)){
		gr_screen.gf_set_bitmap(SPECMAP, gr_screen.current_alphablend_mode, gr_screen.current_bitblt_mode, 0.0);
		if ( !d3d_tcache_set_internal(gr_screen.current_bitmap, tmap_type, &u_scale, &v_scale, 0, gr_screen.current_bitmap_sx, gr_screen.current_bitmap_sy, 0, 0))	{
				mprintf(( "Not rendering specmap texture because it didn't fit in VRAM!\n" ));
				return;
			}
		for (i=0; i<nverts; i++ )	{
			d3d_verts[i].specular = D3DCOLOR_RGBA(verts[i]->spec_r, verts[i]->spec_g, verts[i]->spec_b, *(((ubyte*)&d3d_verts[i].specular)+3));
		}

		if(set_stage_for_spec_mapped())
		d3d_DrawPrimitive(D3DVT_TLVERTEX, D3DPT_TRIANGLEFAN, (LPVOID)d3d_verts, nverts);
	}
	d3d_set_initial_render_state();

 
all verts are transformed and lit (with both specular and defuse light) already in software mode (this is a 5 year old engine I'm tooling up, someone else is working on t&l, and vertex buffers, ect) so I don't need any help on the math behind the phong specular lighting model so is there a way of doing mapped specular lighting with one pass useing only texture stages? PS; I have also noted a problem when sometimes the wrong stage states are set due to some situation I failed to take into acount, if anyone sees this before me please point it out as it is causeing problems elseware (most notably in the HUD getting drawen incorectly) Bobboau, bringing you products that work... in theory [edited by - Bobboau on August 15, 2003 11:11:29 PM]
Bobboau, bringing you products that work... in theory
Advertisement
so should I take this as a no?
Bobboau, bringing you products that work... in theory

This is what pixel shaders are for, in a word

This topic is closed to new replies.

Advertisement