//
// By Joseph Duffey Jan 2008
// Edited by Dennis van den Broek Feb 2010
// For the GameStudio Community
//
// Projective Texturing Spotlight
#define PRAGMA_PATH "GFX"
#define PRAGMA_PATH "Scripts"
BMAP* projectiontex = "Spotlight.jpg"; // texture to be projected
var flashlight_energy;
var flashlight_stat;
//=======================================================================================
// MATERIAL FOR OBJECTS LIT BY SPOTLIGHT
//=======================================================================================
MATERIAL* mtlSpotlit =
{
ambient_red = 18; // The ambient color - a dark grey.
ambient_green = 18;
ambient_blue = 18;
skin1 = projectiontex;
effect = "PT_Spot.fx"; // The effect file containing the vertex shader, pixel shader and technique.
flags |= OVERRIDE;
}
MATERIAL* mtlSpotlitObj =
{
ambient_red = 100; // The ambient color - a dark grey.
ambient_green = 100;
ambient_blue = 100;
skin1 = projectiontex;
effect = "PT_Spot.fx"; // The effect file containing the vertex shader, pixel shader and technique.
flags |= OVERRIDE;
}
MATERIAL* mtlNoSpotLight =
{
effect = "technique DepthTechnique { pass p0 { }}";
flags = OVERRIDE;
}
//=======================================================================================
// PROJECTION
//=======================================================================================
MATERIAL* mtlProjView =
{
effect = "technique DepthTechnique { pass p0 { }}"; // must have an effect or crash!
event = mtlProjection_event; // transform and adjust views view matrix
flags = ENABLE_VIEW; // call the event before view rendering
}
VIEW* ProjectionView = // Put at projectors position during rendering to get its view matrix
{
material = mtlProjView;
flags = SHOW | UNTOUCHABLE;
}
function mtlProjection_event() // adjust matrices to size of bitmaps and pass to "matMtl" and "matEffect"
{
// create a transformation matrix
float pTexAdj[16] = { 0.5, 0.0, 0.0, 0.0, 0.0,-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
// Adjust projection matrix for texture size
pTexAdj[12] = 0.5 + (0.5/(float)bmap_width(projectiontex)*2.0);// store bitmap diminsions into matrix
pTexAdj[13] = 0.5 + (0.5/(float)bmap_height(projectiontex)*2.0);
// Store the transformation matrix to the materials then adjust the matrix with the bitmap size
mat_set(mtlSpotlit.matrix,matViewProj); // store the transformation matrix to the material
mat_multiply(mtlSpotlit.matrix,pTexAdj); // adjust the matrix with the bitmap size
mat_set(mtlSpotlitObj.matrix,matViewProj); // store the transformation matrix to the material
mat_multiply(mtlSpotlitObj.matrix,pTexAdj); // adjust the matrix with the bitmap size
}
//=======================================================================================
// SPOTLIGHT ACTION
//=======================================================================================
function Spotlight()
{
diag_var("\nSpotlight started at %.3f\n", total_ticks/16);
SOUND* flashlight_snd = "flashlight.ogg";
VECTOR temp_vec; // for temporary vectors
VECTOR temp_vec2, temp_vec3;
ENTITY* temp_ent = ent_create(NULL, nullvector, NULL);
ProjectionView.aspect = 0.77; // adjust views aspect to desired ratio, squash or stretch
wait(10);
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
while(!player) wait(1);
while(player)
{
// move me with keyboard keys
//c_move(me, vector((key_w - key_s) * time_step * 8,0,0), nullvector, IGNORE_PASSABLE | GLIDE);
//c_rotate(me, vector((key_cul - key_cur)*time_step*8, (key_cuu-key_cud)*time_step*8,0), IGNORE_PASSABLE);
// Put projection view at my pos and dir
if(mouse_mode != 1)
{
vec_set(temp_ent.x, camera.x);
temp_ent.z -= player.skill100*1.5;
vec_set(temp_ent.pan, camera.pan);
c_move(temp_ent, vector(0,-10,0), nullvector, IGNORE_MODELS | IGNORE_MAPS);
vec_set(ProjectionView.x, temp_ent.x);
vec_set(ProjectionView.pan, camera.pan);
}
else
{
vec_set(temp_ent.x, camera.x);
temp_ent.z -= player.skill100*1.5;
vec_set(temp_ent.pan, camera.pan);
vec_set(ProjectionView.x, temp_ent.x);
temp_vec2.x = mouse_pos.x;
temp_vec2.y = mouse_pos.y;
temp_vec2.z = 50000;
vec_for_screen(temp_vec2, camera);
you = player;
c_trace(camera.x, temp_vec2, IGNORE_YOU);
vec_set(temp_vec3, target.x);
vec_sub(temp_vec3, camera.x);
vec_to_angle(ProjectionView.pan, temp_vec3);
}
// send my position to shader (vecSkill1.xyzw)
mtlSpotlit.skill1 = floatv(camera.x);
mtlSpotlit.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlit.skill3 = floatv(camera.y);
mtlSpotlitObj.skill1 = floatv(camera.x);
mtlSpotlitObj.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlitObj.skill3 = floatv(camera.y);
if(flashlight_stat == 1)
{
if(flashlight_energy > 500)
{
mtlSpotlit.skill4 = floatv(2000); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000); // spotlights range
}
else
{
if(flashlight_energy > 0)
{
mtlSpotlit.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
}
else
{
flashlight_stat = 0;
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
}
}
flashlight_energy -= time_step/2;
}
if(key_f)
{
if(flashlight_energy > 0)
{
if(flashlight_stat == 1)
{
mtlSpotlit.skill4 = floatv(1.0); // spotlights range
mtlSpotlitObj.skill4 = floatv(1.0); // spotlights range
player.skill1 = 0;
flashlight_stat = 0;
}
else
{
if(flashlight_energy > 500)
{
mtlSpotlitObj.skill4 = floatv(2000); // spotlights range
mtlSpotlit.skill4 = floatv(2000); // spotlights range
}
else
{
if(flashlight_energy > 0)
{
mtlSpotlit.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
mtlSpotlitObj.skill4 = floatv(2000-flashlight_energy/2); // spotlights range
}
else
{
flashlight_stat = 0;
mtlSpotlit.skill4 = floatv(1); // spotlights range
mtlSpotlitObj.skill4 = floatv(1); // spotlights range
}
}
player.skill1 = 1;
flashlight_stat = 1;
snd_play(flashlight_snd,100, 0);
}
while(key_f)
{
// Put projection view at my pos and dir
if(mouse_mode != 1)
{
vec_set(temp_ent.x, camera.x);
vec_set(temp_ent.pan, camera.pan);
temp_ent.z -= player.skill100*1.5;
c_move(temp_ent, vector(0,-10,0), nullvector, IGNORE_MODELS | IGNORE_MAPS);
vec_set(ProjectionView.x, temp_ent.x);
vec_set(ProjectionView.pan, camera.pan);
}
else
{
vec_set(temp_ent.x, camera.x);
vec_set(temp_ent.pan, camera.pan);
temp_ent.z -= player.skill100*1.5;
vec_set(ProjectionView.x, temp_ent.x);
temp_vec2.x = mouse_pos.x;
temp_vec2.y = mouse_pos.y;
temp_vec2.z = 50000;
vec_for_screen(temp_vec2, camera);
you = player;
c_trace(camera.x, temp_vec2, IGNORE_YOU);
vec_set(temp_vec3, target.x);
vec_sub(temp_vec3, camera.x);
vec_to_angle(ProjectionView.pan, temp_vec3);
}
// send my position to shader (vecSkill1.xyzw)
mtlSpotlit.skill1 = floatv(camera.x);
mtlSpotlit.skill2 = floatv(camera.z-player.skill100*1.5); // z and y must be reversed!
mtlSpotlit.skill3 = floatv(camera.y);
vec_for_angle(temp_vec.x, vector((camera.pan), camera.tilt, camera.roll)); //turn my angles into a dir vector
mtlSpotlit.skill5 = floatv(temp_vec.x);
mtlSpotlit.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlit.skill7 = floatv(temp_vec.y);
wait(1);
}
}
}
// send my direction to shader (vecSkill2.xyzw)
vec_for_angle(temp_vec.x, ProjectionView.pan); //turn my angles into a dir vector
mtlSpotlit.skill5 = floatv(temp_vec.x);
mtlSpotlit.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlit.skill7 = floatv(temp_vec.y);
mtlSpotlitObj.skill5 = floatv(temp_vec.x);
mtlSpotlitObj.skill6 = floatv(temp_vec.z); // z and y must be reversed!
mtlSpotlitObj.skill7 = floatv(temp_vec.y);
wait(1);
}
}
//=======================================================================================
// ACTION FOR OBJECTS LIT BY SPOTLIGHT
//=======================================================================================
action Spotlit_object()
{
my.material = mtlSpotlit;
}
//=======================================================================================
// FUNCTION FOR SETTING STAGE RENDERING
//=======================================================================================
// this should be done immediatly after level load
function init_stages()
{
ProjectionView.stage = camera; // so projection is not lagging one frame behind
}