diff options
| author | Joe Ludwig <[email protected]> | 2013-07-17 18:26:59 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-07-17 18:26:59 -0700 |
| commit | e16ea21dc8a710237ade8413207f58d403c616a3 (patch) | |
| tree | 85dcfbda9881e4e022dedafefbc2727e2fd2aa59 /mp | |
| parent | Merge pull request #36 from AnAkIn1/fogplayerparams_fix (diff) | |
| download | source-sdk-2013-e16ea21dc8a710237ade8413207f58d403c616a3.tar.xz source-sdk-2013-e16ea21dc8a710237ade8413207f58d403c616a3.zip | |
* Added support for building shaders in your mod
* Added nav mesh support
* fixed many warnings and misc bugs
* Fixed the create*projects scripts in mp
* Added a bunch of stuff to .gitignore
Diffstat (limited to 'mp')
213 files changed, 27497 insertions, 1351 deletions
diff --git a/mp/game/mod_hl2mp/materials/example_model_material.vmt b/mp/game/mod_hl2mp/materials/example_model_material.vmt new file mode 100644 index 00000000..219f60f2 --- /dev/null +++ b/mp/game/mod_hl2mp/materials/example_model_material.vmt @@ -0,0 +1,7 @@ +"Mod_Example_Model"
+{
+ "$basetexture" "Models/props_c17/Oil_Drum001g"
+// "$basetexturetransform" "center 0 0 scale 1 2 rotate 0 translate 0 0"
+// "$AlphaTestReference" "0.5"
+ "$surfaceprop" "metal"
+}
diff --git a/mp/game/mod_hl2mp/shaders/fxc/example_model_ps20b.vcs b/mp/game/mod_hl2mp/shaders/fxc/example_model_ps20b.vcs Binary files differnew file mode 100644 index 00000000..616b536f --- /dev/null +++ b/mp/game/mod_hl2mp/shaders/fxc/example_model_ps20b.vcs diff --git a/mp/game/mod_hl2mp/shaders/fxc/example_model_vs20.vcs b/mp/game/mod_hl2mp/shaders/fxc/example_model_vs20.vcs Binary files differnew file mode 100644 index 00000000..633eda48 --- /dev/null +++ b/mp/game/mod_hl2mp/shaders/fxc/example_model_vs20.vcs diff --git a/mp/src/createallprojects b/mp/src/createallprojects index 4677ca79..4f44d066 100755 --- a/mp/src/createallprojects +++ b/mp/src/createallprojects @@ -1,4 +1,4 @@ #!/bin/bash -devtools/bin/vpc /hl2 /episodic +everything /mksln everything +devtools/bin/vpc /hl2mp +everything /mksln everything diff --git a/mp/src/creategameprojects b/mp/src/creategameprojects index ae1d12cc..0fa9b4ed 100755 --- a/mp/src/creategameprojects +++ b/mp/src/creategameprojects @@ -1,4 +1,4 @@ #!/bin/bash -devtools/bin/vpc /hl2 /episodic +game /mksln games +devtools/bin/vpc /hl2mp +game /mksln games diff --git a/mp/src/devtools/bin/buildshaderlist.pl b/mp/src/devtools/bin/buildshaderlist.pl new file mode 100644 index 00000000..57790ace --- /dev/null +++ b/mp/src/devtools/bin/buildshaderlist.pl @@ -0,0 +1,22 @@ +use File::DosGlob;
+@ARGV = map {
+ my @g = File::DosGlob::glob($_) if /[*?]/;
+ @g ? @g : $_;
+ } @ARGV;
+
+open FILE, ">__tmpshaderlist.txt";
+
+foreach $arg (@ARGV)
+{
+ if( $arg =~ m/\.fxc$/i || $arg =~ m/\.vsh$/i || $arg =~ m/\.psh$/i )
+ {
+ print $arg . "\n";
+ print FILE $arg . "\n";
+ }
+}
+
+close FILE;
+
+system "buildshaders.bat __tmpshaderlist";
+
+unlink "__tmpshaderlist.txt";
\ No newline at end of file diff --git a/mp/src/devtools/bin/checkshaderchecksums.pl b/mp/src/devtools/bin/checkshaderchecksums.pl new file mode 100644 index 00000000..e41509f2 --- /dev/null +++ b/mp/src/devtools/bin/checkshaderchecksums.pl @@ -0,0 +1,116 @@ +use String::CRC32;
+BEGIN {use File::Basename; push @INC, dirname($0); }
+require "valve_perl_helpers.pl";
+
+sub GetShaderType
+{
+ my $shadername = shift;
+ my $shadertype;
+ if( $shadername =~ m/\.vsh/i )
+ {
+ $shadertype = "vsh";
+ }
+ elsif( $shadername =~ m/\.psh/i )
+ {
+ $shadertype = "psh";
+ }
+ elsif( $shadername =~ m/\.fxc/i )
+ {
+ $shadertype = "fxc";
+ }
+ else
+ {
+ die;
+ }
+ return $shadertype;
+}
+
+sub GetShaderSrc
+{
+ my $shadername = shift;
+ if ( $shadername =~ m/^(.*)-----/i )
+ {
+ return $1;
+ }
+ else
+ {
+ return $shadername;
+ }
+}
+
+sub GetShaderType
+{
+ my $shadername = shift;
+ my $shadertype;
+ if( $shadername =~ m/\.vsh/i )
+ {
+ $shadertype = "vsh";
+ }
+ elsif( $shadername =~ m/\.psh/i )
+ {
+ $shadertype = "psh";
+ }
+ elsif( $shadername =~ m/\.fxc/i )
+ {
+ $shadertype = "fxc";
+ }
+ else
+ {
+ die;
+ }
+ return $shadertype;
+}
+
+sub GetShaderBase
+{
+ my $shadername = shift;
+ if ( $shadername =~ m/-----(.*)$/i )
+ {
+ return $1;
+ }
+ else
+ {
+ my $shadertype = &GetShaderType( $shadername );
+ $shadername =~ s/\.$shadertype//i;
+ return $shadername;
+ }
+}
+
+$g_x360 = 0;
+$g_vcsext = ".vcs";
+
+while( 1 )
+{
+ $inputbase = shift;
+
+ if( $inputbase =~ m/-x360/ )
+ {
+ $g_x360 = 1;
+ $g_vcsext = ".360.vcs";
+ }
+ else
+ {
+ last;
+ }
+}
+
+# rip the txt off the end if it's there.
+$inputbase =~ s/\.txt//i;
+
+my @srcfiles = &LoadShaderListFile( $inputbase );
+
+foreach $srcfile ( @srcfiles )
+{
+ my $shadertype = &GetShaderType( $srcfile );
+ my $shaderbase = &GetShaderBase( $srcfile );
+ my $shadersrc = &GetShaderSrc( $srcfile );
+ my $vcsFileName = "..\\..\\..\\game\\hl2\\shaders\\$shadertype\\$shaderbase" . $g_vcsext;
+# print "shadersrc: $shadersrc vcsFileName: $vcsFileName\n";
+
+ if( $g_x360 && ( $shaderbase =~ m/_ps20$/i ) )
+ {
+ next; # skip _ps20 files for 360
+ }
+
+ &CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 1 );
+}
diff --git a/mp/src/devtools/bin/copyshaderincfiles.pl b/mp/src/devtools/bin/copyshaderincfiles.pl new file mode 100644 index 00000000..21702d8f --- /dev/null +++ b/mp/src/devtools/bin/copyshaderincfiles.pl @@ -0,0 +1,75 @@ +BEGIN {use File::Basename; push @INC, dirname($0); }
+require "valve_perl_helpers.pl";
+use Cwd;
+use String::CRC32;
+
+my $txtfilename = shift;
+my $arg = shift;
+
+my $is360 = 0;
+my $platformextension = "";
+if( $arg =~ m/-x360/i )
+{
+ $is360 = 1;
+ $platformextension = ".360";
+}
+
+open TXTFILE, "<$txtfilename";
+
+my $src;
+my $dst;
+while( $src = <TXTFILE> )
+{
+ # get rid of comments
+ $src =~ s,//.*,,g;
+
+ # skip blank lines
+ if( $src =~ m/^\s*$/ )
+ {
+ next;
+ }
+
+ # Get rid of newlines.
+ $src =~ s/\n//g;
+
+ # Save off the shader source filename.
+ my $dst = $src;
+
+ $dst =~ s/_tmp//gi;
+
+ # Does the dst exist?
+ my $dstexists = -e $dst;
+ my $srcexists = -e $src;
+ # What are the time stamps for the src and dst?
+ my $srcmodtime = ( stat $src )[9];
+ my $dstmodtime = ( stat $dst )[9];
+
+ # Open for edit or add if different than what is in perforce already.
+ if( !$dstexists || ( $srcmodtime != $dstmodtime ) )
+ {
+ # Make the target writable if it exists
+ if( $dstexists )
+ {
+ MakeFileWritable( $dst );
+ }
+
+ my $dir = $dst;
+ $dir =~ s,([^/\\]*$),,; # rip the filename off the end
+ my $filename = $1;
+
+ # create the target directory if it doesn't exist
+ if( !$dstexists )
+ {
+ &MakeDirHier( $dir, 0777 );
+ }
+
+ # copy the file to its targets. . . we want to see STDERR here if there is an error.
+ my $cmd = "copy $src $dst > nul";
+# print STDERR "$cmd\n";
+ system $cmd;
+
+ MakeFileReadOnly( $dst );
+ }
+}
+
+close TXTFILE;
diff --git a/mp/src/devtools/bin/copyshaders.pl b/mp/src/devtools/bin/copyshaders.pl new file mode 100644 index 00000000..53839298 --- /dev/null +++ b/mp/src/devtools/bin/copyshaders.pl @@ -0,0 +1,172 @@ +BEGIN {use File::Basename; push @INC, dirname($0); }
+require "valve_perl_helpers.pl";
+use Cwd;
+use String::CRC32;
+
+sub ReadInputFileWithIncludes
+{
+ local( $filename ) = shift;
+
+ local( *INPUT );
+ local( $output );
+
+ open INPUT, "<$filename" || die;
+
+ local( $line );
+ local( $linenum ) = 1;
+ while( $line = <INPUT> )
+ {
+ if( $line =~ m/\#include\s+\"(.*)\"/i )
+ {
+ $output.= ReadInputFileWithIncludes( $1 );
+ }
+ else
+ {
+ $output .= $line;
+ }
+ }
+
+ close INPUT;
+ return $output;
+}
+
+sub PatchCRC
+{
+ my $filename = shift;
+ my $crc = shift;
+# print STDERR "PatchCRC( $filename, $crc )\n";
+ local( *FP );
+ open FP, "+<$filename" || die;
+ binmode( FP );
+ seek FP, 6 * 4, 0;
+ my $uInt = "I";
+ if( $filename =~ m/360/ )
+ {
+ $uInt = "N";
+ }
+ print FP pack $uInt, $crc;
+ close FP;
+}
+
+my $txtfilename = shift;
+my $arg = shift;
+
+my $is360 = 0;
+my $platformextension = "";
+if( $arg =~ m/-x360/i )
+{
+ $is360 = 1;
+ $platformextension = ".360";
+}
+
+# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
+my $changelistnumber = `valve_p4_create_changelist.cmd ..\\..\\..\\game\\hl2\\shaders \"Shader Auto Checkout VCS\"`;
+# Get rid of the newline
+$changelistnumber =~ s/\n//g;
+
+my $changelistarg = "";
+if( $changelistnumber != 0 )
+{
+ $changelistarg = "-c $changelistnumber"
+}
+
+open TXTFILE, "<$txtfilename";
+
+my $src;
+my $dst;
+while( $src = <TXTFILE> )
+{
+ # get rid of comments
+ $src =~ s,//.*,,g;
+
+ # skip blank lines
+ if( $src =~ m/^\s*$/ )
+ {
+ next;
+ }
+
+ # Get rid of newlines.
+ $src =~ s/\n//g;
+
+ # Save off the shader source filename.
+ my $shadersrcfilename = $src;
+ $shadersrcfilename =~ s/-----.*$//;
+ # use only target basename.
+ $src =~ s/^.*-----//;
+
+ # where the binary vcs file is
+ my $spath = "";
+
+ if ( $shadersrcfilename =~ m@\.fxc@i )
+ {
+ $spath = "shaders\\fxc\\";
+ }
+ if ( $shadersrcfilename =~ m@\.vsh@i )
+ {
+ $spath = "shaders\\vsh\\";
+ }
+ if ( $shadersrcfilename =~ m@\.psh@i )
+ {
+ $spath = "shaders\\psh\\";
+ }
+
+ # make the source have path and extension
+ $src = $spath . $src . $platformextension . ".vcs";
+
+ # build the dest filename.
+ $dst = $src;
+
+ $dst =~ s/shaders\\/..\\..\\..\\game\\hl2\\shaders\\/i;
+
+ # Does the dst exist?
+ my $dstexists = -e $dst;
+ my $srcexists = -e $src;
+ # What are the time stamps for the src and dst?
+ my $srcmodtime = ( stat $src )[9];
+ my $dstmodtime = ( stat $dst )[9];
+
+ # Write $dst to a file so that we can do perforce stuff to it later.
+ local( *VCSLIST );
+ open VCSLIST, ">>vcslist.txt" || die;
+ print VCSLIST $dst . "\n";
+ close VCSLIST;
+
+ # Open for edit or add if different than what is in perforce already.
+ if( !$dstexists || ( $srcmodtime != $dstmodtime ) )
+ {
+ if ( $srcexists && $shadersrcfilename =~ m@\.fxc@i )
+ {
+ # Get the CRC for the source file.
+ my $srccode = ReadInputFileWithIncludes( $shadersrcfilename );
+ my $crc = crc32( $srccode );
+
+ # Patch the source VCS file with the CRC32 of the source code used to build that file.
+ PatchCRC( $src, $crc );
+ }
+
+ # Make the target vcs writable if it exists
+ if( $dstexists )
+ {
+ MakeFileWritable( $dst );
+ }
+
+ my $dir = $dst;
+ $dir =~ s,([^/\\]*$),,; # rip the filename off the end
+ my $filename = $1;
+
+ # create the target directory if it doesn't exist
+ if( !$dstexists )
+ {
+ &MakeDirHier( $dir, 0777 );
+ }
+
+ # copy the file to its targets. . . we want to see STDERR here if there is an error.
+ my $cmd = "copy $src $dst > nul";
+# print STDERR "$cmd\n";
+ system $cmd;
+
+ MakeFileReadOnly( $dst );
+ }
+}
+
+close TXTFILE;
diff --git a/mp/src/devtools/bin/d3dx9_33.dll b/mp/src/devtools/bin/d3dx9_33.dll Binary files differnew file mode 100644 index 00000000..a005f8fa --- /dev/null +++ b/mp/src/devtools/bin/d3dx9_33.dll diff --git a/mp/src/devtools/bin/fix_particle_operator_names.pl b/mp/src/devtools/bin/fix_particle_operator_names.pl new file mode 100644 index 00000000..86fd0f0f --- /dev/null +++ b/mp/src/devtools/bin/fix_particle_operator_names.pl @@ -0,0 +1,110 @@ +#!perl
+use File::Find;
+
+&BuildRemapTable;
+
+find(\&convert, "." );
+
+
+sub convert
+ {
+ return unless (/\.pcf$/i);
+ return if (/^tmp\.pcf$/i);
+ return if (/^tmp2\.pcf$/i);
+ return if (/360\.pcf$/i);
+ print STDERR "process ", $File::Find::name," ($_) dir=",`cd`," \n";
+ my $fname=$_;
+ print `p4 edit $fname`;
+ print `dmxconvert -i $_ -o tmp.pcf -oe keyvalues2`;
+ open(TMP, "tmp.pcf" ) || return;
+ open(OUT, ">tmp2.pcf" ) || die;
+ while(<TMP>)
+ {
+ s/[\n\r]//g;
+ if ( (/^(\s*\"functionName\"\s*\"string\"\s*\")(.*)\"(.*)$/) &&
+ length($map{$2}) )
+ {
+ $_=$1.$map{$2}.'"'.$3;
+ }
+ if ( (/^(\s*\"name\"\s*\"string\"\s*\")(.*)\"(.*)$/) &&
+ length($map{$2}) )
+ {
+ $_=$1.$map{$2}.'"'.$3;
+ }
+ print OUT "$_\n";
+ }
+ close OUT;
+ close TMP;
+ print `dmxconvert -i tmp2.pcf -o $fname -ie keyvalues2 -oe binary`;
+ unlink "tmp.pcf";
+ unlink "tmp2.pcf";
+}
+
+
+
+
+
+
+
+
+
+
+
+
+sub BuildRemapTable
+{
+ $map{"alpha_fade"}= "Alpha Fade and Decay";
+ $map{"alpha_fade_in_random"}= "Alpha Fade In Random";
+ $map{"alpha_fade_out_random"}= "Alpha Fade Out Random";
+ $map{"basic_movement"}= "Movement Basic";
+ $map{"color_fade"}= "Color Fade";
+ $map{"controlpoint_light"}= "Color Light From Control Point";
+ $map{"Dampen Movement Relative to Control Point"}= "Movement Dampen Relative to Control Point";
+ $map{"Distance Between Control Points Scale"}= "Remap Distance Between Two Control Points to Scalar";
+ $map{"Distance to Control Points Scale"}= "Remap Distance to Control Point to Scalar";
+ $map{"lifespan_decay"}= "Lifespan Decay";
+ $map{"lock to bone"}= "Movement Lock to Bone";
+ $map{"postion_lock_to_controlpoint"}= "Movement Lock to Control Point";
+ $map{"maintain position along path"}= "Movement Maintain Position Along Path";
+ $map{"Match Particle Velocities"}= "Movement Match Particle Velocities";
+ $map{"Max Velocity"}= "Movement Max Velocity";
+ $map{"noise"}= "Noise Scalar";
+ $map{"vector noise"}= "Noise Vector";
+ $map{"oscillate_scalar"}= "Oscillate Scalar";
+ $map{"oscillate_vector"}= "Oscillate Vector";
+ $map{"Orient Rotation to 2D Direction"}= "Rotation Orient to 2D Direction";
+ $map{"radius_scale"}= "Radius Scale";
+ $map{"Random Cull"}= "Cull Random";
+ $map{"remap_scalar"}= "Remap Scalar";
+ $map{"rotation_movement"}= "Rotation Basic";
+ $map{"rotation_spin"}= "Rotation Spin Roll";
+ $map{"rotation_spin yaw"}= "Rotation Spin Yaw";
+ $map{"alpha_random"}= "Alpha Random";
+ $map{"color_random"}= "Color Random";
+ $map{"create from parent particles"}= "Position From Parent Particles";
+ $map{"Create In Hierarchy"}= "Position In CP Hierarchy";
+ $map{"random position along path"}= "Position Along Path Random";
+ $map{"random position on model"}= "Position on Model Random";
+ $map{"sequential position along path"}= "Position Along Path Sequential";
+ $map{"position_offset_random"}= "Position Modify Offset Random";
+ $map{"position_warp_random"}= "Position Modify Warp Random";
+ $map{"position_within_box"}= "Position Within Box Random";
+ $map{"position_within_sphere"}= "Position Within Sphere Random";
+ $map{"Inherit Velocity"}= "Velocity Inherit from Control Point";
+ $map{"Initial Repulsion Velocity"}= "Velocity Repulse from World";
+ $map{"Initial Velocity Noise"}= "Velocity Noise";
+ $map{"Initial Scalar Noise"}= "Remap Noise to Scalar";
+ $map{"Lifespan from distance to world"}= "Lifetime from Time to Impact";
+ $map{"Pre-Age Noise"}= "Lifetime Pre-Age Noise";
+ $map{"lifetime_random"}= "Lifetime Random";
+ $map{"radius_random"}= "Radius Random";
+ $map{"random yaw"}= "Rotation Yaw Random";
+ $map{"Randomly Flip Yaw"}= "Rotation Yaw Flip Random";
+ $map{"rotation_random"}= "Rotation Random";
+ $map{"rotation_speed_random"}= "Rotation Speed Random";
+ $map{"sequence_random"}= "Sequence Random";
+ $map{"second_sequence_random"}= "Sequence Two Random";
+ $map{"trail_length_random"}= "Trail Length Random";
+ $map{"velocity_random"}= "Velocity Random";
+}
+
diff --git a/mp/src/devtools/bin/linux/ccache b/mp/src/devtools/bin/linux/ccache Binary files differindex 9846e22d..3ef6b8e9 100755 --- a/mp/src/devtools/bin/linux/ccache +++ b/mp/src/devtools/bin/linux/ccache diff --git a/mp/src/devtools/bin/osx32/ccache b/mp/src/devtools/bin/osx32/ccache Binary files differindex 36a7081d..86afc048 100755 --- a/mp/src/devtools/bin/osx32/ccache +++ b/mp/src/devtools/bin/osx32/ccache diff --git a/mp/src/devtools/bin/shaderinfo.pl b/mp/src/devtools/bin/shaderinfo.pl new file mode 100644 index 00000000..ae0b96c8 --- /dev/null +++ b/mp/src/devtools/bin/shaderinfo.pl @@ -0,0 +1,36 @@ +#! perl
+
+my $fname=shift || die "format is shaderinfo blah.vcs";
+
+open(SHADER, $fname) || die "can't open $fname";
+binmode SHADER;
+
+read(SHADER,$header,20);
+($ver,$ntotal,$ndynamic,$flags,$centroidmask)=unpack("LLLLL",$header);
+
+#print "Version $ver total combos=$ntotal, num dynamic combos=$ndynamic,\n flags=$flags, centroid mask=$centroidmask\n";
+
+read(SHADER,$refsize,4);
+$refsize=unpack("L",$refsize);
+#print "Size of reference shader for diffing=$refsize\n";
+
+seek(SHADER,$refsize,1);
+
+$nskipped_combos=0;
+for(1..$ntotal)
+ {
+ read(SHADER,$combodata,8);
+ ($ofs,$combosize)=unpack("LL",$combodata);
+ if ( $ofs == 0xffffffff)
+ {
+ $nskipped_combos++;
+ }
+ else
+ {
+ }
+ }
+#print "$nskipped_combos skipped, for an actual total of ",$ntotal-$nskipped_combos,"\n";
+#print "Real to skipped ratio = ",($ntotal-$nskipped_combos)/$ntotal,"\n";
+# csv output - name, real combos, virtual combos, dynamic combos
+my $real_combos=$ntotal-$nskipped_combos;
+print "$fname,$real_combos,$ntotal,$ndynamic\n";
diff --git a/mp/src/devtools/bin/splitdiff3.pl b/mp/src/devtools/bin/splitdiff3.pl new file mode 100644 index 00000000..e38b493a --- /dev/null +++ b/mp/src/devtools/bin/splitdiff3.pl @@ -0,0 +1,54 @@ +$infilename = shift;
+$outfilename1 = shift;
+$outfilename2 = shift;
+open INPUT, $infilename || die;
+@input = <INPUT>;
+close INPUT;
+
+open MERGEDMINE, ">$outfilename1" || die;
+open MERGEDTHEIRS, ">$outfilename2" || die;
+
+for( $i = 0; $i < scalar( @input ); $i++ )
+{
+ $line = $input[$i];
+
+ if( $line =~ m/^(.*)<<<<<<</ )
+ {
+ $first = 1;
+ $second = 0;
+ print MERGEDMINE $1;
+ print MERGEDTHEIRS $1;
+ next;
+ }
+ # Make sure that we are in a split block so that comments with ======= don't mess us up.
+ if( $line =~ m/^(.*)=======$/ && $first == 1 )
+ {
+ $first = 0;
+ $second = 1;
+ print MERGEDMINE $1;
+ next;
+ }
+ if( $line =~ m/^(.*)>>>>>>>/ )
+ {
+ $first = $second = 0;
+ print MERGEDTHEIRS $1;
+ next;
+ }
+
+ if( $first )
+ {
+ print MERGEDMINE $line;
+ }
+ elsif( $second )
+ {
+ print MERGEDTHEIRS $line;
+ }
+ else
+ {
+ print MERGEDMINE $line;
+ print MERGEDTHEIRS $line;
+ }
+}
+
+close MERGEDMINE;
+close MERGEDTHEIRS;
diff --git a/mp/src/devtools/bin/uniqifylist.pl b/mp/src/devtools/bin/uniqifylist.pl new file mode 100644 index 00000000..d8d40afd --- /dev/null +++ b/mp/src/devtools/bin/uniqifylist.pl @@ -0,0 +1,6 @@ +foreach $_ (sort <> )
+{
+ next if( defined( $prevline ) && $_ eq $prevline );
+ $prevline = $_;
+ print;
+}
diff --git a/mp/src/devtools/bin/valve_perl_helpers.pl b/mp/src/devtools/bin/valve_perl_helpers.pl new file mode 100644 index 00000000..5cd2aa04 --- /dev/null +++ b/mp/src/devtools/bin/valve_perl_helpers.pl @@ -0,0 +1,558 @@ +sub BackToForwardSlash
+{
+ my( $path ) = shift;
+ $path =~ s,\\,/,g;
+ return $path;
+}
+
+sub RemoveFileName
+{
+ my( $in ) = shift;
+ $in = &BackToForwardSlash( $in );
+ $in =~ s,/[^/]*$,,;
+ return $in;
+}
+
+sub RemovePath
+{
+ my( $in ) = shift;
+ $in = &BackToForwardSlash( $in );
+ $in =~ s,^(.*)/([^/]*)$,$2,;
+ return $in;
+}
+
+sub MakeDirHier
+{
+ my( $in ) = shift;
+# print "MakeDirHier( $in )\n";
+ $in = &BackToForwardSlash( $in );
+ my( @path );
+ while( $in =~ m,/, ) # while $in still has a slash
+ {
+ my( $end ) = &RemovePath( $in );
+ push @path, $end;
+# print $in . "\n";
+ $in = &RemoveFileName( $in );
+ }
+ my( $i );
+ my( $numelems ) = scalar( @path );
+ my( $curpath );
+ for( $i = $numelems - 1; $i >= 0; $i-- )
+ {
+ $curpath .= "/" . $path[$i];
+ my( $dir ) = $in . $curpath;
+ if( !stat $dir )
+ {
+# print "mkdir $dir\n";
+ mkdir $dir, 0777;
+ }
+ }
+}
+
+sub FileExists
+{
+ my $filename = shift;
+ my @statresult = stat $filename;
+ my $iswritable = @statresult != 0;
+ return $iswritable;
+}
+
+sub MakeFileWritable
+{
+ my $filename = shift;
+ if ( &FileExists( $filename ) )
+ {
+ chmod 0666, $filename || die;
+ }
+}
+
+sub MakeFileReadOnly
+{
+ my $filename = shift;
+ chmod 0444, $filename || die;
+}
+
+# Run a command and get stdout and stderr to an array
+sub RunCommand
+{
+ my $cmd = shift;
+# print STDERR "command: $cmd\n";
+ system "$cmd > cmdout.txt 2>&1" || die;
+ local( *FILE );
+ open FILE, "<cmdout.txt" || die;
+ my @output = <FILE>;
+# print STDERR "command output: @output\n";
+ close FILE;
+ unlink "cmdout.txt" || die;
+ return @output;
+}
+
+sub PerforceEditOrAdd
+{
+ return;
+ my $filename = shift;
+ my $changelistarg = shift;
+
+ # Is the file on the client?
+ my $cmd = "p4 fstat \"$filename\"";
+ my @p4output = &RunCommand( $cmd );
+ my $p4output = join "", @p4output;
+ if( $p4output =~ m/no such file/ )
+ {
+ # not on client. . add
+ my $cmd = "p4 add $changelistarg $filename";
+ my @p4output = &RunCommand( $cmd );
+ my $p4output = join "", @p4output;
+ if( $p4output =~ m/opened for add/ )
+ {
+ print $p4output;
+ return;
+ }
+ print "ERROR: $p4output";
+ return;
+ }
+
+ # The file is known to be on the client at this point.
+
+ # Is it open for edit?
+ if( $p4output =~ m/action edit/ )
+ {
+ # Is is open for edit, let's see if it's still different.
+ # check for opened files that are not different from the revision in the depot.
+ my $cmd = "p4 diff -sr \"$filename\"";
+ my @p4output = &RunCommand( $cmd );
+ my $outputstring = join "", @p4output;
+ # check for empty string
+ if( !( $outputstring =~ m/^\s*$/ ) )
+ {
+ my $cmd = "p4 revert \"$filename\"";
+ my @p4output = &RunCommand( $cmd );
+ my $outputstring = join "", @p4output;
+ print $outputstring;
+ return;
+ }
+ }
+
+ # check for unopened files that are different from the revision in the depot.
+ my $cmd = "p4 diff -se \"$filename\"";
+ my @p4output = &RunCommand( $cmd );
+ my $outputstring = join "", @p4output;
+ # check for empty string
+ if( $outputstring =~ m/^\s*$/ )
+ {
+ &MakeFileReadOnly( $filename );
+ return;
+ }
+
+ # We need to edit the file since it is known to be different here.
+ my $cmd = "p4 edit $changelistarg \"$filename\"";
+ my @p4output = &RunCommand( $cmd );
+
+ my $line;
+ foreach $line ( @p4output )
+ {
+ if( $line =~ m/not on client/ )
+ {
+ #print "notonclient...";
+ print "ERROR: @p4output\n";
+ return;
+ }
+ if( $line =~ m/currently opened for edit/ )
+ {
+ return;
+ }
+ if( $line =~ m/opened for edit/ )
+ {
+ print $line;
+ }
+ }
+}
+
+sub FileIsWritable
+{
+ local( $filename ) = shift;
+ local( @statresult ) = stat $filename;
+ local( $mode, $iswritable );
+ $mode = oct( $statresult[2] );
+ $iswritable = ( $mode & 2 ) != 0;
+ return $iswritable;
+}
+
+sub TouchFile
+{
+ my $filename = shift;
+ if( !&FileExists( $filename ) )
+ {
+ if( !open FILE, ">$filename" )
+ {
+ die;
+ }
+ close FILE;
+ }
+ my $now = time;
+ local( *FILE );
+ utime $now, $now, $filename;
+}
+
+sub FileExistsInPerforce
+{
+ my $filename = shift;
+ my @output = &RunCommand( "p4 fstat $filename" );
+ my $line;
+ foreach $line (@output)
+ {
+ if( $line =~ m/no such file/ )
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+sub PerforceWriteFile
+{
+ my $filename = shift;
+ my $filecontents = shift;
+# my $changelistname = shift;
+
+ # Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
+# my $changelistnumber = `valve_p4_create_changelist.cmd . \"$changelistname\"`;
+ # Get rid of the newline
+# $changelistnumber =~ s/\n//g;
+
+# my $changelistarg = "";
+# if( $changelistnumber != 0 )
+# {
+# $changelistarg = "-c $changelistnumber"
+# }
+
+ # Make the target vcs writable if it exists
+ MakeFileWritable( $filename );
+
+ # Write the file.
+ local( *FP );
+ open FP, ">$filename";
+ print FP $filecontents;
+ close FP;
+
+ # Do whatever needs to happen with perforce for this file.
+# &PerforceEditOrAdd( $filename, $changelistarg );
+}
+
+sub WriteFile
+{
+ my $filename = shift;
+ my $filecontents = shift;
+
+ # Make the target vcs writable if it exists
+ MakeFileWritable( $filename );
+
+ # Write the file.
+ local( *FP );
+ open FP, ">$filename";
+ print FP $filecontents;
+ close FP;
+}
+
+sub PrintCleanPerforceOutput
+{
+ my $line;
+ while( $line = shift )
+ {
+ if( $line =~ m/currently opened/i )
+ {
+ next;
+ }
+ if( $line =~ m/already opened for edit/i )
+ {
+ next;
+ }
+ if( $line =~ m/also opened/i )
+ {
+ next;
+ }
+ if( $line =~ m/add of existing file/i )
+ {
+ next;
+ }
+ print $line;
+ }
+}
+
+# HACK!!!! Need to pass something in to do this rather than hard coding.
+sub NormalizePerforceFilename
+{
+ my $line = shift;
+
+ # remove newlines.
+ $line =~ s/\n//;
+ # downcase.
+ $line =~ tr/[A-Z]/[a-z]/;
+ # backslash to forwardslash
+ $line =~ s,\\,/,g;
+
+ # for inc files HACK!
+ $line =~ s/^.*(fxctmp9.*)/$1/i;
+ $line =~ s/^.*(vshtmp9.*)/$1/i;
+
+ # for vcs files. HACK!
+ $line =~ s,^.*game/hl2/shaders/,,i;
+
+ return $line;
+}
+
+sub MakeSureFileExists
+{
+ local( $filename ) = shift;
+ local( $testexists ) = shift;
+ local( $testwrite ) = shift;
+
+ local( @statresult ) = stat $filename;
+ if( !@statresult && $testexists )
+ {
+ die "$filename doesn't exist!\n";
+ }
+ local( $mode, $iswritable );
+ $mode = oct( $statresult[2] );
+ $iswritable = ( $mode & 2 ) != 0;
+ if( !$iswritable && $testwrite )
+ {
+ die "$filename isn't writable!\n";
+ }
+}
+
+sub LoadShaderListFile_GetShaderType
+{
+ my $shadername = shift;
+ my $shadertype;
+ if( $shadername =~ m/\.vsh/i )
+ {
+ $shadertype = "vsh";
+ }
+ elsif( $shadername =~ m/\.psh/i )
+ {
+ $shadertype = "psh";
+ }
+ elsif( $shadername =~ m/\.fxc/i )
+ {
+ $shadertype = "fxc";
+ }
+ else
+ {
+ die;
+ }
+ return $shadertype;
+}
+
+sub LoadShaderListFile_GetShaderSrc
+{
+ my $shadername = shift;
+ if ( $shadername =~ m/^(.*)-----/i )
+ {
+ return $1;
+ }
+ else
+ {
+ return $shadername;
+ }
+}
+
+sub LoadShaderListFile_GetShaderBase
+{
+ my $shadername = shift;
+ if ( $shadername =~ m/-----(.*)$/i )
+ {
+ return $1;
+ }
+ else
+ {
+ my $shadertype = &LoadShaderListFile_GetShaderType( $shadername );
+ $shadername =~ s/\.$shadertype//i;
+ return $shadername;
+ }
+}
+
+sub LoadShaderListFile
+{
+ my $inputbase = shift;
+
+ my @srcfiles;
+ &MakeSureFileExists( "$inputbase.txt", 1, 0 );
+
+ open SHADERLISTFILE, "<$inputbase.txt" || die;
+ my $line;
+ while( $line = <SHADERLISTFILE> )
+ {
+ $line =~ s/\/\/.*$//; # remove comments "//..."
+ $line =~ s/^\s*//; # trim leading whitespace
+ $line =~ s/\s*$//; # trim trailing whitespace
+ next if( $line =~ m/^\s*$/ );
+ if( $line =~ m/\.fxc/ || $line =~ m/\.vsh/ || $line =~ m/\.psh/ )
+ {
+ my $shaderbase = &LoadShaderListFile_GetShaderBase( $line );
+
+ if( $ENV{"DIRECTX_FORCE_MODEL"} =~ m/^30$/i ) # forcing all shaders to be ver. 30
+ {
+ my $targetbase = $shaderbase;
+ $targetbase =~ s/_ps2x/_ps30/i;
+ $targetbase =~ s/_ps20b/_ps30/i;
+ $targetbase =~ s/_ps20/_ps30/i;
+ $targetbase =~ s/_vs20/_vs30/i;
+ $targetbase =~ s/_vsxx/_vs30/i;
+ push @srcfiles, ( $line . "-----" . $targetbase );
+ }
+ else
+ {
+ if( $shaderbase =~ m/_ps2x/i )
+ {
+ my $targetbase = $shaderbase;
+ $targetbase =~ s/_ps2x/_ps20/i;
+ push @srcfiles, ( $line . "-----" . $targetbase );
+
+ $targetbase = $shaderbase;
+ $targetbase =~ s/_ps2x/_ps20b/i;
+ push @srcfiles, ( $line . "-----" . $targetbase );
+ }
+ elsif( $shaderbase =~ m/_vsxx/i )
+ {
+ my $targetbase = $shaderbase;
+ $targetbase =~ s/_vsxx/_vs11/i;
+ push @srcfiles, ( $line . "-----" . $targetbase );
+
+ $targetbase = $shaderbase;
+ $targetbase =~ s/_vsxx/_vs20/i;
+ push @srcfiles, ( $line . "-----" . $targetbase );
+ }
+ else
+ {
+ push @srcfiles, ( $line . "-----" . $shaderbase );
+ }
+ }
+ }
+ }
+ close SHADERLISTFILE;
+ return @srcfiles;
+}
+
+sub ReadInputFileWithIncludes
+{
+ local( $filename ) = shift;
+# print STDERR "ReadInputFileWithIncludes: $filename\n";
+
+ local( *INPUT );
+ local( $output );
+
+# print STDERR "before open\n";
+ open INPUT, "<$filename" || die;
+# print STDERR "after open\n";
+
+ local( $line );
+ while( $line = <INPUT> )
+ {
+# print STDERR $line;
+ if( $line =~ m/\#include\s+\"(.*)\"/i )
+ {
+ $output.= ReadInputFileWithIncludes( $1 );
+ }
+ else
+ {
+ $output .= $line;
+ }
+ }
+
+ close INPUT;
+ return $output;
+}
+
+sub GetCRCFromSourceFile
+{
+ my $filename = shift;
+ my $data = &ReadInputFileWithIncludes( $filename );
+# print STDERR $data;
+ $crc = crc32( $data );
+# print STDERR "GetCRCFromSourceFile: $crc\n";
+ return $crc;
+}
+
+sub GetCRCFromVCSFile
+{
+ my $filename = shift;
+# print STDERR "GetCRCFromVCSFile $filename\n";
+ local( *FP );
+ open FP, "<$filename" || die "GetCRCFromVCSFile: can't open file $filename\n";
+ binmode( FP );
+
+ # unpack arguments
+ my $sInt = "i";
+ my $uInt = "I";
+ if( $filename =~ m/\.360\./ )
+ {
+ # Change arguments to "big endian long"
+ $sInt = "N";
+ $uInt = "N";
+ }
+
+ my $header;
+ read FP, $header, 7 * 4 || die "updateshaders.pl:GetCRCFromVCSFile: can't read header for $filename\n";
+ my $version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc;
+ ($version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc) = unpack "$sInt$sInt$sInt$uInt$uInt$uInt$uInt", $header;
+ unless( $version == 4 || $version == 5 || $version == 6 )
+ {
+ print STDERR "ERROR: GetCRCFromVCSFile: $filename is version $version\n";
+ return 0;
+ }
+# print STDERR "version: $version\n";
+# print STDERR "numCombos: $numCombos\n";
+# print STDERR "numDynamicCombos: $numDynamicCombos\n";
+# print STDERR "flags: $flags\n";
+# print STDERR "centroidMask: $centroidMask\n";
+# print STDERR "refSize: $refSize\n";
+# print STDERR "GetCRCFromVCSFile: $crc\n";
+ close( FP );
+ return $crc;
+}
+
+sub CheckCRCAgainstTarget
+{
+ my $srcFileName = shift;
+ my $vcsFileName = shift;
+ my $warn = shift;
+
+ # Make sure both files exist.
+# print STDERR "$srcFileName doesn't exist\n" if( !( -e $srcFileName ) );
+# print STDERR "$vcsFileName doesn't exist\n" if( !( -e $vcsFileName ) );
+ if( !( -e $srcFileName ) )
+ {
+ if( $warn )
+ {
+ print "$srcFileName missing\n";
+ }
+ return 0;
+ }
+ if( !( -e $vcsFileName ) )
+ {
+ if( $warn )
+ {
+ print "$vcsFileName missing\n";
+ }
+ return 0;
+ }
+# print STDERR "CheckCRCAgainstTarget( $srcFileName, $vcsFileName );\n";
+# print STDERR "vcsFileName: $vcsFileName\n";
+# print STDERR "vcsFileName: $srcFileName\n";
+ my $vcsCRC = &GetCRCFromVCSFile( $vcsFileName );
+ my $srcCRC = &GetCRCFromSourceFile( $srcFileName );
+ if( $warn && ( $vcsCRC != $srcCRC ) )
+ {
+ print "$vcsFileName checksum ($vcsCRC) != $srcFileName checksum: ($srcCRC)\n";
+ }
+
+# return 0; # use this to skip crc checking.
+# if( $vcsCRC == $srcCRC )
+# {
+# print STDERR "CRC passed for $srcFileName $vcsFileName $vcsCRC\n";
+# }
+ return $vcsCRC == $srcCRC;
+}
+
+1;
diff --git a/mp/src/devtools/bin/vpc.exe b/mp/src/devtools/bin/vpc.exe Binary files differindex 0c084858..ddc1328c 100644 --- a/mp/src/devtools/bin/vpc.exe +++ b/mp/src/devtools/bin/vpc.exe diff --git a/mp/src/devtools/bin/vpc_linux b/mp/src/devtools/bin/vpc_linux Binary files differindex b0302349..d6534046 100755 --- a/mp/src/devtools/bin/vpc_linux +++ b/mp/src/devtools/bin/vpc_linux diff --git a/mp/src/devtools/bin/vpc_osx b/mp/src/devtools/bin/vpc_osx Binary files differindex 7194daac..0f9ef14b 100755 --- a/mp/src/devtools/bin/vpc_osx +++ b/mp/src/devtools/bin/vpc_osx diff --git a/mp/src/devtools/makefile_base_posix.mak b/mp/src/devtools/makefile_base_posix.mak index f4689c4b..7ad95035 100644 --- a/mp/src/devtools/makefile_base_posix.mak +++ b/mp/src/devtools/makefile_base_posix.mak @@ -1,503 +1,509 @@ -# -# Base makefile for Linux and OSX -# -# !!!!! Note to future editors !!!!! -# -# before you make changes, make sure you grok: -# 1. the difference between =, :=, +=, and ?= -# 2. how and when this base makefile gets included in the generated makefile(s) -# ( see http://www.gnu.org/software/make/manual/make.html#Flavors ) -# -# Command line prefixes: -# - errors are ignored -# @ command is not printed to stdout before being executed -# + command is executed even if Make is invoked in "do not exec" mode - -OS := $(shell uname) -HOSTNAME := $(shell hostname) - --include $(SRCROOT)/devtools/steam_def.mak --include $(SRCROOT)/devtools/sourcesdk_def.mak - -# To build with clang, set the following in your environment: -# CC = clang -# CXX = clang++ - -ifeq ($(CFG), release) - # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3. - # There also was no speed difference running at 1280x1024. May 2012, mikesart. - # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3. - # -fno-omit-frame-pointer: need this for stack traces with perf. - OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops -else - OptimizerLevel_CompilerSpecific = -O0 - #-O1 -finline-functions -endif - -# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags" -ARCH_FLAGS = -BUILDING_MULTI_ARCH = 0 -CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) )) -CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE -CXXFLAGS = $(CFLAGS) -DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE -LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel) -GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P) -MAP_FLAGS = -Srv_GAMEOUTPUTFILE = -COPY_DLL_TO_SRV = 0 - - -ifeq ($(STEAM_BRANCH),1) - WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof -else - WARN_FLAGS = -Wno-write-strings -Wno-multichar -endif - -WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security - - -ifeq ($(OS),Linux) - # We should always specify -Wl,--build-id, as documented at: - # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId - LDFLAGS += -Wl,--build-id - # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path. - # Dedicated server uses this. - ifeq ($(USE_VALVE_BINDIR),1) - # dedicated server flags - ifeq ($(TARGET_PLATFORM),linux64) - VALVE_BINDIR = /valve/bin64/ - MARCH_TARGET = nocona - else - VALVE_BINDIR = /valve/bin/ - MARCH_TARGET = pentium4 - endif - STRIP_FLAGS = - else - # linux desktop client flags - VALVE_BINDIR = - # If the steam-runtime is available, use it. We should just default to using it when - # buildbot and everyone has a bit of time to get it installed. - ifneq "$(wildcard /valve/steam-runtime/bin/)" "" - # The steam-runtime is incompatible with clang at this point, so disable it - # if clang is enabled. - ifneq ($(CXX),clang++) - VALVE_BINDIR = /valve/steam-runtime/bin/ - endif - endif - GCC_VER = - MARCH_TARGET = pentium4 - # On dedicated servers, some plugins depend on global variable symbols in addition to functions. - # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2. - STRIP_FLAGS = -x - endif - - ifeq ($(CXX),clang++) - # Clang does not support -mfpmath=sse because it uses whatever - # instruction set extensions are available by default. - SSE_GEN_FLAGS = -msse2 - else - SSE_GEN_FLAGS = -msse2 -mfpmath=sse - endif - - CCACHE := $(SRCROOT)/devtools/bin/linux/ccache - - ifeq ($(origin GCC_VER), undefined) - GCC_VER=-4.6 - endif - ifeq ($(origin AR), default) - AR = $(VALVE_BINDIR)ar crs - endif - ifeq ($(origin CC),default) - CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER) - endif - ifeq ($(origin CXX), default) - CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER) - endif - # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to - # a ccache quirk. Could also upgrade ccache. - # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html - ifeq ($(CC),clang) - CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments - endif - ifeq ($(CXX),clang++) - CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments - endif - LINK ?= $(CC) - - ifeq ($(TARGET_PLATFORM),linux64) - # nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2) - ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2 - LD_SO = ld-linux-x86_64.so.2 - LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a) - LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a) - else - # pentium4 = MMX, SSE, SSE2 - no SSE3 (added in prescott) # -msse3 -mfpmath=sse - ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=core2 $(SSE_GEN_FLAGS) - LD_SO = ld-linux.so.2 - LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) - LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so) - LDFLAGS += -m32 - endif - - GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh - ifeq ($(CFG),release) - STRIP ?= strip $(STRIP_FLAGS) -S - # CFLAGS += -ffunction-sections -fdata-sections - # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections - else - STRIP ?= true - endif - VSIGN ?= true - - ifeq ($(SOURCE_SDK), 1) - Srv_GAMEOUTPUTFILE := $(GAMEOUTPUTFILE:.so=_srv.so) - COPY_DLL_TO_SRC := 1 - endif - - LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map - - SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined - - _WRAP := -Xlinker --wrap= - PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \ - $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \ - $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \ - $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \ - $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath - - LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group - LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread - - LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group - LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt - -endif - -ifeq ($(OS),Darwin) - CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache - MAC_SDK_VER ?= 10.6 - MAC_SDK := macosx$(MAC_SDK_VER) - SYSROOT := $(shell xcodebuild -sdk $(MAC_SDK) -version Path) - - ifneq ($(origin MAC_SDK_VER), file) - $(warning Attempting build with SDK version $(MAC_SDK_VER), only 10.6 is supported and recommended!) - endif - - ifeq ($(SYSROOT),) - FIRSTSDK := $(firstword $(sort $(shell xcodebuild -showsdks | grep macosx | sed 's/.*macosx//'))) - $(error Could not find SDK version $(MAC_SDK_VER). Install and configure Xcode 4.3, or build with: make MAC_SDK_VER=$(FIRSTSDK)) - endif - - ifeq ($(origin CC), default) - # Test to see if you have a compiler in the right place, if you - # don't abort with an error - CLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang) - ifeq ($(wildcard $(CLANG)),) - $(error Unable to find C compiler, install and configure Xcode 4.3) - endif - - CC := $(CCACHE) $(CLANG) -Qunused-arguments - endif - - ifeq ($(origin CXX), default) - CXXLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang++) - ifeq ($(wildcard $(CXXLANG)),) - $(error Unable to find C++ compiler, install and configure Xcode 4.3) - endif - - CXX := $(CCACHE) $(CXXLANG) -Qunused-arguments - endif - LINK ?= $(CXX) - - ifeq ($(origin AR), default) - AR := $(shell xcrun -sdk $(MAC_SDK) -find libtool) -static -o - endif - - ifeq ($(TARGET_PLATFORM),osx64) - ARCH_FLAGS += -arch x86_64 -m64 -march=core2 - else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags))) - ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2 - else - # dirty hack to build a universal binary - don't specify the architecture - ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2 - endif - - GEN_SYM ?= $(shell xcrun -sdk $(MAC_SDK) -find dsymutil) - ifeq ($(CFG),release) - STRIP ?= strip -S - else - STRIP ?= true - endif - ifeq ($(SOURCE_SDK), 1) - VSIGN ?= true - else - VSIGN ?= $(SRCROOT)/devtools/bin/vsign - endif - - CPPFLAGS += -I$(SYSROOT)/usr/include/malloc - CFLAGS += -isysroot $(SYSROOT) -mmacosx-version-min=10.5 -fasm-blocks - - LIB_START_EXE = -lm -ldl -lpthread - LIB_END_EXE = - - LIB_START_SHLIB = - LIB_END_SHLIB = - - SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms - - ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE))) - SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms - endif - -endif - -# -# Profile-directed optimizations. -# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%! -# -# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are. -# PROFILE_LINKER_FLAG=-fprofile-arcs -# PROFILE_COMPILER_FLAG=-fprofile-arcs -# -# Then, comment the above flags out again and rebuild with this flag uncommented: -# PROFILE_COMPILER_FLAG=-fprofile-use -# - -############################################################################# -# The compiler command lne for each src code file to compile -############################################################################# - -OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG) -CPP_TO_OBJ = $(CPPFILES:.cpp=.o) -CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o) -CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o) -MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o) -C_TO_OBJ = $(MM_TO_OBJ:.c=.o) -OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ))) - -ifeq ($(MAKE_VERBOSE),1) - QUIET_PREFIX = - QUIET_ECHO_POSTFIX = -else - QUIET_PREFIX = @ - QUIET_ECHO_POSTFIX = > /dev/null -endif - -ifeq ($(MAKE_CC_VERBOSE),1) -CC += -v -endif - -ifeq ($(CONFTYPE),lib) - LIB_File = $(OUTPUTFILE) -endif - -ifeq ($(CONFTYPE),dll) - SO_File = $(OUTPUTFILE) -endif - -ifeq ($(CONFTYPE),exe) - EXE_File = $(OUTPUTFILE) -endif - -# we generate dependencies as a side-effect of compilation now -GEN_DEP_FILE= - -PRE_COMPILE_FILE = - -POST_COMPILE_FILE = - -ifeq ($(BUILDING_MULTI_ARCH),1) - SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS)) - COMPILE_FILE = \ - $(QUIET_PREFIX) \ - echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\ - mkdir -p $(OBJ_DIR) && \ - $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \ - $(CXX) $(CXXFLAGS) -o $@ -c $< -else - COMPILE_FILE = \ - $(QUIET_PREFIX) \ - echo "---- $(lastword $(subst /, ,$<)) ----";\ - mkdir -p $(OBJ_DIR) && \ - $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< -endif - -ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined" - P4_EDIT_START = chmod -R +w - P4_EDIT_END = || true - P4_REVERT_START = true - P4_REVERT_END = -else - ifndef P4_EDIT_CHANGELIST - # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default - # setting is best, but here is an alternate example: - # export P4_EDIT_CHANGELIST_CMD="echo 1424335" - # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed. - P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1 - P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD)) - endif - ifeq ($(P4_EDIT_CHANGELIST),) - # If we haven't found a changelist to check out to then create one. The name must match the one from a few - # lines above or else a new changelist will be created each time. - # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be - # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which - # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command. - P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ') - endif - - P4_EDIT_START := for f in - P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) - P4_REVERT_START := for f in - P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX) -endif - -ifeq ($(CONFTYPE),dll) -all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE) - @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX) -else -all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE) - @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX) -endif - -.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile - - -rebuild : - $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove - $(MAKE) -f $(firstword $(MAKEFILE_LIST)) - - -# Use the relink target to force to relink the project. -relink: RemoveOutputFile all - -RemoveOutputFile: - rm -f $(OUTPUTFILE) - - -# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file. -# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that. -SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o - @echo "" - -RemoveSingleFile: - $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o - -clean: -ifneq "$(OBJ_DIR)" "" - $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" - $(QUIET_PREFIX) rm -rf $(OBJ_DIR) -endif -ifneq "$(OUTPUTFILE)" "" - $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ - echo "p4 revert $(OUTPUTFILE)"; \ - $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \ - fi; -endif -ifneq "$(OTHER_DEPENDENCIES)" "" - $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" - $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES) -endif -ifneq "$(GAMEOUTPUTFILE)" "" - $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)" - $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END) -endif - - -# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the -# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave -# us with archive files that have extra unused symbols, and also potentially cause compilation errors -# when you rename a file and have many duplicate symbols. -cleanandremove: -ifneq "$(OBJ_DIR)" "" - $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)" - $(QUIET_PREFIX) -rm -rf $(OBJ_DIR) -endif -ifneq "$(OUTPUTFILE)" "" - $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \ - echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \ - $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \ - fi; - $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT); -endif -ifneq "$(OTHER_DEPENDENCIES)" "" - $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)" - $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES) -endif -ifneq "$(GAMEOUTPUTFILE)" "" - $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)" - $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END) - $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE) -endif - - -# This just deletes the final targets so it'll do a relink next time we build. -cleantargets: - $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE) - - -$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS) - $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END); - $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES); - -SO_GameOutputFile = $(GAMEOUTPUTFILE) - -# Remove the target before installing a file over it; this prevents existing -# instances of the game from crashing due to the overwrite. -$(SO_GameOutputFile): $(SO_File) - $(QUIET_PREFIX) \ - $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \ - echo "----" $(QUIET_ECHO_POSTFIX);\ - echo "---- COPYING TO $@ [$(CFG)] ----";\ - echo "----" $(QUIET_ECHO_POSTFIX); - $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END); - $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null; - $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); - $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX); - $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); - $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE); - $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE); - $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE); - $(QUIET_PREFIX) if [ "$(COPY_DLL_TO_SRV)" = "1" ]; then\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - echo "---- COPYING TO $(Srv_GAMEOUTPUTFILE) ----";\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - cp -v $(GAMEOUTPUTFILE) $(Srv_GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);\ - cp -v $(GAMEOUTPUTFILE)$(SYM_EXT) $(Srv_GAMEOUTPUTFILE)$(SYM_EXT) $(QUIET_ECHO_POSTFIX);\ - fi; - $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \ - mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \ - cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \ - fi; - - -$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) - $(QUIET_PREFIX) \ - echo "----" $(QUIET_ECHO_POSTFIX);\ - echo "---- LINKING $@ [$(CFG)] ----";\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - \ - $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB); - $(VSIGN) -signvalve $(OUTPUTFILE); - - -$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES) - $(QUIET_PREFIX) \ - echo "----" $(QUIET_ECHO_POSTFIX);\ - echo "---- LINKING EXE $@ [$(CFG)] ----";\ - echo "----" $(QUIET_ECHO_POSTFIX);\ - \ - $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\ - $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE); - $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); - $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE); - $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE); - $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE); - - -tags: - etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx +#
+# Base makefile for Linux and OSX
+#
+# !!!!! Note to future editors !!!!!
+#
+# before you make changes, make sure you grok:
+# 1. the difference between =, :=, +=, and ?=
+# 2. how and when this base makefile gets included in the generated makefile(s)
+# ( see http://www.gnu.org/software/make/manual/make.html#Flavors )
+#
+# Command line prefixes:
+# - errors are ignored
+# @ command is not printed to stdout before being executed
+# + command is executed even if Make is invoked in "do not exec" mode
+
+OS := $(shell uname)
+HOSTNAME := $(shell hostname)
+
+-include $(SRCROOT)/devtools/steam_def.mak
+-include $(SRCROOT)/devtools/sourcesdk_def.mak
+
+# To build with clang, set the following in your environment:
+# CC = clang
+# CXX = clang++
+
+ifeq ($(CFG), release)
+ # With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3.
+ # There also was no speed difference running at 1280x1024. May 2012, mikesart.
+ # tonyp: The size increase was likely caused by -finline-functions and -fipa-cp-clone getting switched on with -O3.
+ # -fno-omit-frame-pointer: need this for stack traces with perf.
+ OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer -ftree-vectorize -fpredictive-commoning -funswitch-loops
+else
+ OptimizerLevel_CompilerSpecific = -O0
+ #-O1 -finline-functions
+endif
+
+# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags"
+ARCH_FLAGS =
+BUILDING_MULTI_ARCH = 0
+CPPFLAGS = $(DEFINES) $(addprefix -I, $(abspath $(INCLUDEDIRS) ))
+CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE
+# In -std=gnu++0x mode we get lots of errors about "error: narrowing conversion". -fpermissive
+# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+.
+ifeq ($(CXX),clang++)
+ CXXFLAGS = $(CFLAGS) -Wno-c++11-narrowing -Wno-dangling-else
+else
+ CXXFLAGS = $(CFLAGS) -fpermissive
+endif
+DEFINES += -DVPROF_LEVEL=1 -DGNUC -DNO_HOOK_MALLOC -DNO_MALLOC_OVERRIDE
+LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel)
+GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P)
+MAP_FLAGS =
+Srv_GAMEOUTPUTFILE =
+COPY_DLL_TO_SRV = 0
+
+
+ifeq ($(STEAM_BRANCH),1)
+ WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof
+else
+ WARN_FLAGS = -Wno-write-strings -Wno-multichar
+endif
+
+WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security
+
+
+ifeq ($(OS),Linux)
+ # We should always specify -Wl,--build-id, as documented at:
+ # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId
+ LDFLAGS += -Wl,--build-id
+ # Set USE_VALVE_BINDIR to build with /Steam/tools/linux in the /valve/bin path.
+ # Dedicated server uses this.
+ ifeq ($(USE_VALVE_BINDIR),1)
+ # dedicated server flags
+ ifeq ($(TARGET_PLATFORM),linux64)
+ VALVE_BINDIR = /valve/bin64/
+ MARCH_TARGET = nocona
+ else
+ VALVE_BINDIR = /valve/bin/
+ MARCH_TARGET = pentium4
+ endif
+ STRIP_FLAGS =
+ else
+ # linux desktop client flags
+ VALVE_BINDIR =
+ # If the steam-runtime is available, use it. We should just default to using it when
+ # buildbot and everyone has a bit of time to get it installed.
+ ifneq "$(wildcard /valve/steam-runtime/bin/)" ""
+ # The steam-runtime is incompatible with clang at this point, so disable it
+ # if clang is enabled.
+ ifneq ($(CXX),clang++)
+ VALVE_BINDIR = /valve/steam-runtime/bin/
+ endif
+ endif
+ GCC_VER =
+ MARCH_TARGET = pentium4
+ # On dedicated servers, some plugins depend on global variable symbols in addition to functions.
+ # So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2.
+ STRIP_FLAGS = -x
+ endif
+
+ ifeq ($(CXX),clang++)
+ # Clang does not support -mfpmath=sse because it uses whatever
+ # instruction set extensions are available by default.
+ SSE_GEN_FLAGS = -msse2
+ else
+ SSE_GEN_FLAGS = -msse2 -mfpmath=sse
+ endif
+
+ CCACHE := $(SRCROOT)/devtools/bin/linux/ccache
+
+ ifeq ($(origin GCC_VER), undefined)
+ GCC_VER=-4.6
+ endif
+ ifeq ($(origin AR), default)
+ AR = $(VALVE_BINDIR)ar crs
+ endif
+ ifeq ($(origin CC),default)
+ CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER)
+ endif
+ ifeq ($(origin CXX), default)
+ CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER)
+ endif
+ # Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to
+ # a ccache quirk. Could also upgrade ccache.
+ # http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html
+ ifeq ($(CC),clang)
+ CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments
+ endif
+ ifeq ($(CXX),clang++)
+ CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments
+ endif
+ LINK ?= $(CC)
+
+ ifeq ($(TARGET_PLATFORM),linux64)
+ # nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2)
+ ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2
+ LD_SO = ld-linux-x86_64.so.2
+ LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.a)
+ LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++-pic.a)
+ else
+ # pentium4 = MMX, SSE, SSE2 - no SSE3 (added in prescott) # -msse3 -mfpmath=sse
+ ARCH_FLAGS += -m32 -march=$(MARCH_TARGET) -mtune=core2 $(SSE_GEN_FLAGS)
+ LD_SO = ld-linux.so.2
+ LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so)
+ LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.so)
+ LDFLAGS += -m32
+ endif
+
+ GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh
+ ifeq ($(CFG),release)
+ STRIP ?= strip $(STRIP_FLAGS) -S
+ # CFLAGS += -ffunction-sections -fdata-sections
+ # LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections
+ else
+ STRIP ?= true
+ endif
+ VSIGN ?= true
+
+ ifeq ($(SOURCE_SDK), 1)
+ Srv_GAMEOUTPUTFILE := $(GAMEOUTPUTFILE:.so=_srv.so)
+ COPY_DLL_TO_SRV := 1
+ endif
+
+ LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map
+
+ SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined
+
+ _WRAP := -Xlinker --wrap=
+ PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \
+ $(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \
+ $(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \
+ $(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \
+ $(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath
+
+ LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group
+ LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread
+
+ LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group
+ LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt
+
+endif
+
+ifeq ($(OS),Darwin)
+ CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache
+ MAC_SDK_VER ?= 10.6
+ MAC_SDK := macosx$(MAC_SDK_VER)
+ SYSROOT := $(shell xcodebuild -sdk $(MAC_SDK) -version Path)
+
+ ifneq ($(origin MAC_SDK_VER), file)
+ $(warning Attempting build with SDK version $(MAC_SDK_VER), only 10.6 is supported and recommended!)
+ endif
+
+ ifeq ($(SYSROOT),)
+ FIRSTSDK := $(firstword $(sort $(shell xcodebuild -showsdks | grep macosx | sed 's/.*macosx//')))
+ $(error Could not find SDK version $(MAC_SDK_VER). Install and configure Xcode 4.3, or build with: make MAC_SDK_VER=$(FIRSTSDK))
+ endif
+
+ ifeq ($(origin CC), default)
+ # Test to see if you have a compiler in the right place, if you
+ # don't abort with an error
+ CLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang)
+ ifeq ($(wildcard $(CLANG)),)
+ $(error Unable to find C compiler, install and configure Xcode 4.3)
+ endif
+
+ CC := $(CCACHE) $(CLANG) -Qunused-arguments
+ endif
+
+ ifeq ($(origin CXX), default)
+ CXXLANG := $(shell xcrun -sdk $(MAC_SDK) -find clang++)
+ ifeq ($(wildcard $(CXXLANG)),)
+ $(error Unable to find C++ compiler, install and configure Xcode 4.3)
+ endif
+
+ CXX := $(CCACHE) $(CXXLANG) -Qunused-arguments
+ endif
+ LINK ?= $(CXX)
+
+ ifeq ($(origin AR), default)
+ AR := $(shell xcrun -sdk $(MAC_SDK) -find libtool) -static -o
+ endif
+
+ ifeq ($(TARGET_PLATFORM),osx64)
+ ARCH_FLAGS += -arch x86_64 -m64 -march=core2
+ else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags)))
+ ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2
+ else
+ # dirty hack to build a universal binary - don't specify the architecture
+ ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2
+ endif
+
+ GEN_SYM ?= $(shell xcrun -sdk $(MAC_SDK) -find dsymutil)
+ ifeq ($(CFG),release)
+ STRIP ?= strip -S
+ else
+ STRIP ?= true
+ endif
+ ifeq ($(SOURCE_SDK), 1)
+ VSIGN ?= true
+ else
+ VSIGN ?= $(SRCROOT)/devtools/bin/vsign
+ endif
+
+ CPPFLAGS += -I$(SYSROOT)/usr/include/malloc
+ CFLAGS += -isysroot $(SYSROOT) -mmacosx-version-min=10.5 -fasm-blocks
+
+ LIB_START_EXE = -lm -ldl -lpthread
+ LIB_END_EXE =
+
+ LIB_START_SHLIB =
+ LIB_END_SHLIB =
+
+ SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms
+
+ ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE)))
+ SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms
+ endif
+
+endif
+
+#
+# Profile-directed optimizations.
+# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%!
+#
+# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are.
+# PROFILE_LINKER_FLAG=-fprofile-arcs
+# PROFILE_COMPILER_FLAG=-fprofile-arcs
+#
+# Then, comment the above flags out again and rebuild with this flag uncommented:
+# PROFILE_COMPILER_FLAG=-fprofile-use
+#
+
+#############################################################################
+# The compiler command lne for each src code file to compile
+#############################################################################
+
+OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG)
+CPP_TO_OBJ = $(CPPFILES:.cpp=.o)
+CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o)
+CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o)
+MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o)
+C_TO_OBJ = $(MM_TO_OBJ:.c=.o)
+OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ)))
+
+ifeq ($(MAKE_VERBOSE),1)
+ QUIET_PREFIX =
+ QUIET_ECHO_POSTFIX =
+else
+ QUIET_PREFIX = @
+ QUIET_ECHO_POSTFIX = > /dev/null
+endif
+
+ifeq ($(MAKE_CC_VERBOSE),1)
+CC += -v
+endif
+
+ifeq ($(CONFTYPE),lib)
+ LIB_File = $(OUTPUTFILE)
+endif
+
+ifeq ($(CONFTYPE),dll)
+ SO_File = $(OUTPUTFILE)
+endif
+
+ifeq ($(CONFTYPE),exe)
+ EXE_File = $(OUTPUTFILE)
+endif
+
+# we generate dependencies as a side-effect of compilation now
+GEN_DEP_FILE=
+
+PRE_COMPILE_FILE =
+
+POST_COMPILE_FILE =
+
+ifeq ($(BUILDING_MULTI_ARCH),1)
+ SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS))
+ COMPILE_FILE = \
+ $(QUIET_PREFIX) \
+ echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\
+ mkdir -p $(OBJ_DIR) && \
+ $(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \
+ $(CXX) $(CXXFLAGS) -o $@ -c $<
+else
+ COMPILE_FILE = \
+ $(QUIET_PREFIX) \
+ echo "---- $(lastword $(subst /, ,$<)) ----";\
+ mkdir -p $(OBJ_DIR) && \
+ $(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $<
+endif
+
+ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined"
+ P4_EDIT_START = chmod -R +w
+ P4_EDIT_END = || true
+ P4_REVERT_START = true
+ P4_REVERT_END =
+else
+ ifndef P4_EDIT_CHANGELIST
+ # You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default
+ # setting is best, but here is an alternate example:
+ # export P4_EDIT_CHANGELIST_CMD="echo 1424335"
+ # ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed.
+ P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1
+ P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD))
+ endif
+ ifeq ($(P4_EDIT_CHANGELIST),)
+ # If we haven't found a changelist to check out to then create one. The name must match the one from a few
+ # lines above or else a new changelist will be created each time.
+ # Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be
+ # interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which
+ # confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command.
+ P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ')
+ endif
+
+ P4_EDIT_START := for f in
+ P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX)
+ P4_REVERT_START := for f in
+ P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX)
+endif
+
+ifeq ($(CONFTYPE),dll)
+all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE)
+ @echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX)
+else
+all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE)
+ @echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX)
+endif
+
+.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile
+
+
+rebuild :
+ $(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove
+ $(MAKE) -f $(firstword $(MAKEFILE_LIST))
+
+
+# Use the relink target to force to relink the project.
+relink: RemoveOutputFile all
+
+RemoveOutputFile:
+ rm -f $(OUTPUTFILE)
+
+
+# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file.
+# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that.
+SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o
+ @echo ""
+
+RemoveSingleFile:
+ $(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o
+
+clean:
+ifneq "$(OBJ_DIR)" ""
+ $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)"
+ $(QUIET_PREFIX) rm -rf $(OBJ_DIR)
+endif
+ifneq "$(OUTPUTFILE)" ""
+ $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \
+ echo "p4 revert $(OUTPUTFILE)"; \
+ $(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \
+ fi;
+endif
+ifneq "$(OTHER_DEPENDENCIES)" ""
+ $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)"
+ $(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES)
+endif
+ifneq "$(GAMEOUTPUTFILE)" ""
+ $(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)"
+ $(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END)
+endif
+
+
+# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the
+# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave
+# us with archive files that have extra unused symbols, and also potentially cause compilation errors
+# when you rename a file and have many duplicate symbols.
+cleanandremove:
+ifneq "$(OBJ_DIR)" ""
+ $(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)"
+ $(QUIET_PREFIX) -rm -rf $(OBJ_DIR)
+endif
+ifneq "$(OUTPUTFILE)" ""
+ $(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \
+ echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \
+ $(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \
+ fi;
+ $(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT);
+endif
+ifneq "$(OTHER_DEPENDENCIES)" ""
+ $(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)"
+ $(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES)
+endif
+ifneq "$(GAMEOUTPUTFILE)" ""
+ $(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)"
+ $(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END)
+ $(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE)
+endif
+
+
+# This just deletes the final targets so it'll do a relink next time we build.
+cleantargets:
+ $(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE)
+
+
+$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS)
+ $(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END);
+ $(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES);
+
+SO_GameOutputFile = $(GAMEOUTPUTFILE)
+
+# Remove the target before installing a file over it; this prevents existing
+# instances of the game from crashing due to the overwrite.
+$(SO_GameOutputFile): $(SO_File)
+ $(QUIET_PREFIX) \
+ $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ echo "---- COPYING TO $@ [$(CFG)] ----";\
+ echo "----" $(QUIET_ECHO_POSTFIX);
+ $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END);
+ $(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null;
+ $(QUIET_PREFIX) rm -f $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);
+ $(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);
+ $(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END);
+ $(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE);
+ $(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE);
+ $(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE);
+ $(QUIET_PREFIX) if [ "$(COPY_DLL_TO_SRV)" = "1" ]; then\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ echo "---- COPYING TO $(Srv_GAMEOUTPUTFILE) ----";\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ cp -v $(GAMEOUTPUTFILE) $(Srv_GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);\
+ cp -v $(GAMEOUTPUTFILE)$(SYM_EXT) $(Srv_GAMEOUTPUTFILE)$(SYM_EXT) $(QUIET_ECHO_POSTFIX);\
+ fi;
+ $(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ $(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \
+ mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \
+ cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \
+ fi;
+
+
+$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES)
+ $(QUIET_PREFIX) \
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ echo "---- LINKING $@ [$(CFG)] ----";\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ \
+ $(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB);
+ $(VSIGN) -signvalve $(OUTPUTFILE);
+
+
+$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES)
+ $(QUIET_PREFIX) \
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ echo "---- LINKING EXE $@ [$(CFG)] ----";\
+ echo "----" $(QUIET_ECHO_POSTFIX);\
+ \
+ $(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\
+ $(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE);
+ $(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END);
+ $(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE);
+ $(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE);
+ $(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE);
+
+
+tags:
+ etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx
diff --git a/mp/src/dx10sdk/Utilities/dx9_30/dx_proxy.dll b/mp/src/dx10sdk/Utilities/dx9_30/dx_proxy.dll Binary files differnew file mode 100644 index 00000000..d76adbc0 --- /dev/null +++ b/mp/src/dx10sdk/Utilities/dx9_30/dx_proxy.dll diff --git a/mp/src/dx9sdk/utilities/dx_proxy.dll b/mp/src/dx9sdk/utilities/dx_proxy.dll Binary files differnew file mode 100644 index 00000000..676a897d --- /dev/null +++ b/mp/src/dx9sdk/utilities/dx_proxy.dll diff --git a/mp/src/game/client/c_baseanimating.cpp b/mp/src/game/client/c_baseanimating.cpp index 137923d4..1086c301 100644 --- a/mp/src/game/client/c_baseanimating.cpp +++ b/mp/src/game/client/c_baseanimating.cpp @@ -1543,6 +1543,8 @@ void C_BaseAnimating::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quater ApplyBoneMatrixTransform( GetBoneForWrite( i ) );
}
}
+
+
}
//-----------------------------------------------------------------------------
@@ -3233,7 +3235,7 @@ int C_BaseAnimating::InternalDrawModel( int flags ) if ( !GetModelPtr() )
return 0;
- UpdateBoneAttachments( flags );
+ UpdateBoneAttachments( );
if ( IsEffectActive( EF_ITEM_BLINK ) )
{
@@ -6255,7 +6257,7 @@ bool C_BaseAnimating::ShouldResetSequenceOnNewModel( void ) //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
-void C_BaseAnimating::UpdateBoneAttachments( int flags )
+void C_BaseAnimating::UpdateBoneAttachments( void )
{
if ( !m_pAttachedTo )
return;
diff --git a/mp/src/game/client/c_baseanimating.h b/mp/src/game/client/c_baseanimating.h index d1c99868..5f30d8f8 100644 --- a/mp/src/game/client/c_baseanimating.h +++ b/mp/src/game/client/c_baseanimating.h @@ -228,7 +228,7 @@ public: int GetNumBoneAttachments();
C_BaseAnimating* GetBoneAttachment( int i );
virtual void NotifyBoneAttached( C_BaseAnimating* attachTarget );
- virtual void UpdateBoneAttachments( int flags );
+ virtual void UpdateBoneAttachments( void );
//bool solveIK(float a, float b, const Vector &Foot, const Vector &Knee1, Vector &Knee2);
//void DebugIK( mstudioikchain_t *pikchain );
diff --git a/mp/src/game/client/c_baseentity.h b/mp/src/game/client/c_baseentity.h index 955e80c5..3ea4b7fd 100644 --- a/mp/src/game/client/c_baseentity.h +++ b/mp/src/game/client/c_baseentity.h @@ -743,6 +743,7 @@ public: virtual void SetHealth(int iHealth) {}
virtual int GetHealth() const { return 0; }
virtual int GetMaxHealth() const { return 1; }
+ virtual bool IsVisibleToTargetID( void ) { return false; }
// Returns the health fraction
float HealthFraction() const;
@@ -1004,6 +1005,7 @@ public: virtual bool IsBaseObject( void ) const { return false; }
virtual bool IsBaseCombatWeapon( void ) const { return false; }
virtual class C_BaseCombatWeapon *MyCombatWeaponPointer() { return NULL; }
+ virtual bool IsCombatItem( void ) const { return false; }
virtual bool IsBaseTrain( void ) const { return false; }
diff --git a/mp/src/game/client/c_team_objectiveresource.cpp b/mp/src/game/client/c_team_objectiveresource.cpp index 7d31036d..e0412d27 100644 --- a/mp/src/game/client/c_team_objectiveresource.cpp +++ b/mp/src/game/client/c_team_objectiveresource.cpp @@ -87,7 +87,10 @@ IMPLEMENT_CLIENTCLASS_DT_NOBASE(C_BaseTeamObjectiveResource, DT_BaseTeamObjectiv RecvPropArray3( RECVINFO_ARRAY(m_iTeamInZone), RecvPropInt( RECVINFO(m_iTeamInZone[0]) ) ),
RecvPropArray3( RECVINFO_ARRAY(m_bBlocked), RecvPropInt( RECVINFO(m_bBlocked[0]) ) ),
RecvPropArray3( RECVINFO_ARRAY(m_iOwner), RecvPropInt( RECVINFO(m_iOwner[0]), 0, RecvProxy_Owner ) ),
+ RecvPropArray3( RECVINFO_ARRAY(m_bCPCapRateScalesWithPlayers), RecvPropBool( RECVINFO(m_bCPCapRateScalesWithPlayers[0]) ) ),
RecvPropString( RECVINFO(m_pszCapLayoutInHUD), 0, RecvProxy_CapLayout ),
+ RecvPropFloat( RECVINFO(m_flCustomPositionX) ),
+ RecvPropFloat( RECVINFO(m_flCustomPositionY) ),
END_RECV_TABLE()
C_BaseTeamObjectiveResource *g_pObjectiveResource = NULL;
@@ -151,6 +154,9 @@ C_BaseTeamObjectiveResource::C_BaseTeamObjectiveResource() m_flNodeHillData[i] = 0;
}
+ m_flCustomPositionX = -1.f;
+ m_flCustomPositionY = -1.f;
+
g_pObjectiveResource = this;
}
@@ -173,6 +179,9 @@ void C_BaseTeamObjectiveResource::OnPreDataChanged( DataUpdateType_t updateType m_iOldUpdateCapHudParity = m_iUpdateCapHudParity;
m_bOldControlPointsReset = m_bControlPointsReset;
+ m_flOldCustomPositionX = m_flCustomPositionX;
+ m_flOldCustomPositionY = m_flCustomPositionY;
+
memcpy( m_flOldLazyCapPerc, m_flLazyCapPerc, sizeof(float)*m_iNumControlPoints );
memcpy( m_flOldUnlockTimes, m_flUnlockTimes, sizeof(float)*m_iNumControlPoints );
memcpy( m_flOldCPTimerTimes, m_flCPTimerTimes, sizeof(float)*m_iNumControlPoints );
@@ -229,6 +238,11 @@ void C_BaseTeamObjectiveResource::OnDataChanged( DataUpdateType_t updateType ) }
}
}
+
+ if ( m_flOldCustomPositionX != m_flCustomPositionX || m_flOldCustomPositionY != m_flCustomPositionY )
+ {
+ UpdateControlPoint( "controlpoint_updatelayout" );
+ }
}
//-----------------------------------------------------------------------------
@@ -373,7 +387,7 @@ void C_BaseTeamObjectiveResource::ClientThink() if ( iPlayersCapping > 0 )
{
float flReduction = gpGlobals->curtime - m_flCapLastThinkTime[i];
- if ( mp_capstyle.GetInt() == 1 )
+ if ( mp_capstyle.GetInt() == 1 && m_bCPCapRateScalesWithPlayers[i] )
{
// Diminishing returns for successive players.
for ( int iPlayer = 1; iPlayer < iPlayersCapping; iPlayer++ )
@@ -423,7 +437,8 @@ void C_BaseTeamObjectiveResource::ClientThink() if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->TeamMayCapturePoint(m_iCappingTeam[i],i) )
{
float flCapLength = m_flTeamCapTime[ TEAM_ARRAY(i,m_iCappingTeam[i]) ];
- float flDecrease = (flCapLength / mp_capdeteriorate_time.GetFloat()) * (gpGlobals->curtime - m_flCapLastThinkTime[i]);
+ float flDecreaseScale = m_bCPCapRateScalesWithPlayers[i] ? mp_capdeteriorate_time.GetFloat() : flCapLength;
+ float flDecrease = (flCapLength / flDecreaseScale) * (gpGlobals->curtime - m_flCapLastThinkTime[i]);
if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->InOvertime() )
{
flDecrease *= 6;
diff --git a/mp/src/game/client/c_team_objectiveresource.h b/mp/src/game/client/c_team_objectiveresource.h index ca75d8dc..588971c3 100644 --- a/mp/src/game/client/c_team_objectiveresource.h +++ b/mp/src/game/client/c_team_objectiveresource.h @@ -163,6 +163,7 @@ public: }
const char *GetCapLayoutInHUD( void ) { return m_pszCapLayoutInHUD; }
+ void GetCapLayoutCustomPosition( float& flCustomPositionX, float& flCustomPositionY ) { flCustomPositionX = m_flCustomPositionX; flCustomPositionY = m_flCustomPositionY; }
bool PlayingMiniRounds( void ){ return m_bPlayingMiniRounds; }
bool IsInMiniRound( int index ) { return m_bInMiniRound[index]; }
@@ -313,6 +314,7 @@ protected: int m_iTeamInZone[MAX_CONTROL_POINTS];
bool m_bBlocked[MAX_CONTROL_POINTS];
int m_iOwner[MAX_CONTROL_POINTS];
+ bool m_bCPCapRateScalesWithPlayers[MAX_CONTROL_POINTS];
// client calculated state
float m_flCapTimeLeft[MAX_CONTROL_POINTS];
@@ -321,6 +323,10 @@ protected: bool m_bWarnedOnFinalCap[MAX_CONTROL_POINTS];
float m_flLastCapWarningTime[MAX_CONTROL_POINTS];
char m_pszCapLayoutInHUD[MAX_CAPLAYOUT_LENGTH];
+ float m_flOldCustomPositionX;
+ float m_flOldCustomPositionY;
+ float m_flCustomPositionX;
+ float m_flCustomPositionY;
// hill data for multi-escort payload maps
int m_nNumNodeHillData[TEAM_TRAIN_MAX_TEAMS];
diff --git a/mp/src/game/client/cdll_client_int.cpp b/mp/src/game/client/cdll_client_int.cpp index 0e96b11c..c8f7f40b 100644 --- a/mp/src/game/client/cdll_client_int.cpp +++ b/mp/src/game/client/cdll_client_int.cpp @@ -104,6 +104,7 @@ #include "replay/vgui/replayperformanceeditor.h"
#endif
#include "vgui/ILocalize.h"
+#include "vgui/IVGui.h"
#include "ixboxsystem.h"
#include "ipresence.h"
#include "engine/imatchmaking.h"
@@ -982,6 +983,8 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi g_pSourceVR->GetViewportBounds( ISourceVirtualReality::VREye_Left, NULL, NULL, &nViewportWidth, &nViewportHeight );
vgui::surface()->SetFullscreenViewport( 0, 0, nViewportWidth, nViewportHeight );
+
+ vgui::ivgui()->SetVRMode( true );
}
if (!Initializer::InitializeAllObjects())
diff --git a/mp/src/game/client/client_virtualreality.cpp b/mp/src/game/client/client_virtualreality.cpp index 69f6e63a..1eb59a59 100644 --- a/mp/src/game/client/client_virtualreality.cpp +++ b/mp/src/game/client/client_virtualreality.cpp @@ -635,34 +635,6 @@ bool CClientVirtualReality::OverrideStereoView( CViewSetup *pViewMiddle, CViewSe g_pSourceVR->GetEyeProjectionMatrix ( &pViewLeft->m_ViewToProjection, ISourceVirtualReality::VREye_Left, pViewMiddle->zNear, pViewMiddle->zFar, 1.0f/headtrackFovScale );
g_pSourceVR->GetEyeProjectionMatrix ( &pViewRight->m_ViewToProjection, ISourceVirtualReality::VREye_Right, pViewMiddle->zNear, pViewMiddle->zFar, 1.0f/headtrackFovScale );
- static ConVarRef vr_distortion_grow_outside( "vr_distortion_grow_outside" );
- static ConVarRef vr_distortion_grow_inside( "vr_distortion_grow_inside" );
- static ConVarRef vr_distortion_grow_above( "vr_distortion_grow_above" );
- static ConVarRef vr_distortion_grow_below( "vr_distortion_grow_below" );
-
- float StereoDistortionGrowOutside = vr_distortion_grow_outside.GetFloat();
- float StereoDistortionGrowInside = vr_distortion_grow_inside.GetFloat();
- float StereoDistortionGrowAbove = vr_distortion_grow_above.GetFloat();
- float StereoDistortionGrowBelow = vr_distortion_grow_below.GetFloat();
- if ( ( StereoDistortionGrowOutside != 0.0f ) || (StereoDistortionGrowInside != 0.0f ) )
- {
- float ScaleX = 2.0f / ( StereoDistortionGrowInside + StereoDistortionGrowOutside + 2.0f );
- float OffsetX = 0.5f * ScaleX * ( StereoDistortionGrowInside - StereoDistortionGrowOutside );
- pViewLeft ->m_ViewToProjection.m[0][0] *= ScaleX;
- pViewLeft ->m_ViewToProjection.m[0][2] = ( pViewLeft ->m_ViewToProjection.m[0][2] * ScaleX ) + OffsetX;
- pViewRight->m_ViewToProjection.m[0][0] *= ScaleX;
- pViewRight->m_ViewToProjection.m[0][2] = ( pViewRight->m_ViewToProjection.m[0][2] * ScaleX ) - OffsetX;
- }
- if ( ( StereoDistortionGrowAbove != 0.0f ) || (StereoDistortionGrowBelow != 0.0f ) )
- {
- float ScaleY = 2.0f / ( StereoDistortionGrowBelow + StereoDistortionGrowAbove + 2.0f );
- float OffsetY = -0.5f * ScaleY * ( StereoDistortionGrowBelow - StereoDistortionGrowAbove ); // Why is this -0.5 and not +0.5? I wish I knew.
- pViewLeft ->m_ViewToProjection.m[1][1] *= ScaleY;
- pViewLeft ->m_ViewToProjection.m[1][2] = ( pViewLeft ->m_ViewToProjection.m[1][2] * ScaleY ) + OffsetY;
- pViewRight->m_ViewToProjection.m[1][1] *= ScaleY;
- pViewRight->m_ViewToProjection.m[1][2] = ( pViewRight->m_ViewToProjection.m[1][2] * ScaleY ) + OffsetY;
- }
-
// And bodge together some sort of average for our cyclops friends.
pViewMiddle->m_bViewToProjectionOverride = true;
for ( int i = 0; i < 4; i++ )
diff --git a/mp/src/game/client/glow_outline_effect.cpp b/mp/src/game/client/glow_outline_effect.cpp index 600b15d7..a6d80b7f 100644 --- a/mp/src/game/client/glow_outline_effect.cpp +++ b/mp/src/game/client/glow_outline_effect.cpp @@ -312,37 +312,20 @@ void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int n void CGlowObjectManager::GlowObjectDefinition_t::DrawModel()
{
- C_BaseEntity *pEntity = m_hEntity.Get();
- if ( !pEntity )
- return;
-
- if ( pEntity->GetMoveParent() != NULL )
+ if ( m_hEntity.Get() )
{
- C_BaseAnimating *pBaseAnimating = pEntity->GetBaseAnimating();
- if ( pBaseAnimating )
- {
- pBaseAnimating->InvalidateBoneCache();
- }
- }
+ m_hEntity->DrawModel( STUDIO_RENDER );
+ C_BaseEntity *pAttachment = m_hEntity->FirstMoveChild();
- pEntity->DrawModel( STUDIO_RENDER );
-
- C_BaseEntity *pAttachment = pEntity->FirstMoveChild();
- while ( pAttachment != NULL )
- {
- if ( !g_GlowObjectManager.HasGlowEffect( pAttachment ) && pAttachment->ShouldDraw() )
+ while ( pAttachment != NULL )
{
- C_BaseAnimating *pBaseAnimating = pAttachment->GetBaseAnimating();
- if ( pBaseAnimating )
+ if ( !g_GlowObjectManager.HasGlowEffect( pAttachment ) && pAttachment->ShouldDraw() )
{
- pBaseAnimating->InvalidateBoneCache();
+ pAttachment->DrawModel( STUDIO_RENDER );
}
-
- pAttachment->DrawModel( STUDIO_RENDER );
+ pAttachment = pAttachment->NextMovePeer();
}
-
- pAttachment = pAttachment->NextMovePeer();
}
}
-#endif // GLOWS_ENABLE
+#endif // GLOWS_ENABLE
\ No newline at end of file diff --git a/mp/src/game/client/hud_controlpointicons.cpp b/mp/src/game/client/hud_controlpointicons.cpp index 20d6150b..a8c390ae 100644 --- a/mp/src/game/client/hud_controlpointicons.cpp +++ b/mp/src/game/client/hud_controlpointicons.cpp @@ -1107,7 +1107,23 @@ void CHudControlPointIcons::PerformLayout( void ) }
// Setup the main panel
- SetBounds( (ScreenWidth() - iWidest) * 0.5, ScreenHeight() - iTall - m_nHeightOffset, iWidest, iTall );
+ float flPositionX = (ScreenWidth() - iWidest) * 0.5;
+ float flPositionY = ScreenHeight() - iTall - m_nHeightOffset;
+ if ( ObjectiveResource() )
+ {
+ float flCustomPositionX = -1.f;
+ float flCustomPositionY = -1.f;
+ ObjectiveResource()->GetCapLayoutCustomPosition( flCustomPositionX, flCustomPositionY );
+ if ( flCustomPositionX != -1.f )
+ {
+ flPositionX = flCustomPositionX * ScreenWidth();
+ }
+ if ( flCustomPositionY != -1.f )
+ {
+ flPositionY = flCustomPositionY * ScreenHeight();
+ }
+ }
+ SetBounds( flPositionX, flPositionY, iWidest, iTall );
// Now that we know how wide we are, and how many icons are in each line,
// we can lay the icons out, centered in the lines.
diff --git a/mp/src/game/client/in_mouse.cpp b/mp/src/game/client/in_mouse.cpp index 207e7508..16cdd15e 100644 --- a/mp/src/game/client/in_mouse.cpp +++ b/mp/src/game/client/in_mouse.cpp @@ -10,9 +10,6 @@ #define _WIN32_WINNT 0x0502
#include <windows.h>
#endif
-#ifdef OSX
-#include <Carbon/Carbon.h>
-#endif
#include "cbase.h"
#include "hud.h"
#include "cdll_int.h"
@@ -105,12 +102,7 @@ static ConVar m_mousespeed( "m_mousespeed", "1", FCVAR_ARCHIVE, "Windows mouse a static ConVar m_mouseaccel1( "m_mouseaccel1", "0", FCVAR_ARCHIVE, "Windows mouse acceleration initial threshold (2x movement).", true, 0, false, 0.0f );
static ConVar m_mouseaccel2( "m_mouseaccel2", "0", FCVAR_ARCHIVE, "Windows mouse acceleration secondary threshold (4x movement).", true, 0, false, 0.0f );
-#if defined( OSX )
-// On OSX, this needs to stick at 0.
-static ConVar m_rawinput( "m_rawinput", "0", FCVAR_ARCHIVE, "Raw Mouse input is unavailable on OSX", true, 0.0, true, 0.0);
-#else
static ConVar m_rawinput( "m_rawinput", "0", FCVAR_ARCHIVE, "Use Raw Input for mouse input.");
-#endif
#if DEBUG
ConVar cl_mouselook( "cl_mouselook", "1", FCVAR_ARCHIVE, "Set to 1 to use mouse for look, 0 for keyboard look." );
@@ -604,7 +596,7 @@ void CInput::AccumulateMouse( void ) m_flAccumulatedMouseXMovement += current_posx - x;
m_flAccumulatedMouseYMovement += current_posy - y;
-#elif defined( USE_SDL ) || defined( OSX )
+#elif defined( USE_SDL )
int dx, dy;
engine->GetMouseDelta( dx, dy );
m_flAccumulatedMouseXMovement += dx;
diff --git a/mp/src/game/client/input.h b/mp/src/game/client/input.h index bd371c80..00bbb02f 100644 --- a/mp/src/game/client/input.h +++ b/mp/src/game/client/input.h @@ -18,7 +18,7 @@ #include "ehandle.h"
#include "inputsystem/AnalogCode.h"
-typedef unsigned long CRC32_t;
+typedef unsigned int CRC32_t;
//-----------------------------------------------------------------------------
// Purpose:
diff --git a/mp/src/game/server/ai_activity.cpp b/mp/src/game/server/ai_activity.cpp index ba9c8432..25e5c441 100644 --- a/mp/src/game/server/ai_activity.cpp +++ b/mp/src/game/server/ai_activity.cpp @@ -2147,4 +2147,10 @@ void CAI_BaseNPC::InitDefaultActivitySR(void) ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_CROUCH_PRIMARY3_END );
ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_AIRWALK_PRIMARY3_END );
ADD_ACTIVITY_TO_SR( ACT_MP_RELOAD_SWIM_PRIMARY3 );
+
+ ADD_ACTIVITY_TO_SR( ACT_MP_THROW );
+ ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_DRAW );
+ ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_IDLE );
+ ADD_ACTIVITY_TO_SR( ACT_THROWABLE_VM_FIRE );
+
}
diff --git a/mp/src/game/server/ai_networkmanager.cpp b/mp/src/game/server/ai_networkmanager.cpp index 953e2884..00826e02 100644 --- a/mp/src/game/server/ai_networkmanager.cpp +++ b/mp/src/game/server/ai_networkmanager.cpp @@ -2633,7 +2633,7 @@ void CAI_NetworkBuilder::InitVisibility(CAI_Network *pNetwork, CAI_Node *pNode) if ( DebuggingConnect( pNode->m_iID, testnode ) )
{
- DevMsg( "" ); // break here..
+ DevMsg( " " ); // break here..
}
// We know we can view ourself
@@ -2814,7 +2814,7 @@ void CAI_NetworkBuilder::InitNeighbors(CAI_Network *pNetwork, CAI_Node *pNode) {
if ( DebuggingConnect( pNode->m_iID, checknode ) )
{
- DevMsg( "" ); // break here..
+ DevMsg( " " ); // break here..
}
// I'm not a neighbor of myself
@@ -3204,7 +3204,7 @@ void CAI_NetworkBuilder::InitLinks(CAI_Network *pNetwork, CAI_Node *pNode) if ( DebuggingConnect( pNode->m_iID, i ) )
{
- DevMsg( "" ); // break here..
+ DevMsg( " " ); // break here..
}
if ( !(pNode->m_eNodeInfo & bits_NODE_FALLEN) && !(pDestNode->m_eNodeInfo & bits_NODE_FALLEN) )
diff --git a/mp/src/game/server/basecombatcharacter.cpp b/mp/src/game/server/basecombatcharacter.cpp index 58767184..7fb5cce1 100644 --- a/mp/src/game/server/basecombatcharacter.cpp +++ b/mp/src/game/server/basecombatcharacter.cpp @@ -3522,6 +3522,10 @@ void CBaseCombatCharacter::ChangeTeam( int iTeamNum ) // old team member no longer in the nav mesh
ClearLastKnownArea();
+#ifdef GLOWS_ENABLE
+ RemoveGlowEffect();
+#endif // GLOWS_ENABLE
+
BaseClass::ChangeTeam( iTeamNum );
}
diff --git a/mp/src/game/server/baseentity.h b/mp/src/game/server/baseentity.h index 26d81804..016915ca 100644 --- a/mp/src/game/server/baseentity.h +++ b/mp/src/game/server/baseentity.h @@ -948,6 +948,7 @@ public: bool IsBSPModel() const;
bool IsCombatCharacter() { return MyCombatCharacterPointer() == NULL ? false : true; }
bool IsInWorld( void ) const;
+ virtual bool IsCombatItem( void ) const { return false; }
virtual bool IsBaseCombatWeapon( void ) const { return false; }
virtual bool IsWearable( void ) const { return false; }
diff --git a/mp/src/game/server/cbase.cpp b/mp/src/game/server/cbase.cpp index f1f9b0d6..944e6841 100644 --- a/mp/src/game/server/cbase.cpp +++ b/mp/src/game/server/cbase.cpp @@ -278,14 +278,32 @@ void CBaseEntityOutput::FireOutput(variant_t Value, CBaseEntity *pActivator, CBa if ( ev->m_flDelay )
{
char szBuffer[256];
- Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) output: (%s,%s) -> (%s,%s,%.1f)(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), ev->m_flDelay, STRING(ev->m_iParameter) );
+ Q_snprintf( szBuffer,
+ sizeof(szBuffer),
+ "(%0.2f) output: (%s,%s) -> (%s,%s,%.1f)(%s)\n",
+ engine->GetServerTime(),
+ pCaller ? STRING(pCaller->m_iClassname) : "NULL",
+ pCaller ? STRING(pCaller->GetEntityName()) : "NULL",
+ STRING(ev->m_iTarget),
+ STRING(ev->m_iTargetInput),
+ ev->m_flDelay,
+ STRING(ev->m_iParameter) );
+
DevMsg( 2, "%s", szBuffer );
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
}
else
{
char szBuffer[256];
- Q_snprintf( szBuffer, sizeof(szBuffer), "(%0.2f) output: (%s,%s) -> (%s,%s)(%s)\n", gpGlobals->curtime, pCaller ? STRING(pCaller->m_iClassname) : "NULL", pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget), STRING(ev->m_iTargetInput), STRING(ev->m_iParameter) );
+ Q_snprintf( szBuffer,
+ sizeof(szBuffer),
+ "(%0.2f) output: (%s,%s) -> (%s,%s)(%s)\n",
+ engine->GetServerTime(),
+ pCaller ? STRING(pCaller->m_iClassname) : "NULL",
+ pCaller ? STRING(pCaller->GetEntityName()) : "NULL", STRING(ev->m_iTarget),
+ STRING(ev->m_iTargetInput),
+ STRING(ev->m_iParameter) );
+
DevMsg( 2, "%s", szBuffer );
ADD_DEBUG_HISTORY( HISTORY_ENTITY_IO, szBuffer );
}
@@ -749,7 +767,7 @@ void CEventQueue::Dump( void ) {
EventQueuePrioritizedEvent_t *pe = m_Events.m_pNext;
- Msg("Dumping event queue. Current time is: %.2f\n", gpGlobals->curtime );
+ Msg( "Dumping event queue. Current time is: %.2f\n", engine->GetServerTime() );
while ( pe != NULL )
{
@@ -777,7 +795,7 @@ void CEventQueue::AddEvent( const char *target, const char *targetInput, variant {
// build the new event
EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t;
- newEvent->m_flFireTime = gpGlobals->curtime + fireDelay; // priority key in the priority queue
+ newEvent->m_flFireTime = engine->GetServerTime() + fireDelay; // priority key in the priority queue
newEvent->m_iTarget = MAKE_STRING( target );
newEvent->m_pEntTarget = NULL;
newEvent->m_iTargetInput = MAKE_STRING( targetInput );
@@ -796,7 +814,7 @@ void CEventQueue::AddEvent( CBaseEntity *target, const char *targetInput, varian {
// build the new event
EventQueuePrioritizedEvent_t *newEvent = new EventQueuePrioritizedEvent_t;
- newEvent->m_flFireTime = gpGlobals->curtime + fireDelay; // primary priority key in the priority queue
+ newEvent->m_flFireTime = engine->GetServerTime() + fireDelay; // primary priority key in the priority queue
newEvent->m_iTarget = NULL_STRING;
newEvent->m_pEntTarget = target;
newEvent->m_iTargetInput = MAKE_STRING( targetInput );
@@ -867,7 +885,7 @@ void CEventQueue::ServiceEvents( void ) EventQueuePrioritizedEvent_t *pe = m_Events.m_pNext;
- while ( pe != NULL && pe->m_flFireTime <= gpGlobals->curtime )
+ while ( pe != NULL && pe->m_flFireTime <= engine->GetServerTime() )
{
MDLCACHE_CRITICAL_SECTION();
@@ -1150,11 +1168,23 @@ int CEventQueue::Restore( IRestore &restore ) // add the restored event into the list
if ( tmpEvent.m_pEntTarget )
{
- AddEvent( tmpEvent.m_pEntTarget, STRING(tmpEvent.m_iTargetInput), tmpEvent.m_VariantValue, tmpEvent.m_flFireTime - gpGlobals->curtime, tmpEvent.m_pActivator, tmpEvent.m_pCaller, tmpEvent.m_iOutputID );
+ AddEvent( tmpEvent.m_pEntTarget,
+ STRING(tmpEvent.m_iTargetInput),
+ tmpEvent.m_VariantValue,
+ tmpEvent.m_flFireTime - engine->GetServerTime(),
+ tmpEvent.m_pActivator,
+ tmpEvent.m_pCaller,
+ tmpEvent.m_iOutputID );
}
else
{
- AddEvent( STRING(tmpEvent.m_iTarget), STRING(tmpEvent.m_iTargetInput), tmpEvent.m_VariantValue, tmpEvent.m_flFireTime - gpGlobals->curtime, tmpEvent.m_pActivator, tmpEvent.m_pCaller, tmpEvent.m_iOutputID );
+ AddEvent( STRING(tmpEvent.m_iTarget),
+ STRING(tmpEvent.m_iTargetInput),
+ tmpEvent.m_VariantValue,
+ tmpEvent.m_flFireTime - engine->GetServerTime(),
+ tmpEvent.m_pActivator,
+ tmpEvent.m_pCaller,
+ tmpEvent.m_iOutputID );
}
}
diff --git a/mp/src/game/server/doors.cpp b/mp/src/game/server/doors.cpp index d44d6632..53abb829 100644 --- a/mp/src/game/server/doors.cpp +++ b/mp/src/game/server/doors.cpp @@ -21,6 +21,10 @@ #include "KeyValues.h"
#endif
+#ifdef TF_DLL
+#include "tf_gamerules.h"
+#endif // TF_DLL
+
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@@ -332,6 +336,17 @@ void CBaseDoor::Spawn() }
CreateVPhysics();
+
+#ifdef TF_DLL
+ if ( TFGameRules() && TFGameRules()->IsMultiplayer() )
+ {
+ if ( !m_flBlockDamage )
+ {
+ // Never block doors in TF2 - to prevent various exploits.
+ m_flBlockDamage = 10.f;
+ }
+ }
+#endif // TF_DLL
}
void CBaseDoor::MovingSoundThink( void )
diff --git a/mp/src/game/server/functorutils.h b/mp/src/game/server/functorutils.h index 8b4657b2..d07f0597 100644 --- a/mp/src/game/server/functorutils.h +++ b/mp/src/game/server/functorutils.h @@ -5,8 +5,10 @@ #ifndef _FUNCTOR_UTILS_H_
#define _FUNCTOR_UTILS_H_
+#ifdef NEXT_BOT
#include "NextBotInterface.h"
#include "NextBotManager.h"
+#endif // NEXT_BOT
//--------------------------------------------------------------------------------------------------------
/**
@@ -321,12 +323,14 @@ inline bool ForEachActor( Functor &func ) if ( !player->IsConnected() )
continue;
+#ifdef NEXT_BOT
// skip bots - ForEachCombatCharacter will catch them
INextBot *bot = player->MyNextBotPointer();
if ( bot )
{
continue;
}
+#endif // NEXT_BOT
if ( func( player ) == false )
{
@@ -334,8 +338,12 @@ inline bool ForEachActor( Functor &func ) }
}
+#ifdef NEXT_BOT
// iterate all NextBots
return TheNextBots().ForEachCombatCharacter( func );
+#else
+ return true;
+#endif // NEXT_BOT
}
@@ -385,12 +393,14 @@ inline bool ForEachActor( IActorFunctor &func ) if ( !player->IsConnected() )
continue;
+#ifdef NEXT_BOT
// skip bots - ForEachCombatCharacter will catch them
INextBot *bot = dynamic_cast< INextBot * >( player );
if ( bot )
{
continue;
}
+#endif // NEXT_BOT
if ( func( player ) == false )
{
@@ -399,11 +409,13 @@ inline bool ForEachActor( IActorFunctor &func ) }
}
+#ifdef NEXT_BOT
if ( !isComplete )
{
// iterate all NextBots
isComplete = TheNextBots().ForEachCombatCharacter( func );
}
+#endif // NEXT_BOT
func.OnEndIteration( isComplete );
diff --git a/mp/src/game/server/gameinterface.cpp b/mp/src/game/server/gameinterface.cpp index 9f707419..b4d09bae 100644 --- a/mp/src/game/server/gameinterface.cpp +++ b/mp/src/game/server/gameinterface.cpp @@ -98,14 +98,17 @@ #include "tf/tf_gc_server.h"
#include "tf_gamerules.h"
#include "tf_lobby.h"
-#include "player_vs_environment/tf_populator.h"
+#include "player_vs_environment/tf_population_manager.h"
extern ConVar tf_mm_trusted;
extern ConVar tf_mm_servermode;
#endif
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
#include "nav_mesh.h"
+#endif
+
+#ifdef NEXT_BOT
#include "NextBotManager.h"
#endif
@@ -730,7 +733,7 @@ bool CServerGameDLL::DLLInit( CreateInterfaceFn appSystemFactory, debugoverlay = (IVDebugOverlay *)appSystemFactory( VDEBUG_OVERLAY_INTERFACE_VERSION, NULL );
#ifndef _XBOX
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
// create the Navigation Mesh interface
TheNavMesh = NavMeshFactory();
#endif
@@ -776,7 +779,7 @@ void CServerGameDLL::DLLShutdown( void ) #endif
#ifndef _XBOX
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
// destroy the Navigation Mesh interface
if ( TheNavMesh )
{
@@ -1125,7 +1128,7 @@ void CServerGameDLL::ServerActivate( edict_t *pEdictList, int edictCount, int cl }
#ifndef _XBOX
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
// load the Navigation Mesh for this map
TheNavMesh->Load();
TheNavMesh->OnServerActivate();
@@ -1220,9 +1223,11 @@ void CServerGameDLL::GameFrame( bool simulating ) GameStartFrame();
#ifndef _XBOX
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
TheNavMesh->Update();
+#endif
+#ifdef NEXT_BOT
TheNextBots().Update();
#endif
@@ -1388,7 +1393,7 @@ void CServerGameDLL::LevelShutdown( void ) g_nCurrentChapterIndex = -1;
#ifndef _XBOX
-#ifdef NEXT_BOT
+#ifdef USE_NAV_MESH
// reset the Navigation Mesh
if ( TheNavMesh )
{
diff --git a/mp/src/game/server/hl2/combine_mine.cpp b/mp/src/game/server/hl2/combine_mine.cpp index 6d49f94e..d3e40b56 100644 --- a/mp/src/game/server/hl2/combine_mine.cpp +++ b/mp/src/game/server/hl2/combine_mine.cpp @@ -244,7 +244,7 @@ int CBounceBomb::DrawDebugTextOverlays(void) if (m_debugOverlays & OVERLAY_TEXT_BIT)
{
char tempstr[512];
- Q_snprintf(tempstr,sizeof(tempstr), pszMineStateNames[m_iMineState] );
+ Q_snprintf(tempstr,sizeof(tempstr), "%s", pszMineStateNames[m_iMineState] );
EntityText(text_offset,tempstr,0);
text_offset++;
}
diff --git a/mp/src/game/server/nav_area.h b/mp/src/game/server/nav_area.h index cbabe493..6eba5966 100644 --- a/mp/src/game/server/nav_area.h +++ b/mp/src/game/server/nav_area.h @@ -313,10 +313,12 @@ public: bool HasAvoidanceObstacle( float maxObstructionHeight = StepHeight ) const; // is there a large, immobile object obstructing this area
float GetAvoidanceObstacleHeight( void ) const; // returns the maximum height of the obstruction above the ground
+#ifdef NEXT_BOT
bool HasPrerequisite( CBaseCombatCharacter *actor = NULL ) const; // return true if this area has a prerequisite that applies to the given actor
const CUtlVector< CHandle< CFuncNavPrerequisite > > &GetPrerequisiteVector( void ) const; // return vector of prerequisites that must be met before this area can be traversed
void RemoveAllPrerequisites( void );
void AddPrerequisite( CFuncNavPrerequisite *prereq );
+#endif
void ClearAllNavCostEntities( void ); // clear set of func_nav_cost entities that affect this area
void AddFuncNavCostEntity( CFuncNavCost *cost ); // add the given func_nav_cost entity to the cost of this area
@@ -722,7 +724,9 @@ private: void CalcDebugID();
+#ifdef NEXT_BOT
CUtlVector< CHandle< CFuncNavPrerequisite > > m_prerequisiteVector; // list of prerequisites that must be met before this area can be traversed
+#endif
CNavArea *m_prevHash, *m_nextHash; // for hash table in CNavMesh
@@ -764,6 +768,8 @@ extern NavAreaVector TheNavAreas; // Inlines
//
+#ifdef NEXT_BOT
+
//--------------------------------------------------------------------------------------------------------------
inline bool CNavArea::HasPrerequisite( CBaseCombatCharacter *actor ) const
{
@@ -790,6 +796,7 @@ inline void CNavArea::AddPrerequisite( CFuncNavPrerequisite *prereq ) m_prerequisiteVector.AddToTail( prereq );
}
}
+#endif
//--------------------------------------------------------------------------------------------------------------
inline float CNavArea::GetDangerDecayRate( void ) const
diff --git a/mp/src/game/server/nav_colors.cpp b/mp/src/game/server/nav_colors.cpp index 8f2035be..50ba6cac 100644 --- a/mp/src/game/server/nav_colors.cpp +++ b/mp/src/game/server/nav_colors.cpp @@ -79,8 +79,8 @@ void NavDrawLine( const Vector& from, const Vector& to, NavEditColor navColor ) const Vector offset( 0, 0, 1 );
Color color = NavColors[navColor];
- NDebugOverlay::Line( from + offset, to + offset, color[0]/2, color[1]/2, color[2]/2, true, 0.1f );
- NDebugOverlay::Line( from + offset, to + offset, color[0], color[1], color[2], false, 0.15f );
+ NDebugOverlay::Line( from + offset, to + offset, color[0], color[1], color[2], false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
+ NDebugOverlay::Line( from + offset, to + offset, color[0]/2, color[1]/2, color[2]/2, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
}
@@ -113,8 +113,8 @@ void NavDrawHorizontalArrow( const Vector& from, const Vector& to, float width, const Vector offset( 0, 0, 1 );
Color color = NavColors[navColor];
- NDebugOverlay::HorzArrow( from + offset, to + offset, width, color[0]/2, color[1]/2, color[2]/2, 255, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
NDebugOverlay::HorzArrow( from + offset, to + offset, width, color[0], color[1], color[2], 255, false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
+ NDebugOverlay::HorzArrow( from + offset, to + offset, width, color[0]/2, color[1]/2, color[2]/2, 255, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
}
@@ -142,8 +142,8 @@ void NavDrawDashedLine( const Vector& from, const Vector& to, NavEditColor navCo distance += solidLen + gapLen;
- NDebugOverlay::Line( start + offset, end + offset, color[0]/2, color[1]/2, color[2]/2, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
NDebugOverlay::Line( start + offset, end + offset, color[0], color[1], color[2], false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
+ NDebugOverlay::Line( start + offset, end + offset, color[0]/2, color[1]/2, color[2]/2, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
}
}
diff --git a/mp/src/game/server/nav_edit.cpp b/mp/src/game/server/nav_edit.cpp index cea4e41d..512d5dda 100644 --- a/mp/src/game/server/nav_edit.cpp +++ b/mp/src/game/server/nav_edit.cpp @@ -732,9 +732,6 @@ void CNavMesh::DrawEditMode( void ) static ConVarRef host_thread_mode( "host_thread_mode" );
host_thread_mode.SetValue( 0 );
- static ConVarRef sb_perf_collect( "sb_perf_collect" );
- sb_perf_collect.SetValue( 0 );
-
const float maxRange = 1000.0f; // 500
#if DEBUG_NAV_NODES
@@ -908,7 +905,7 @@ void CNavMesh::DrawEditMode( void ) {
V_snprintf( buffer, sizeof( buffer ), "Ladder #%d\n", m_selectedLadder->GetID() );
}
- NDebugOverlay::ScreenText( 0.5, 0.53, buffer, 255, 255, 0, 128, nav_show_area_info.GetBool() ? 0.1 : 0.5 );
+ NDebugOverlay::ScreenText( 0.5, 0.53, buffer, 255, 255, 0, 128, NDEBUG_PERSIST_TILL_NEXT_SERVER );
}
// draw the ladder we are pointing at and all connected areas
diff --git a/mp/src/game/server/nav_entities.cpp b/mp/src/game/server/nav_entities.cpp index c7abe838..ef9366cc 100644 --- a/mp/src/game/server/nav_entities.cpp +++ b/mp/src/game/server/nav_entities.cpp @@ -96,7 +96,7 @@ void CFuncNavCost::Spawn( void ) for( char *token = strtok( buffer, " " ); token; token = strtok( NULL, " " ) )
{
- m_tags.AddToTail( token );
+ m_tags.AddToTail( CFmtStr( "%s", token ) );
}
delete [] buffer;
@@ -189,6 +189,19 @@ bool CFuncNavCost::IsApplicableTo( CBaseCombatCharacter *who ) const return true;
}
+ // check custom bomb_carrier tags for this bot
+ for( int i=0; i<m_tags.Count(); ++i )
+ {
+ const char* pszTag = m_tags[i];
+ if ( V_stristr( pszTag, "bomb_carrier" ) )
+ {
+ if ( bot->HasTag( pszTag ) )
+ {
+ return true;
+ }
+ }
+ }
+
// the bomb carrier only pays attention to bomb_carrier costs
return false;
}
@@ -217,6 +230,11 @@ bool CFuncNavCost::IsApplicableTo( CBaseCombatCharacter *who ) const }
}
+ if ( bot->HasMission( CTFBot::MISSION_REPROGRAMMED ) )
+ {
+ return false;
+ }
+
if ( !bot->IsOnAnyMission() )
{
if ( HasTag( "common" ) )
diff --git a/mp/src/game/server/nav_mesh.cpp b/mp/src/game/server/nav_mesh.cpp index 095fabb0..05cf7ff7 100644 --- a/mp/src/game/server/nav_mesh.cpp +++ b/mp/src/game/server/nav_mesh.cpp @@ -21,13 +21,15 @@ #endif
#include "functorutils.h"
+#ifdef NEXT_BOT
#include "NextBot/NavMeshEntities/func_nav_prerequisite.h"
+#endif
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
-#define DrawLine( from, to, duration, red, green, blue ) NDebugOverlay::Line( from, to, red, green, blue, true, 0.1f )
+#define DrawLine( from, to, duration, red, green, blue ) NDebugOverlay::Line( from, to, red, green, blue, true, NDEBUG_PERSIST_TILL_NEXT_SERVER )
/**
@@ -42,6 +44,7 @@ ConVar nav_show_danger( "nav_show_danger", "0", FCVAR_GAMEDLL | FCVAR_CHEAT, "Sh ConVar nav_show_player_counts( "nav_show_player_counts", "0", FCVAR_GAMEDLL | FCVAR_CHEAT, "Show current player counts in each area." );
ConVar nav_show_func_nav_avoid( "nav_show_func_nav_avoid", "0", FCVAR_GAMEDLL | FCVAR_CHEAT, "Show areas of designer-placed bot avoidance due to func_nav_avoid entities" );
ConVar nav_show_func_nav_prefer( "nav_show_func_nav_prefer", "0", FCVAR_GAMEDLL | FCVAR_CHEAT, "Show areas of designer-placed bot preference due to func_nav_prefer entities" );
+ConVar nav_show_func_nav_prerequisite( "nav_show_func_nav_prerequisite", "0", FCVAR_GAMEDLL | FCVAR_CHEAT, "Show areas of designer-placed bot preference due to func_nav_prerequisite entities" );
ConVar nav_max_vis_delta_list_length( "nav_max_vis_delta_list_length", "64", FCVAR_CHEAT );
extern ConVar nav_show_potentially_visible;
@@ -302,6 +305,13 @@ void CNavMesh::Update( void ) DrawFuncNavPrefer();
}
+#ifdef NEXT_BOT
+ if ( nav_show_func_nav_prerequisite.GetBool() )
+ {
+ DrawFuncNavPrerequisite();
+ }
+#endif
+
if ( nav_show_potentially_visible.GetBool() )
{
CBasePlayer *player = UTIL_GetListenServerHost();
@@ -569,6 +579,7 @@ void CNavMesh::OnServerActivate( void ) }
}
+#ifdef NEXT_BOT
//--------------------------------------------------------------------------------------------------------------
class CRegisterPrerequisite
@@ -588,6 +599,8 @@ public: CFuncNavPrerequisite *m_prereq;
};
+#endif
+
//--------------------------------------------------------------------------------------------------------------
/**
* Test all areas for blocked status
@@ -609,6 +622,7 @@ void CNavMesh::OnRoundRestart( void ) {
m_updateBlockedAreasTimer.Start( 1.0f );
+#ifdef NEXT_BOT
FOR_EACH_VEC( TheNavAreas, pit )
{
CNavArea *area = TheNavAreas[ pit ];
@@ -626,6 +640,7 @@ void CNavMesh::OnRoundRestart( void ) ForAllAreasOverlappingExtent( apply, prereqExtent );
}
+#endif
}
@@ -1420,7 +1435,7 @@ void CNavMesh::DrawPlayerCounts( void ) const if (area->GetPlayerCount() > 0)
{
- NDebugOverlay::Text( area->GetCenter(), msg.sprintf( "%d (%d/%d)", area->GetPlayerCount(), area->GetPlayerCount(1), area->GetPlayerCount(2) ), false, 0.1f );
+ NDebugOverlay::Text( area->GetCenter(), msg.sprintf( "%d (%d/%d)", area->GetPlayerCount(), area->GetPlayerCount(1), area->GetPlayerCount(2) ), false, NDEBUG_PERSIST_TILL_NEXT_SERVER );
}
}
}
@@ -1462,6 +1477,26 @@ void CNavMesh::DrawFuncNavPrefer( void ) const }
+#ifdef NEXT_BOT
+//--------------------------------------------------------------------------------------------------------------
+/**
+ * Draw bot preference areas from func_nav_prerequisite entities
+ */
+void CNavMesh::DrawFuncNavPrerequisite( void ) const
+{
+ FOR_EACH_VEC( TheNavAreas, it )
+ {
+ CNavArea *area = TheNavAreas[ it ];
+
+ if ( area->HasPrerequisite() )
+ {
+ area->DrawFilled( 0, 0, 255, 255 );
+ }
+ }
+}
+#endif
+
+
//--------------------------------------------------------------------------------------------------------------
/**
* Increase the danger of nav areas containing and near the given position
diff --git a/mp/src/game/server/nav_mesh.h b/mp/src/game/server/nav_mesh.h index dd608792..21dc200b 100644 --- a/mp/src/game/server/nav_mesh.h +++ b/mp/src/game/server/nav_mesh.h @@ -340,7 +340,9 @@ public: void DrawPlayerCounts( void ) const; // draw the current player counts for each area
void DrawFuncNavAvoid( void ) const; // draw bot avoidance areas from func_nav_avoid entities
void DrawFuncNavPrefer( void ) const; // draw bot preference areas from func_nav_prefer entities
-
+#ifdef NEXT_BOT
+ void DrawFuncNavPrerequisite( void ) const; // draw bot prerequisite areas from func_nav_prerequisite entities
+#endif
//-------------------------------------------------------------------------------------
// Auto-generation
//
diff --git a/mp/src/game/server/nav_mesh.vpc b/mp/src/game/server/nav_mesh.vpc new file mode 100644 index 00000000..a9af8574 --- /dev/null +++ b/mp/src/game/server/nav_mesh.vpc @@ -0,0 +1,43 @@ +//-----------------------------------------------------------------------------
+// NAV_MESH.VPC
+//
+// Project script for navigation mesh files (no NextBot files)
+//-----------------------------------------------------------------------------
+
+$Configuration
+{
+ $Compiler
+ {
+ $PreprocessorDefinitions "$BASE;USE_NAV_MESH"
+ }
+}
+
+$Project
+{
+ $Folder "Source Files"
+ {
+ $Folder "Navigation Mesh"
+ {
+ $File "nav.h"
+ $File "nav_area.cpp"
+ $File "nav_area.h"
+ $File "nav_colors.cpp"
+ $File "nav_colors.h"
+ $File "nav_edit.cpp"
+ $File "nav_entities.cpp"
+ $File "nav_entities.h"
+ $File "nav_file.cpp"
+ $File "nav_generate.cpp"
+ $File "nav_ladder.cpp"
+ $File "nav_ladder.h"
+ $File "nav_merge.cpp"
+ $File "nav_mesh.cpp"
+ $File "nav_mesh.h"
+ $File "nav_mesh_factory.cpp"
+ $File "nav_node.cpp"
+ $File "nav_node.h"
+ $File "nav_pathfind.h"
+ $File "nav_simplify.cpp"
+ }
+ }
+}
\ No newline at end of file diff --git a/mp/src/game/server/server_hl2mp.vpc b/mp/src/game/server/server_hl2mp.vpc index 1dfbdbc2..e4002760 100644 --- a/mp/src/game/server/server_hl2mp.vpc +++ b/mp/src/game/server/server_hl2mp.vpc @@ -9,6 +9,7 @@ $Macro GAMENAME "hl2mp" [!$SOURCESDK] $Macro GAMENAME "mod_hl2mp" [$SOURCESDK]
$Include "$SRCDIR\game\server\server_base.vpc"
+$Include "$SRCDIR\game\server\nav_mesh.vpc" [$SOURCESDK]
$Configuration
{
diff --git a/mp/src/game/server/team_control_point_master.cpp b/mp/src/game/server/team_control_point_master.cpp index 6a579e01..662d8200 100644 --- a/mp/src/game/server/team_control_point_master.cpp +++ b/mp/src/game/server/team_control_point_master.cpp @@ -24,6 +24,9 @@ BEGIN_DATADESC( CTeamControlPointMaster ) DEFINE_KEYFIELD( m_flPartialCapturePointsRate, FIELD_FLOAT, "partial_cap_points_rate" ),
+ DEFINE_KEYFIELD( m_flCustomPositionX, FIELD_FLOAT, "custom_position_x" ),
+ DEFINE_KEYFIELD( m_flCustomPositionY, FIELD_FLOAT, "custom_position_y" ),
+
// DEFINE_FIELD( m_ControlPoints, CUtlMap < int , CTeamControlPoint * > ),
// DEFINE_FIELD( m_bFoundPoints, FIELD_BOOLEAN ),
// DEFINE_FIELD( m_ControlPointRounds, CUtlVector < CTeamControlPointRound * > ),
@@ -40,6 +43,8 @@ BEGIN_DATADESC( CTeamControlPointMaster ) DEFINE_INPUTFUNC( FIELD_VOID, "RoundSpawn", InputRoundSpawn ),
DEFINE_INPUTFUNC( FIELD_VOID, "RoundActivate", InputRoundActivate ),
DEFINE_INPUTFUNC( FIELD_STRING, "SetCapLayout", InputSetCapLayout ),
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "SetCapLayoutCustomPositionX", InputSetCapLayoutCustomPositionX ),
+ DEFINE_INPUTFUNC( FIELD_FLOAT, "SetCapLayoutCustomPositionY", InputSetCapLayoutCustomPositionY ),
DEFINE_FUNCTION( CPMThink ),
@@ -70,6 +75,8 @@ int ControlPointRoundSort( CTeamControlPointRound* const *p1, CTeamControlPointR CTeamControlPointMaster::CTeamControlPointMaster()
{
m_flPartialCapturePointsRate = 0.0f;
+ m_flCustomPositionX = -1.f;
+ m_flCustomPositionY = -1.f;
}
//-----------------------------------------------------------------------------
@@ -329,6 +336,7 @@ bool CTeamControlPointMaster::FindControlPointRounds( void ) {
g_pObjectiveResource->SetPlayingMiniRounds( bFoundRounds );
g_pObjectiveResource->SetCapLayoutInHUD( STRING(m_iszCapLayoutInHUD) );
+ g_pObjectiveResource->SetCapLayoutCustomPosition( m_flCustomPositionX, m_flCustomPositionY );
}
return bFoundRounds;
@@ -837,15 +845,11 @@ void CTeamControlPointMaster::InputRoundSpawn( inputdata_t &input ) // init the ClientAreas
int index = 0;
- CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, GetTriggerAreaCaptureName() );
- while( pEnt )
+ for ( int i=0; i<ITriggerAreaCaptureAutoList::AutoList().Count(); ++i )
{
- CTriggerAreaCapture *pArea = (CTriggerAreaCapture *)pEnt;
- Assert( pArea );
+ CTriggerAreaCapture *pArea = static_cast< CTriggerAreaCapture * >( ITriggerAreaCaptureAutoList::AutoList()[i] );
pArea->SetAreaIndex( index );
index++;
-
- pEnt = gEntList.FindEntityByClassname( pEnt, GetTriggerAreaCaptureName() );
}
ObjectiveResource()->ResetControlPoints();
@@ -892,6 +896,24 @@ void CTeamControlPointMaster::InputSetCapLayout( inputdata_t &inputdata ) //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
+void CTeamControlPointMaster::InputSetCapLayoutCustomPositionX( inputdata_t &inputdata )
+{
+ m_flCustomPositionX = inputdata.value.Float();
+ g_pObjectiveResource->SetCapLayoutCustomPosition( m_flCustomPositionX, m_flCustomPositionY );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTeamControlPointMaster::InputSetCapLayoutCustomPositionY( inputdata_t &inputdata )
+{
+ m_flCustomPositionY = inputdata.value.Float();
+ g_pObjectiveResource->SetCapLayoutCustomPosition( m_flCustomPositionX, m_flCustomPositionY );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
void CTeamControlPointMaster::FireTeamWinOutput( int iWinningTeam )
{
// Remap team so that first game team = 1
diff --git a/mp/src/game/server/team_control_point_master.h b/mp/src/game/server/team_control_point_master.h index 48265ba6..64b1e9b5 100644 --- a/mp/src/game/server/team_control_point_master.h +++ b/mp/src/game/server/team_control_point_master.h @@ -36,7 +36,6 @@ public: CTeamControlPointMaster();
// Used to find game specific entities
- virtual const char *GetTriggerAreaCaptureName( void ) { return "trigger_capture_area"; }
virtual const char *GetControlPointName( void ) { return "team_control_point"; }
virtual const char *GetControlPointRoundName( void ) { return "team_control_point_round"; }
@@ -182,6 +181,8 @@ private: void InputSetWinner( inputdata_t &inputdata );
void InputSetWinnerAndForceCaps( inputdata_t &inputdata );
void InputSetCapLayout( inputdata_t &inputdata );
+ void InputSetCapLayoutCustomPositionX( inputdata_t &inputdata );
+ void InputSetCapLayoutCustomPositionY( inputdata_t &inputdata );
void InternalSetWinner( int iTeam );
@@ -191,6 +192,9 @@ private: int m_iTeamBaseIcons[MAX_TEAMS];
string_t m_iszCapLayoutInHUD;
+ float m_flCustomPositionX;
+ float m_flCustomPositionY;
+
int m_iInvalidCapWinner;
bool m_bSwitchTeamsOnWin;
bool m_bScorePerCapture;
diff --git a/mp/src/game/server/team_control_point_round.cpp b/mp/src/game/server/team_control_point_round.cpp index cc3d0cc7..c9e36bd7 100644 --- a/mp/src/game/server/team_control_point_round.cpp +++ b/mp/src/game/server/team_control_point_round.cpp @@ -365,33 +365,27 @@ bool CTeamControlPointRound::MakePlayable( void ) if ( !IsPlayable() )
{
// we need to try switching the owners of the teams to make this round playable
- for ( int i = FIRST_GAME_TEAM ; i < GetNumberOfTeams() ; i++ )
+ for ( int iTeam = FIRST_GAME_TEAM ; iTeam < GetNumberOfTeams() ; iTeam++ )
{
- for ( int j = 0 ; j < m_ControlPoints.Count() ; j++ )
+ for ( int iControlPoint = 0 ; iControlPoint < m_ControlPoints.Count() ; iControlPoint++ )
{
- if ( ( !pMaster->IsBaseControlPoint( m_ControlPoints[j]->GetPointIndex() ) ) && // this is NOT the base point for one of the teams (we don't want to assign the base to the wrong team)
- ( !WouldNewCPOwnerWinGame( m_ControlPoints[j], i ) ) ) // making this change would make this round playable
+ if ( ( !pMaster->IsBaseControlPoint( m_ControlPoints[iControlPoint]->GetPointIndex() ) ) && // this is NOT the base point for one of the teams (we don't want to assign the base to the wrong team)
+ ( !WouldNewCPOwnerWinGame( m_ControlPoints[iControlPoint], iTeam ) ) ) // making this change would make this round playable
{
// need to find the trigger area associated with this point
- CBaseEntity *pEnt = gEntList.FindEntityByClassname( NULL, pMaster->GetTriggerAreaCaptureName() );
- while( pEnt )
+ for ( int iObj=0; iObj<ITriggerAreaCaptureAutoList::AutoList().Count(); ++iObj )
{
- CTriggerAreaCapture *pArea = assert_cast<CTriggerAreaCapture*>( pEnt );
- if ( pArea )
- {
- if ( pArea->TeamCanCap( i ) )
+ CTriggerAreaCapture *pArea = static_cast< CTriggerAreaCapture * >( ITriggerAreaCaptureAutoList::AutoList()[iObj] );
+ if ( pArea->TeamCanCap( iTeam ) )
+ {
+ CHandle<CTeamControlPoint> hPoint = pArea->GetControlPoint();
+ if ( hPoint == m_ControlPoints[iControlPoint] )
{
- CHandle<CTeamControlPoint> hPoint = pArea->GetControlPoint();
- if ( hPoint == m_ControlPoints[j] )
- {
- // found!
- pArea->ForceOwner( i ); // this updates the trigger_area *and* the control_point
- return true;
- }
+ // found!
+ pArea->ForceOwner( iTeam ); // this updates the trigger_area *and* the control_point
+ return true;
}
}
-
- pEnt = gEntList.FindEntityByClassname( pEnt, pMaster->GetTriggerAreaCaptureName() );
}
}
}
diff --git a/mp/src/game/server/team_objectiveresource.cpp b/mp/src/game/server/team_objectiveresource.cpp index 9f8d0e7f..f7dd502e 100644 --- a/mp/src/game/server/team_objectiveresource.cpp +++ b/mp/src/game/server/team_objectiveresource.cpp @@ -61,7 +61,10 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CBaseTeamObjectiveResource, DT_BaseTeamObjective SendPropArray3( SENDINFO_ARRAY3(m_iTeamInZone), SendPropInt( SENDINFO_ARRAY(m_iTeamInZone), 4, SPROP_UNSIGNED ) ),
SendPropArray3( SENDINFO_ARRAY3(m_bBlocked), SendPropInt( SENDINFO_ARRAY(m_bBlocked), 1, SPROP_UNSIGNED ) ),
SendPropArray3( SENDINFO_ARRAY3(m_iOwner), SendPropInt( SENDINFO_ARRAY(m_iOwner), 4, SPROP_UNSIGNED ) ),
+ SendPropArray3( SENDINFO_ARRAY3(m_bCPCapRateScalesWithPlayers), SendPropBool( SENDINFO_ARRAY(m_bCPCapRateScalesWithPlayers) ) ),
SendPropString( SENDINFO(m_pszCapLayoutInHUD) ),
+ SendPropFloat( SENDINFO( m_flCustomPositionX ) ),
+ SendPropFloat( SENDINFO( m_flCustomPositionY ) ),
END_SEND_TABLE()
@@ -72,6 +75,8 @@ BEGIN_DATADESC( CBaseTeamObjectiveResource ) DEFINE_FIELD( m_bPlayingMiniRounds, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bControlPointsReset, FIELD_BOOLEAN ),
DEFINE_FIELD( m_iUpdateCapHudParity, FIELD_INTEGER ),
+ DEFINE_FIELD( m_flCustomPositionX, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flCustomPositionY, FIELD_FLOAT ),
DEFINE_ARRAY( m_vCPPositions, FIELD_VECTOR, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_bCPIsVisible, FIELD_INTEGER, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_flLazyCapPerc, FIELD_FLOAT, MAX_CONTROL_POINTS ),
@@ -91,6 +96,7 @@ BEGIN_DATADESC( CBaseTeamObjectiveResource ) DEFINE_ARRAY( m_iTeamInZone, FIELD_INTEGER, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_bBlocked, FIELD_BOOLEAN, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_iOwner, FIELD_INTEGER, MAX_CONTROL_POINTS ),
+ DEFINE_ARRAY( m_bCPCapRateScalesWithPlayers, FIELD_BOOLEAN, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_pszCapLayoutInHUD, FIELD_CHARACTER, MAX_CAPLAYOUT_LENGTH ),
DEFINE_ARRAY( m_flCapPercentages, FIELD_FLOAT, MAX_CONTROL_POINTS ),
DEFINE_ARRAY( m_iCPGroup, FIELD_INTEGER, MAX_CONTROL_POINTS ),
@@ -114,6 +120,8 @@ CBaseTeamObjectiveResource::CBaseTeamObjectiveResource() m_bPlayingMiniRounds = false;
m_iUpdateCapHudParity = 0;
m_bControlPointsReset = false;
+ m_flCustomPositionX = -1.f;
+ m_flCustomPositionY = -1.f;
}
//-----------------------------------------------------------------------------
@@ -153,6 +161,7 @@ void CBaseTeamObjectiveResource::Spawn( void ) m_bCPLocked.Set( i, false );
m_flUnlockTimes.Set( i, 0.0 );
m_flCPTimerTimes.Set( i, -1.0 );
+ m_bCPCapRateScalesWithPlayers.Set( i, true );
for ( int team = 0; team < MAX_CONTROL_POINT_TEAMS; team++ )
{
@@ -384,6 +393,15 @@ void CBaseTeamObjectiveResource::SetCPTimerTime( int index, float flTime ) //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
+void CBaseTeamObjectiveResource::SetCPCapTimeScalesWithPlayers( int index, bool bScales )
+{
+ AssertValidIndex(index);
+ m_bCPCapRateScalesWithPlayers.Set( index, bScales );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
void CBaseTeamObjectiveResource::SetTeamCanCap( int index, int iTeam, bool bCanCap )
{
AssertValidIndex(index);
diff --git a/mp/src/game/server/team_objectiveresource.h b/mp/src/game/server/team_objectiveresource.h index 40d1920c..5cc42009 100644 --- a/mp/src/game/server/team_objectiveresource.h +++ b/mp/src/game/server/team_objectiveresource.h @@ -58,6 +58,7 @@ public: int GetPreviousPointForPoint( int index, int team, int iPrevIndex );
bool TeamCanCapPoint( int index, int team );
void SetCapLayoutInHUD( const char *pszLayout ) { Q_strncpy(m_pszCapLayoutInHUD.GetForModify(), pszLayout, MAX_CAPLAYOUT_LENGTH ); }
+ void SetCapLayoutCustomPosition( float flPositionX, float flPositionY ) { m_flCustomPositionX = flPositionX; m_flCustomPositionY = flPositionY; }
void SetWarnOnCap( int index, int iWarnLevel );
void SetWarnSound( int index, string_t iszSound );
void SetCPGroup( int index, int iCPGroup );
@@ -65,6 +66,7 @@ public: void SetTrackAlarm( int index, bool bAlarm );
void SetCPUnlockTime( int index, float flTime );
void SetCPTimerTime( int index, float flTime );
+ void SetCPCapTimeScalesWithPlayers( int index, bool bScales );
// State functions, called many times
void SetNumPlayers( int index, int team, int iNumPlayers );
@@ -205,10 +207,15 @@ private: // changes when a point is successfully captured
CNetworkArray( int, m_iOwner, MAX_CONTROL_POINTS );
+ CNetworkArray( bool, m_bCPCapRateScalesWithPlayers, MAX_CONTROL_POINTS );
// describes how to lay out the cap points in the hud
CNetworkString( m_pszCapLayoutInHUD, MAX_CAPLAYOUT_LENGTH );
+ // custom screen position for the cap points in the hud
+ CNetworkVar( float, m_flCustomPositionX );
+ CNetworkVar( float, m_flCustomPositionY );
+
// the groups the points belong to
CNetworkArray( int, m_iCPGroup, MAX_CONTROL_POINTS );
diff --git a/mp/src/game/server/team_train_watcher.cpp b/mp/src/game/server/team_train_watcher.cpp index 27d7a15c..cf6631fb 100644 --- a/mp/src/game/server/team_train_watcher.cpp +++ b/mp/src/game/server/team_train_watcher.cpp @@ -819,17 +819,15 @@ void CTeamTrainWatcher::WatcherActivate( void ) {
if ( m_hTrain )
{
- CTriggerAreaCapture *pArea = dynamic_cast<CTriggerAreaCapture *>( gEntList.FindEntityByClassname( NULL, "trigger_capture_area" ) );
- while( pArea )
+ for ( int i=0; i<ITriggerAreaCaptureAutoList::AutoList().Count(); ++i )
{
+ CTriggerAreaCapture *pArea = static_cast< CTriggerAreaCapture * >( ITriggerAreaCaptureAutoList::AutoList()[i] );
if ( pArea->GetParent() == m_hTrain.Get() )
{
// this is the capture area we care about, so let it know that we want updates on the capture numbers
pArea->SetTrainWatcher( this );
break;
}
-
- pArea = dynamic_cast<CTriggerAreaCapture *>( gEntList.FindEntityByClassname( pArea, "trigger_capture_area" ) );
}
}
diff --git a/mp/src/game/server/trigger_area_capture.cpp b/mp/src/game/server/trigger_area_capture.cpp index fcf3a868..665bd005 100644 --- a/mp/src/game/server/trigger_area_capture.cpp +++ b/mp/src/game/server/trigger_area_capture.cpp @@ -18,10 +18,12 @@ extern ConVar mp_capstyle; extern ConVar mp_blockstyle;
extern ConVar mp_capdeteriorate_time;
+IMPLEMENT_AUTO_LIST( ITriggerAreaCaptureAutoList );
+
BEGIN_DATADESC(CTriggerAreaCapture)
// Touch functions
- DEFINE_FUNCTION( AreaTouch ),
+ DEFINE_FUNCTION( CTriggerAreaCaptureShim::Touch ),
// Think functions
DEFINE_THINKFUNC( CaptureThink ),
@@ -96,7 +98,7 @@ void CTriggerAreaCapture::Spawn( void ) m_iAreaIndex = -1;
- SetTouch ( &CTriggerAreaCapture::AreaTouch );
+ SetTouch ( &CTriggerAreaCaptureShim::Touch );
SetThink( &CTriggerAreaCapture::CaptureThink );
SetNextThink( gpGlobals->curtime + AREA_THINK_TIME );
@@ -253,6 +255,14 @@ void CTriggerAreaCapture::EndTouch(CBaseEntity *pOther) //-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
+bool CTriggerAreaCapture::CaptureModeScalesWithPlayers() const
+{
+ return mp_capstyle.GetBool();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
void CTriggerAreaCapture::AreaTouch( CBaseEntity *pOther )
{
if ( !IsActive() )
@@ -469,7 +479,7 @@ void CTriggerAreaCapture::CaptureThink( void ) float flTimeDelta = gpGlobals->curtime - m_flLastReductionTime;
float flReduction = flTimeDelta;
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
// Diminishing returns for successive players.
for ( int i = 1; i < m_TeamData[m_nTeamInZone].iNumTouching; i++ )
@@ -490,7 +500,7 @@ void CTriggerAreaCapture::CaptureThink( void ) // See if anyone gets credit for the block
float flPercentToGo = m_fTimeRemaining / m_flCapTime;
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
flPercentToGo = m_fTimeRemaining / ((m_flCapTime * 2) * m_TeamData[m_nCapturingTeam].iNumRequiredToCap);
}
@@ -561,7 +571,7 @@ void CTriggerAreaCapture::CaptureThink( void ) }
float flTotalTimeToCap = m_flCapTime;
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
flTotalTimeToCap = ((m_flCapTime * 2) * m_TeamData[m_nCapturingTeam].iNumRequiredToCap);
}
@@ -580,7 +590,8 @@ void CTriggerAreaCapture::CaptureThink( void ) // Caps deteriorate over time
if ( TeamplayRoundBasedRules() && m_hPoint && TeamplayRoundBasedRules()->TeamMayCapturePoint(m_nCapturingTeam,m_hPoint->GetPointIndex()) )
{
- float flDecrease = (flTotalTimeToCap / mp_capdeteriorate_time.GetFloat()) * flTimeDelta;
+ float flDecreaseScale = CaptureModeScalesWithPlayers() ? mp_capdeteriorate_time.GetFloat() : flTotalTimeToCap;
+ float flDecrease = (flTotalTimeToCap / flDecreaseScale) * flTimeDelta;
if ( TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->InOvertime() )
{
flDecrease *= 6;
@@ -649,7 +660,7 @@ void CTriggerAreaCapture::CaptureThink( void ) if ( m_TeamData[i].iNumTouching < m_TeamData[i].iNumRequiredToStartCap )
continue;
- if ( mp_capstyle.GetInt() == 0 && m_TeamData[i].iNumTouching < m_TeamData[i].iNumRequiredToCap )
+ if ( !CaptureModeScalesWithPlayers() && m_TeamData[i].iNumTouching < m_TeamData[i].iNumRequiredToCap )
continue;
StartCapture( i, CAPTURE_NORMAL );
@@ -670,7 +681,7 @@ void CTriggerAreaCapture::SetCapTimeRemaining( float flTime ) if ( m_nCapturingTeam )
{
flCapPercentage = m_fTimeRemaining / m_flCapTime;
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
flCapPercentage = m_fTimeRemaining / ((m_flCapTime * 2) * m_TeamData[m_nCapturingTeam].iNumRequiredToCap);
}
@@ -762,7 +773,7 @@ void CTriggerAreaCapture::StartCapture( int team, int capmode ) UpdateNumPlayers();
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
SetCapTimeRemaining( ((m_flCapTime * 2) * m_TeamData[team].iNumRequiredToCap) );
}
@@ -1017,7 +1028,7 @@ void CTriggerAreaCapture::InputRoundSpawn( inputdata_t &inputdata ) ObjectiveResource()->SetCPRequiredCappers( m_hPoint->GetPointIndex(), i, m_TeamData[i].iNumRequiredToCap );
ObjectiveResource()->SetTeamCanCap( m_hPoint->GetPointIndex(), i, m_TeamData[i].bCanCap );
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
ObjectiveResource()->SetCPCapTime( m_hPoint->GetPointIndex(), i, (m_flCapTime * 2) * m_TeamData[i].iNumRequiredToCap );
}
@@ -1025,6 +1036,8 @@ void CTriggerAreaCapture::InputRoundSpawn( inputdata_t &inputdata ) {
ObjectiveResource()->SetCPCapTime( m_hPoint->GetPointIndex(), i, m_flCapTime );
}
+
+ ObjectiveResource()->SetCPCapTimeScalesWithPlayers( m_hPoint->GetPointIndex(), CaptureModeScalesWithPlayers() );
}
}
}
@@ -1125,7 +1138,7 @@ bool CTriggerAreaCapture::CheckIfDeathCausesBlock( CBaseMultiplayerPlayer *pVict // break early incase we kill multiple people in the same frame
bool bBreakCap = false;
- if ( mp_capstyle.GetInt() == 1 )
+ if ( CaptureModeScalesWithPlayers() )
{
bBreakCap = ( m_TeamData[m_nCapturingTeam].iBlockedTouching - 1 ) <= 0;
}
diff --git a/mp/src/game/server/trigger_area_capture.h b/mp/src/game/server/trigger_area_capture.h index e2e494c9..383f3fad 100644 --- a/mp/src/game/server/trigger_area_capture.h +++ b/mp/src/game/server/trigger_area_capture.h @@ -32,9 +32,19 @@ class CTeamTrainWatcher; // Can either be capped by both teams at once, or just by one
// Time to capture and number of people required to capture are both passed by the mapper
//-----------------------------------------------------------------------------
-class CTriggerAreaCapture : public CBaseTrigger
+// This class is to get around the fact that DEFINE_FUNCTION doesn't like multiple inheritance
+class CTriggerAreaCaptureShim : public CBaseTrigger
{
- DECLARE_CLASS( CTriggerAreaCapture, CBaseTrigger );
+ virtual void AreaTouch( CBaseEntity *pOther ) = 0;
+public:
+ void Touch( CBaseEntity *pOther ) { return AreaTouch( pOther ) ; }
+};
+
+DECLARE_AUTO_LIST( ITriggerAreaCaptureAutoList );
+
+class CTriggerAreaCapture : public CTriggerAreaCaptureShim, public ITriggerAreaCaptureAutoList
+{
+ DECLARE_CLASS( CTriggerAreaCapture, CTriggerAreaCaptureShim );
public:
CTriggerAreaCapture();
@@ -73,10 +83,17 @@ public: void SetTrainWatcher( CTeamTrainWatcher *pTrainWatcher ){ m_hTrainWatcher = pTrainWatcher; } // used for train watchers that control train movement
CTeamTrainWatcher *GetTrainWatcher( void ) const { return m_hTrainWatcher; }
+ virtual void StartTouch(CBaseEntity *pOther) OVERRIDE;
+ virtual void EndTouch(CBaseEntity *pOther) OVERRIDE;
+
+ float GetCapTime() const { return m_flCapTime; }
+
+protected:
+
+ virtual bool CaptureModeScalesWithPlayers() const;
+
private:
- void StartTouch(CBaseEntity *pOther);
- void EXPORT AreaTouch( CBaseEntity *pOther );
- void EndTouch(CBaseEntity *pOther);
+ virtual void AreaTouch( CBaseEntity *pOther ) OVERRIDE;
void CaptureThink( void );
void StartCapture( int team, int capmode );
diff --git a/mp/src/game/server/vote_controller.cpp b/mp/src/game/server/vote_controller.cpp index f2c8e2f4..a2fcfd99 100644 --- a/mp/src/game/server/vote_controller.cpp +++ b/mp/src/game/server/vote_controller.cpp @@ -346,6 +346,19 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons Assert( nNumVoteOptions >= 2 );
}
+ // Have the issue start working on it
+ pCurrentIssue->OnVoteStarted();
+
+ // Now the vote handling and UI
+ m_nPotentialVotes = pCurrentIssue->CountPotentialVoters();
+ m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() );
+
+ // Force the vote holder to agree with a Yes/No vote
+ if ( m_bIsYesNoVote && !bDedicatedServer )
+ {
+ TryCastVote( iEntIndex, "Option1" );
+ }
+
// Get the data out to the client
CBroadcastRecipientFilter filter;
filter.MakeReliable();
@@ -357,16 +370,6 @@ bool CVoteController::CreateVote( int iEntIndex, const char *pszTypeString, cons WRITE_BOOL( m_bIsYesNoVote );
MessageEnd();
- // Force the vote holder to agree with a Yes/No vote
- if ( m_bIsYesNoVote && !bDedicatedServer )
- {
- TryCastVote( iEntIndex, "Option1" );
- }
-
- m_nPotentialVotes = pCurrentIssue->CountPotentialVoters();
- m_acceptingVotesTimer.Start( sv_vote_timer_duration.GetFloat() );
- pCurrentIssue->OnVoteStarted();
-
if ( !bDedicatedServer )
{
TrackVoteCaller( pVoteCaller );
diff --git a/mp/src/game/shared/activitylist.cpp b/mp/src/game/shared/activitylist.cpp index 1b61fb64..a69933c9 100644 --- a/mp/src/game/shared/activitylist.cpp +++ b/mp/src/game/shared/activitylist.cpp @@ -2265,6 +2265,11 @@ void ActivityList_RegisterSharedActivities( void ) REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_AIRWALK_PRIMARY3_END );
REGISTER_SHARED_ACTIVITY( ACT_MP_RELOAD_SWIM_PRIMARY3 );
+ REGISTER_SHARED_ACTIVITY( ACT_MP_THROW );
+ REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_DRAW );
+ REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_IDLE );
+ REGISTER_SHARED_ACTIVITY( ACT_THROWABLE_VM_FIRE );
+
AssertMsg( g_HighestActivity == LAST_SHARED_ACTIVITY - 1, "Not all activities from ai_activity.h registered in activitylist.cpp" );
}
diff --git a/mp/src/game/shared/ai_activity.h b/mp/src/game/shared/ai_activity.h index 854da726..4e94fca8 100644 --- a/mp/src/game/shared/ai_activity.h +++ b/mp/src/game/shared/ai_activity.h @@ -2095,6 +2095,13 @@ typedef enum ACT_MP_RELOAD_AIRWALK_PRIMARY3_END,
ACT_MP_RELOAD_SWIM_PRIMARY3,
+ // Throwable Animations
+ ACT_MP_THROW,
+
+ ACT_THROWABLE_VM_DRAW,
+ ACT_THROWABLE_VM_IDLE,
+ ACT_THROWABLE_VM_FIRE,
+
// this is the end of the global activities, private per-monster activities start here.
LAST_SHARED_ACTIVITY,
} Activity;
diff --git a/mp/src/game/shared/baseentity_shared.cpp b/mp/src/game/shared/baseentity_shared.cpp index 470b2d2e..949143b1 100644 --- a/mp/src/game/shared/baseentity_shared.cpp +++ b/mp/src/game/shared/baseentity_shared.cpp @@ -48,6 +48,11 @@ ConVar hl2_episodic( "hl2_episodic", "0", FCVAR_REPLICATED ); #include "prop_portal_shared.h"
#endif
+#ifdef TF_DLL
+#include "tf_gamerules.h"
+#include "tf_weaponbase.h"
+#endif // TF_DLL
+
#include "rumble_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
@@ -1746,6 +1751,17 @@ void CBaseEntity::FireBullets( const FireBulletsInfo_t &info ) {
pShootThroughPortal = NULL;
}
+#elif TF_DLL
+ CTraceFilterIgnoreFriendlyCombatItems traceFilterCombatItem( this, COLLISION_GROUP_NONE, GetTeamNumber() );
+ if ( TFGameRules() && TFGameRules()->GameModeUsesUpgrades() )
+ {
+ CTraceFilterChain traceFilterChain( &traceFilter, &traceFilterCombatItem );
+ AI_TraceLine(info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilterChain, &tr);
+ }
+ else
+ {
+ AI_TraceLine(info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr);
+ }
#else
AI_TraceLine(info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr);
#endif //#ifdef PORTAL
diff --git a/mp/src/game/shared/multiplay_gamerules.cpp b/mp/src/game/shared/multiplay_gamerules.cpp index f933634c..2cbb6f61 100644 --- a/mp/src/game/shared/multiplay_gamerules.cpp +++ b/mp/src/game/shared/multiplay_gamerules.cpp @@ -1223,7 +1223,7 @@ ConVarRef suitcharger( "sk_suitcharger" ); {
if ( bForceSpew || V_stricmp( szLastResult, pszResult) )
{
- Msg( "Using map cycle file %s.\n", pszResult );
+ Msg( "Using map cycle file '%s'.\n", pszResult );
V_strcpy_safe( szLastResult, pszResult );
}
return;
diff --git a/mp/src/game/shared/particle_property.cpp b/mp/src/game/shared/particle_property.cpp index b1ae32a7..18d278ad 100644 --- a/mp/src/game/shared/particle_property.cpp +++ b/mp/src/game/shared/particle_property.cpp @@ -26,6 +26,12 @@ // memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
+#ifdef STAGING_ONLY
+#ifdef TF_CLIENT_DLL
+extern ConVar tf_unusual_effect_offset;
+#endif
+#endif
+
//-----------------------------------------------------------------------------
// Save/load
//-----------------------------------------------------------------------------
diff --git a/mp/src/game/shared/playernet_vars.h b/mp/src/game/shared/playernet_vars.h index abb49765..9fdeec0f 100644 --- a/mp/src/game/shared/playernet_vars.h +++ b/mp/src/game/shared/playernet_vars.h @@ -77,10 +77,10 @@ struct fogplayerparams_t {
m_hCtrl.Set( NULL );
m_flTransitionTime = -1.0f;
- m_OldColor.r = m_OldColor.g = m_OldColor.b = m_OldColor.a = 0;
+ m_OldColor.r = m_OldColor.g = m_OldColor.g = m_OldColor.a = 0.0f;
m_flOldStart = 0.0f;
m_flOldEnd = 0.0f;
- m_NewColor.r = m_NewColor.g = m_NewColor.b = m_NewColor.a = 0;
+ m_NewColor.r = m_NewColor.g = m_NewColor.g = m_NewColor.a = 0.0f;
m_flNewStart = 0.0f;
m_flNewEnd = 0.0f;
}
diff --git a/mp/src/game/shared/teamplay_round_timer.h b/mp/src/game/shared/teamplay_round_timer.h index 7826cf5b..470a5f16 100644 --- a/mp/src/game/shared/teamplay_round_timer.h +++ b/mp/src/game/shared/teamplay_round_timer.h @@ -79,6 +79,7 @@ public: void SetStopWatch( bool bState ) { m_bStopWatchTimer = bState; }
bool IsStopWatchTimer( void ) { return m_bStopWatchTimer; }
float GetStopWatchTotalTime( void ) { return m_flTotalTime; }
+ bool IsRoundMaxTimerSet( void ) { return m_nTimerMaxLength > 0; }
private:
diff --git a/mp/src/game/shared/teamplayroundbased_gamerules.cpp b/mp/src/game/shared/teamplayroundbased_gamerules.cpp index f737aecf..a843d134 100644 --- a/mp/src/game/shared/teamplayroundbased_gamerules.cpp +++ b/mp/src/game/shared/teamplayroundbased_gamerules.cpp @@ -38,7 +38,7 @@ #if defined(TF_CLIENT_DLL) || defined(TF_DLL)
#include "tf_lobby.h"
#ifdef GAME_DLL
- #include "player_vs_environment/tf_populator.h"
+ #include "player_vs_environment/tf_population_manager.h"
#include "../server/tf/tf_gc_server.h"
#include "../server/tf/tf_objective_resource.h"
#else
diff --git a/mp/src/game/shared/voice_status.cpp b/mp/src/game/shared/voice_status.cpp index 4d295713..ed6c0f2f 100644 --- a/mp/src/game/shared/voice_status.cpp +++ b/mp/src/game/shared/voice_status.cpp @@ -425,7 +425,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) void CVoiceStatus::HandleVoiceMaskMsg(bf_read &msg)
{
- unsigned long dw;
+ unsigned int dw;
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
m_AudiblePlayers.SetDWord(dw, (unsigned long)msg.ReadLong());
@@ -434,8 +434,8 @@ void CVoiceStatus::HandleVoiceMaskMsg(bf_read &msg) if( voice_clientdebug.GetInt())
{
Msg("CVoiceStatus::HandleVoiceMaskMsg\n");
- Msg(" - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw));
- Msg(" - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw));
+ Msg(" - m_AudiblePlayers[%d] = %u\n", dw, m_AudiblePlayers.GetDWord(dw));
+ Msg(" - m_ServerBannedPlayers[%d] = %u\n", dw, m_ServerBannedPlayers.GetDWord(dw));
}
}
diff --git a/mp/src/lib/osx32/bitmap.a b/mp/src/lib/osx32/bitmap.a Binary files differindex 083bebc3..cfdb3754 100644 --- a/mp/src/lib/osx32/bitmap.a +++ b/mp/src/lib/osx32/bitmap.a diff --git a/mp/src/lib/osx32/choreoobjects.a b/mp/src/lib/osx32/choreoobjects.a Binary files differindex caa6d1cd..47431a06 100644 --- a/mp/src/lib/osx32/choreoobjects.a +++ b/mp/src/lib/osx32/choreoobjects.a diff --git a/mp/src/lib/osx32/dmxloader.a b/mp/src/lib/osx32/dmxloader.a Binary files differindex 5ace7439..bdbf0211 100644 --- a/mp/src/lib/osx32/dmxloader.a +++ b/mp/src/lib/osx32/dmxloader.a diff --git a/mp/src/lib/osx32/libtier0.dylib b/mp/src/lib/osx32/libtier0.dylib Binary files differindex e217d299..af6b5c58 100644 --- a/mp/src/lib/osx32/libtier0.dylib +++ b/mp/src/lib/osx32/libtier0.dylib diff --git a/mp/src/lib/osx32/libvstdlib.dylib b/mp/src/lib/osx32/libvstdlib.dylib Binary files differindex 99e9495a..4a7a32a6 100644 --- a/mp/src/lib/osx32/libvstdlib.dylib +++ b/mp/src/lib/osx32/libvstdlib.dylib diff --git a/mp/src/lib/osx32/matsys_controls.a b/mp/src/lib/osx32/matsys_controls.a Binary files differindex 84c5ed52..75d6fc9e 100644 --- a/mp/src/lib/osx32/matsys_controls.a +++ b/mp/src/lib/osx32/matsys_controls.a diff --git a/mp/src/lib/osx32/particles.a b/mp/src/lib/osx32/particles.a Binary files differindex fe4c9efd..7808c3f8 100644 --- a/mp/src/lib/osx32/particles.a +++ b/mp/src/lib/osx32/particles.a diff --git a/mp/src/lib/osx32/tier2.a b/mp/src/lib/osx32/tier2.a Binary files differindex 503e2663..5b374e52 100644 --- a/mp/src/lib/osx32/tier2.a +++ b/mp/src/lib/osx32/tier2.a diff --git a/mp/src/lib/osx32/tier3.a b/mp/src/lib/osx32/tier3.a Binary files differindex 33a789ec..2bc80e46 100644 --- a/mp/src/lib/osx32/tier3.a +++ b/mp/src/lib/osx32/tier3.a diff --git a/mp/src/lib/osx32/vtf.a b/mp/src/lib/osx32/vtf.a Binary files differindex 66baf6f2..c0ef3476 100644 --- a/mp/src/lib/osx32/vtf.a +++ b/mp/src/lib/osx32/vtf.a diff --git a/mp/src/lib/public/appframework.lib b/mp/src/lib/public/appframework.lib Binary files differindex a32303f1..c69838ca 100644 --- a/mp/src/lib/public/appframework.lib +++ b/mp/src/lib/public/appframework.lib diff --git a/mp/src/lib/public/bitmap.lib b/mp/src/lib/public/bitmap.lib Binary files differindex a467de69..cf3530fc 100644 --- a/mp/src/lib/public/bitmap.lib +++ b/mp/src/lib/public/bitmap.lib diff --git a/mp/src/lib/public/choreoobjects.lib b/mp/src/lib/public/choreoobjects.lib Binary files differindex 40e42d7f..eb31ddd4 100644 --- a/mp/src/lib/public/choreoobjects.lib +++ b/mp/src/lib/public/choreoobjects.lib diff --git a/mp/src/lib/public/dmxloader.lib b/mp/src/lib/public/dmxloader.lib Binary files differindex 4f25a567..18edcba5 100644 --- a/mp/src/lib/public/dmxloader.lib +++ b/mp/src/lib/public/dmxloader.lib diff --git a/mp/src/lib/public/fgdlib.lib b/mp/src/lib/public/fgdlib.lib Binary files differindex 4f3de80e..fb1aafd9 100644 --- a/mp/src/lib/public/fgdlib.lib +++ b/mp/src/lib/public/fgdlib.lib diff --git a/mp/src/lib/public/linux32/bitmap.a b/mp/src/lib/public/linux32/bitmap.a Binary files differindex 39a1dc3e..bbd65285 100644 --- a/mp/src/lib/public/linux32/bitmap.a +++ b/mp/src/lib/public/linux32/bitmap.a diff --git a/mp/src/lib/public/linux32/choreoobjects.a b/mp/src/lib/public/linux32/choreoobjects.a Binary files differindex 96a9ba79..bbeb2ef3 100644 --- a/mp/src/lib/public/linux32/choreoobjects.a +++ b/mp/src/lib/public/linux32/choreoobjects.a diff --git a/mp/src/lib/public/linux32/dmxloader.a b/mp/src/lib/public/linux32/dmxloader.a Binary files differindex 6c3bf0ac..71d39e95 100644 --- a/mp/src/lib/public/linux32/dmxloader.a +++ b/mp/src/lib/public/linux32/dmxloader.a diff --git a/mp/src/lib/public/linux32/libSDL2-2.0.so.0 b/mp/src/lib/public/linux32/libSDL2-2.0.so.0 Binary files differnew file mode 100644 index 00000000..5908adb7 --- /dev/null +++ b/mp/src/lib/public/linux32/libSDL2-2.0.so.0 diff --git a/mp/src/lib/public/linux32/libSDL2.so b/mp/src/lib/public/linux32/libSDL2.so new file mode 100644 index 00000000..d58bb41c --- /dev/null +++ b/mp/src/lib/public/linux32/libSDL2.so @@ -0,0 +1 @@ +libSDL2-2.0.so.0 diff --git a/mp/src/lib/public/linux32/libtier0.so b/mp/src/lib/public/linux32/libtier0.so Binary files differindex 365d88bd..cd02bc3b 100644 --- a/mp/src/lib/public/linux32/libtier0.so +++ b/mp/src/lib/public/linux32/libtier0.so diff --git a/mp/src/lib/public/linux32/libvstdlib.so b/mp/src/lib/public/linux32/libvstdlib.so Binary files differindex fa19b46c..f6aea107 100644 --- a/mp/src/lib/public/linux32/libvstdlib.so +++ b/mp/src/lib/public/linux32/libvstdlib.so diff --git a/mp/src/lib/public/linux32/matsys_controls.a b/mp/src/lib/public/linux32/matsys_controls.a Binary files differindex d758fa8e..1a284e03 100644 --- a/mp/src/lib/public/linux32/matsys_controls.a +++ b/mp/src/lib/public/linux32/matsys_controls.a diff --git a/mp/src/lib/public/linux32/particles.a b/mp/src/lib/public/linux32/particles.a Binary files differindex e788bdb4..626fecaf 100644 --- a/mp/src/lib/public/linux32/particles.a +++ b/mp/src/lib/public/linux32/particles.a diff --git a/mp/src/lib/public/linux32/tier2.a b/mp/src/lib/public/linux32/tier2.a Binary files differindex a9c78bb8..a440a0b7 100644 --- a/mp/src/lib/public/linux32/tier2.a +++ b/mp/src/lib/public/linux32/tier2.a diff --git a/mp/src/lib/public/linux32/tier3.a b/mp/src/lib/public/linux32/tier3.a Binary files differindex 98d6839d..77f98b2b 100644 --- a/mp/src/lib/public/linux32/tier3.a +++ b/mp/src/lib/public/linux32/tier3.a diff --git a/mp/src/lib/public/linux32/vtf.a b/mp/src/lib/public/linux32/vtf.a Binary files differindex cb4e892e..4d7f1f26 100644 --- a/mp/src/lib/public/linux32/vtf.a +++ b/mp/src/lib/public/linux32/vtf.a diff --git a/mp/src/lib/public/mathlib.lib b/mp/src/lib/public/mathlib.lib Binary files differindex 56985a5c..d581b673 100644 --- a/mp/src/lib/public/mathlib.lib +++ b/mp/src/lib/public/mathlib.lib diff --git a/mp/src/lib/public/matsys_controls.lib b/mp/src/lib/public/matsys_controls.lib Binary files differindex 803f997f..bf1da093 100644 --- a/mp/src/lib/public/matsys_controls.lib +++ b/mp/src/lib/public/matsys_controls.lib diff --git a/mp/src/lib/public/nvtristrip.lib b/mp/src/lib/public/nvtristrip.lib Binary files differindex 12f88e14..21185355 100644 --- a/mp/src/lib/public/nvtristrip.lib +++ b/mp/src/lib/public/nvtristrip.lib diff --git a/mp/src/lib/public/osx32/libSDL2-2.0.0.dylib b/mp/src/lib/public/osx32/libSDL2-2.0.0.dylib Binary files differnew file mode 100644 index 00000000..3fd8c749 --- /dev/null +++ b/mp/src/lib/public/osx32/libSDL2-2.0.0.dylib diff --git a/mp/src/lib/public/osx32/libSDL2.dylib b/mp/src/lib/public/osx32/libSDL2.dylib new file mode 100644 index 00000000..4122f22f --- /dev/null +++ b/mp/src/lib/public/osx32/libSDL2.dylib @@ -0,0 +1 @@ +libSDL2-2.0.0.dylib diff --git a/mp/src/lib/public/particles.lib b/mp/src/lib/public/particles.lib Binary files differindex 2d5d6f0b..4f78b611 100644 --- a/mp/src/lib/public/particles.lib +++ b/mp/src/lib/public/particles.lib diff --git a/mp/src/lib/public/raytrace.lib b/mp/src/lib/public/raytrace.lib Binary files differindex 6b470314..2b9ad265 100644 --- a/mp/src/lib/public/raytrace.lib +++ b/mp/src/lib/public/raytrace.lib diff --git a/mp/src/lib/public/shaderlib.lib b/mp/src/lib/public/shaderlib.lib Binary files differnew file mode 100644 index 00000000..53a7744d --- /dev/null +++ b/mp/src/lib/public/shaderlib.lib diff --git a/mp/src/lib/public/tier0.lib b/mp/src/lib/public/tier0.lib Binary files differindex 7c85b7f1..da3ed75c 100644 --- a/mp/src/lib/public/tier0.lib +++ b/mp/src/lib/public/tier0.lib diff --git a/mp/src/lib/public/tier1.lib b/mp/src/lib/public/tier1.lib Binary files differindex aedd4b28..d9293e4a 100644 --- a/mp/src/lib/public/tier1.lib +++ b/mp/src/lib/public/tier1.lib diff --git a/mp/src/lib/public/tier2.lib b/mp/src/lib/public/tier2.lib Binary files differindex d071c271..6600cb7f 100644 --- a/mp/src/lib/public/tier2.lib +++ b/mp/src/lib/public/tier2.lib diff --git a/mp/src/lib/public/tier3.lib b/mp/src/lib/public/tier3.lib Binary files differindex 1ba407a2..a549f07e 100644 --- a/mp/src/lib/public/tier3.lib +++ b/mp/src/lib/public/tier3.lib diff --git a/mp/src/lib/public/vgui_controls.lib b/mp/src/lib/public/vgui_controls.lib Binary files differindex ddb284cf..d05d0bcb 100644 --- a/mp/src/lib/public/vgui_controls.lib +++ b/mp/src/lib/public/vgui_controls.lib diff --git a/mp/src/lib/public/vmpi.lib b/mp/src/lib/public/vmpi.lib Binary files differindex f2a5682c..b16b57ae 100644 --- a/mp/src/lib/public/vmpi.lib +++ b/mp/src/lib/public/vmpi.lib diff --git a/mp/src/lib/public/vstdlib.lib b/mp/src/lib/public/vstdlib.lib Binary files differindex 2b43846f..80035b6a 100644 --- a/mp/src/lib/public/vstdlib.lib +++ b/mp/src/lib/public/vstdlib.lib diff --git a/mp/src/lib/public/vtf.lib b/mp/src/lib/public/vtf.lib Binary files differindex d1adfa8a..32a90207 100644 --- a/mp/src/lib/public/vtf.lib +++ b/mp/src/lib/public/vtf.lib diff --git a/mp/src/materialsystem/shaderapidx9/locald3dtypes.h b/mp/src/materialsystem/shaderapidx9/locald3dtypes.h new file mode 100644 index 00000000..31854816 --- /dev/null +++ b/mp/src/materialsystem/shaderapidx9/locald3dtypes.h @@ -0,0 +1,191 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#ifndef LOCALD3DTYPES_H
+#define LOCALD3DTYPES_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#if defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION )
+
+#include <d3d10.h>
+#include <d3dx10.h>
+
+struct IDirect3D10BaseTexture
+{
+ ID3D10Resource *m_pBaseTexture;
+ ID3D10ShaderResourceView *m_pSRView;
+ ID3D10RenderTargetView *m_pRTView;
+};
+
+class CDx10Types
+{
+public:
+ typedef struct IDirect3D10BaseTexture IDirect3DTexture;
+ // FIXME: What is this called now ?
+ // typedef ID3D10TextureCube IDirect3DCubeTexture;
+ typedef ID3D10Texture3D IDirect3DVolumeTexture;
+ typedef ID3D10Device IDirect3DDevice;
+ typedef D3D10_VIEWPORT D3DVIEWPORT;
+ typedef ID3D10Buffer IDirect3DIndexBuffer;
+ typedef ID3D10Buffer IDirect3DVertexBuffer;
+ typedef ID3D10VertexShader IDirect3DVertexShader;
+ typedef ID3D10PixelShader IDirect3DPixelShader;
+ typedef ID3D10ShaderResourceView IDirect3DSurface;
+ typedef ID3DX10Font ID3DXFont;
+ typedef ID3D10Query ID3DQuery;
+
+ typedef ID3D10Device *LPDIRECT3DDEVICE;
+ typedef ID3D10Buffer *LPDIRECT3DINDEXBUFFER;
+ typedef ID3D10Buffer *LPDIRECT3DVERTEXBUFFER;
+};
+
+#endif // defined( DX10 ) && !defined( DX_TO_GL_ABSTRACTION )
+
+
+#if !defined( _X360 ) && !defined( DX_TO_GL_ABSTRACTION )
+#ifdef _DEBUG
+#define D3D_DEBUG_INFO 1
+#endif
+#endif
+
+struct IDirect3DTexture9;
+struct IDirect3DBaseTexture9;
+struct IDirect3DCubeTexture9;
+struct IDirect3D9;
+struct IDirect3DDevice9;
+struct IDirect3DSurface9;
+struct IDirect3DIndexBuffer9;
+struct IDirect3DVertexBuffer9;
+struct IDirect3DVertexShader9;
+struct IDirect3DPixelShader9;
+struct IDirect3DVolumeTexture9;
+
+typedef struct _D3DLIGHT9 D3DLIGHT9;
+typedef struct _D3DADAPTER_IDENTIFIER9 D3DADAPTER_IDENTIFIER9;
+typedef struct _D3DCAPS9 D3DCAPS9;
+typedef struct _D3DVIEWPORT9 D3DVIEWPORT9;
+typedef struct _D3DMATERIAL9 D3DMATERIAL9;
+typedef IDirect3DTexture9 IDirect3DTexture;
+typedef IDirect3DBaseTexture9 IDirect3DBaseTexture;
+typedef IDirect3DCubeTexture9 IDirect3DCubeTexture;
+typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture;
+typedef IDirect3DDevice9 IDirect3DDevice;
+typedef D3DMATERIAL9 D3DMATERIAL;
+typedef D3DLIGHT9 D3DLIGHT;
+typedef IDirect3DSurface9 IDirect3DSurface;
+typedef D3DCAPS9 D3DCAPS;
+typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer;
+typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer;
+typedef IDirect3DPixelShader9 IDirect3DPixelShader;
+typedef IDirect3DDevice *LPDIRECT3DDEVICE;
+typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER;
+typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER;
+
+class CDx9Types
+{
+public:
+ typedef IDirect3DTexture9 IDirect3DTexture;
+ typedef IDirect3DBaseTexture9 IDirect3DBaseTexture;
+ typedef IDirect3DCubeTexture9 IDirect3DCubeTexture;
+ typedef IDirect3DVolumeTexture9 IDirect3DVolumeTexture;
+ typedef IDirect3DDevice9 IDirect3DDevice;
+ typedef D3DMATERIAL9 D3DMATERIAL;
+ typedef D3DLIGHT9 D3DLIGHT;
+ typedef IDirect3DSurface9 IDirect3DSurface;
+ typedef D3DCAPS9 D3DCAPS;
+ typedef IDirect3DIndexBuffer9 IDirect3DIndexBuffer;
+ typedef IDirect3DVertexBuffer9 IDirect3DVertexBuffer;
+ typedef IDirect3DPixelShader9 IDirect3DPixelShader;
+ typedef IDirect3DDevice *LPDIRECT3DDEVICE;
+ typedef IDirect3DIndexBuffer *LPDIRECT3DINDEXBUFFER;
+ typedef IDirect3DVertexBuffer *LPDIRECT3DVERTEXBUFFER;
+};
+
+typedef void *HardwareShader_t;
+
+//-----------------------------------------------------------------------------
+// The vertex and pixel shader type
+//-----------------------------------------------------------------------------
+typedef int VertexShader_t;
+typedef int PixelShader_t;
+
+//-----------------------------------------------------------------------------
+// Bitpattern for an invalid shader
+//-----------------------------------------------------------------------------
+#define INVALID_SHADER ( 0xFFFFFFFF )
+#define INVALID_HARDWARE_SHADER ( NULL )
+
+#define D3DSAMP_NOTSUPPORTED D3DSAMP_FORCE_DWORD
+#define D3DRS_NOTSUPPORTED D3DRS_FORCE_DWORD
+
+#include "togl/rendermechanism.h"
+
+#if defined( _X360 )
+
+// not supported, keeping for port ease
+#define D3DSAMP_SRGBTEXTURE D3DSAMP_NOTSUPPORTED
+#define D3DRS_LIGHTING D3DRS_NOTSUPPORTED
+#define D3DRS_DIFFUSEMATERIALSOURCE D3DRS_NOTSUPPORTED
+#define D3DRS_SPECULARENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_SHADEMODE D3DRS_NOTSUPPORTED
+#define D3DRS_LASTPIXEL D3DRS_NOTSUPPORTED
+#define D3DRS_DITHERENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_FOGENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_FOGCOLOR D3DRS_NOTSUPPORTED
+#define D3DRS_FOGTABLEMODE D3DRS_NOTSUPPORTED
+#define D3DRS_FOGSTART D3DRS_NOTSUPPORTED
+#define D3DRS_FOGEND D3DRS_NOTSUPPORTED
+#define D3DRS_FOGDENSITY D3DRS_NOTSUPPORTED
+#define D3DRS_RANGEFOGENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_TEXTUREFACTOR D3DRS_NOTSUPPORTED
+#define D3DRS_CLIPPING D3DRS_NOTSUPPORTED
+#define D3DRS_AMBIENT D3DRS_NOTSUPPORTED
+#define D3DRS_FOGVERTEXMODE D3DRS_NOTSUPPORTED
+#define D3DRS_COLORVERTEX D3DRS_NOTSUPPORTED
+#define D3DRS_LOCALVIEWER D3DRS_NOTSUPPORTED
+#define D3DRS_NORMALIZENORMALS D3DRS_NOTSUPPORTED
+#define D3DRS_SPECULARMATERIALSOURCE D3DRS_NOTSUPPORTED
+#define D3DRS_AMBIENTMATERIALSOURCE D3DRS_NOTSUPPORTED
+#define D3DRS_EMISSIVEMATERIALSOURCE D3DRS_NOTSUPPORTED
+#define D3DRS_VERTEXBLEND D3DRS_NOTSUPPORTED
+#define D3DRS_POINTSCALEENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_POINTSCALE_A D3DRS_NOTSUPPORTED
+#define D3DRS_POINTSCALE_B D3DRS_NOTSUPPORTED
+#define D3DRS_POINTSCALE_C D3DRS_NOTSUPPORTED
+#define D3DRS_PATCHEDGESTYLE D3DRS_NOTSUPPORTED
+#define D3DRS_DEBUGMONITORTOKEN D3DRS_NOTSUPPORTED
+#define D3DRS_INDEXEDVERTEXBLENDENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_TWEENFACTOR D3DRS_NOTSUPPORTED
+#define D3DRS_POSITIONDEGREE D3DRS_NOTSUPPORTED
+#define D3DRS_NORMALDEGREE D3DRS_NOTSUPPORTED
+#define D3DRS_ANTIALIASEDLINEENABLE D3DRS_NOTSUPPORTED
+#define D3DRS_ADAPTIVETESS_X D3DRS_NOTSUPPORTED
+#define D3DRS_ADAPTIVETESS_Y D3DRS_NOTSUPPORTED
+#define D3DRS_ADAPTIVETESS_Z D3DRS_NOTSUPPORTED
+#define D3DRS_ADAPTIVETESS_W D3DRS_NOTSUPPORTED
+#define D3DRS_ENABLEADAPTIVETESSELLATION D3DRS_NOTSUPPORTED
+#define D3DRS_SRGBWRITEENABLE D3DRS_NOTSUPPORTED
+#define D3DLOCK_DISCARD 0
+#define D3DUSAGE_DYNAMIC 0
+#define D3DUSAGE_AUTOGENMIPMAP 0
+#define D3DDEVTYPE_REF D3DDEVTYPE_HAL
+#define D3DENUM_WHQL_LEVEL 0
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING D3DCREATE_HARDWARE_VERTEXPROCESSING
+#define D3DDMT_ENABLE 0
+
+typedef enum D3DSHADEMODE
+{
+ D3DSHADE_FLAT = 0,
+ D3DSHADE_GOURAUD = 0,
+};
+
+#endif // _X360
+
+#endif // LOCALD3DTYPES_H
diff --git a/mp/src/materialsystem/stdshaders/BaseVSShader.cpp b/mp/src/materialsystem/stdshaders/BaseVSShader.cpp new file mode 100644 index 00000000..ba1f6e15 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BaseVSShader.cpp @@ -0,0 +1,2234 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+// This is what all vs/ps (dx8+) shaders inherit from.
+//===========================================================================//
+#if !defined(_STATIC_LINKED) || defined(STDSHADER_DX8_DLL_EXPORT) || defined(STDSHADER_DX9_DLL_EXPORT)
+
+#include "BaseVSShader.h"
+#include "mathlib/vmatrix.h"
+#include "mathlib/bumpvects.h"
+#include "cpp_shader_constant_register_map.h"
+#include "convar.h"
+
+#ifndef GAME_SHADER_DLL
+#ifdef HDR
+#include "vertexlit_and_unlit_generic_hdr_ps20.inc"
+#include "vertexlit_and_unlit_generic_hdr_ps20b.inc"
+#endif
+
+#if SUPPORT_DX8
+#include "lightmappedgeneric_flashlight_vs11.inc"
+#include "flashlight_ps11.inc"
+#endif
+
+#ifdef STDSHADER_DX9_DLL_EXPORT
+#include "lightmappedgeneric_flashlight_vs20.inc"
+#endif
+#ifdef STDSHADER_DX9_DLL_EXPORT
+#include "flashlight_ps20.inc"
+#include "flashlight_ps20b.inc"
+#endif
+#include "unlitgeneric_vs11.inc"
+#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14.inc"
+#include "VertexLitGeneric_EnvmappedBumpmap_NoLighting.inc"
+#include "vertexlitgeneric_flashlight_vs11.inc"
+#include "LightmappedGeneric_BaseTexture.inc"
+#include "LightmappedGeneric_BumpmappedLightmap_Base_ps14.inc"
+#include "LightmappedGeneric_BumpmappedLightmap_Blend_ps14.inc"
+#include "lightmappedgeneric_bumpmappedenvmap_ps14.inc"
+#include "lightmappedgeneric_bumpmappedenvmap.inc"
+#include "lightmappedgeneric_basetextureblend.inc"
+#include "lightmappedgeneric_bumpmappedlightmap.inc"
+#endif // GAME_SHADER_DLL
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+static ConVar mat_fullbright( "mat_fullbright","0", FCVAR_CHEAT );
+
+// These functions are to be called from the shaders.
+
+//-----------------------------------------------------------------------------
+// Pixel and vertex shader constants....
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+ IMaterialVar* pPixelVar2 = s_ppParams[constantVar2];
+ Assert( pPixelVar2 );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ {
+ pPixelVar->GetVecValue( val, 3 );
+ }
+ else
+ {
+ val[0] = val[1] = val[2] = pPixelVar->GetFloatValue();
+ }
+
+ val[3] = pPixelVar2->GetFloatValue();
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+ IMaterialVar* pPixelVar2 = s_ppParams[constantVar2];
+ Assert( pPixelVar2 );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ {
+ pPixelVar->GetVecValue( val, 3 );
+ }
+ else
+ {
+ val[0] = val[1] = val[2] = pPixelVar->GetFloatValue();
+ }
+
+ val[3] = pPixelVar2->GetFloatValue();
+ val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] );
+ val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] );
+ val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] );
+
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pPixelVar->GetVecValue( val, 4 );
+ else
+ val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
+ val[3]=fWValue;
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pPixelVar->GetVecValue( val, 4 );
+ else
+ val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pPixelVar->GetVecValue( val, 4 );
+ else
+ val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue();
+
+ val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] );
+ val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] );
+ val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] );
+
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce )
+{
+ int i;
+ for( i = 0; i < numConst; i++ )
+ {
+ float vec[4];
+ vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] );
+ vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] );
+ vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] );
+ vec[3] = pVec[i*4+3];
+
+ s_pShaderAPI->SetVertexShaderConstant( var + i, vec, 1, bForce );
+ }
+}
+
+void CBaseVSShader::SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst, bool bForce )
+{
+ int i;
+ for( i = 0; i < numConst; i++ )
+ {
+ float vec[4];
+ vec[0] = pVec[i*4+0] > 1.0f ? pVec[i*4+0] : GammaToLinear( pVec[i*4+0] );
+ vec[1] = pVec[i*4+1] > 1.0f ? pVec[i*4+1] : GammaToLinear( pVec[i*4+1] );
+ vec[2] = pVec[i*4+2] > 1.0f ? pVec[i*4+2] : GammaToLinear( pVec[i*4+2] );
+
+ vec[3] = pVec[i*4+3];
+
+ s_pShaderAPI->SetPixelShaderConstant( var + i, vec, 1, bForce );
+ }
+}
+
+// GR - special version with fix for const/lerp issue
+void CBaseVSShader::SetPixelShaderConstantFudge( int pixelReg, int constantVar )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1))
+ return;
+
+ IMaterialVar* pPixelVar = s_ppParams[constantVar];
+ Assert( pPixelVar );
+
+ float val[4];
+ if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ {
+ pPixelVar->GetVecValue( val, 4 );
+ val[0] = val[0] * 0.992f + 0.0078f;
+ val[1] = val[1] * 0.992f + 0.0078f;
+ val[2] = val[2] * 0.992f + 0.0078f;
+ val[3] = val[3] * 0.992f + 0.0078f;
+ }
+ else
+ val[0] = val[1] = val[2] = val[3] = pPixelVar->GetFloatValue() * 0.992f + 0.0078f;
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, val );
+}
+
+void CBaseVSShader::SetVertexShaderConstant( int vertexReg, int constantVar )
+{
+ Assert( !IsSnapshotting() );
+ if ((!s_ppParams) || (constantVar == -1))
+ return;
+
+ IMaterialVar* pVertexVar = s_ppParams[constantVar];
+ Assert( pVertexVar );
+
+ float val[4];
+ if (pVertexVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pVertexVar->GetVecValue( val, 4 );
+ else
+ val[0] = val[1] = val[2] = val[3] = pVertexVar->GetFloatValue();
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, val );
+}
+
+//-----------------------------------------------------------------------------
+// Sets normalized light color for pixel shaders.
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetPixelShaderLightColors( int pixelReg )
+{
+ int i;
+ int maxLights = s_pShaderAPI->GetMaxLights();
+ for( i = 0; i < maxLights; i++ )
+ {
+ const LightDesc_t & lightDesc = s_pShaderAPI->GetLight( i );
+ if( lightDesc.m_Type != MATERIAL_LIGHT_DISABLE )
+ {
+ Vector color( lightDesc.m_Color[0], lightDesc.m_Color[1], lightDesc.m_Color[2] );
+ VectorNormalize( color );
+ float val[4] = { color[0], color[1], color[2], 1.0f };
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, val, 1 );
+ }
+ else
+ {
+ float zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg + i, zero, 1 );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets vertex shader texture transforms
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetVertexShaderTextureTranslation( int vertexReg, int translationVar )
+{
+ float offset[2] = {0, 0};
+
+ IMaterialVar* pTranslationVar = s_ppParams[translationVar];
+ if (pTranslationVar)
+ {
+ if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pTranslationVar->GetVecValue( offset, 2 );
+ else
+ offset[0] = offset[1] = pTranslationVar->GetFloatValue();
+ }
+
+ Vector4D translation[2];
+ translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] );
+ translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, translation[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetVertexShaderTextureScale( int vertexReg, int scaleVar )
+{
+ float scale[2] = {1, 1};
+
+ IMaterialVar* pScaleVar = s_ppParams[scaleVar];
+ if (pScaleVar)
+ {
+ if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pScaleVar->GetVecValue( scale, 2 );
+ else if (pScaleVar->IsDefined())
+ scale[0] = scale[1] = pScaleVar->GetFloatValue();
+ }
+
+ Vector4D scaleMatrix[2];
+ scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f );
+ scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, scaleMatrix[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetVertexShaderTextureTransform( int vertexReg, int transformVar )
+{
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = s_ppParams[transformVar];
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar )
+{
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = s_ppParams[transformVar];
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+
+ Vector2D scale( 1, 1 );
+ IMaterialVar* pScaleVar = s_ppParams[scaleVar];
+ if (pScaleVar)
+ {
+ if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pScaleVar->GetVecValue( scale.Base(), 2 );
+ else if (pScaleVar->IsDefined())
+ scale[0] = scale[1] = pScaleVar->GetFloatValue();
+ }
+
+ // Apply the scaling
+ transformation[0][0] *= scale[0];
+ transformation[0][1] *= scale[1];
+ transformation[1][0] *= scale[0];
+ transformation[1][1] *= scale[1];
+ transformation[0][3] *= scale[0];
+ transformation[1][3] *= scale[1];
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets pixel shader texture transforms
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetPixelShaderTextureTranslation( int pixelReg, int translationVar )
+{
+ float offset[2] = {0, 0};
+
+ IMaterialVar* pTranslationVar = s_ppParams[translationVar];
+ if (pTranslationVar)
+ {
+ if (pTranslationVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pTranslationVar->GetVecValue( offset, 2 );
+ else
+ offset[0] = offset[1] = pTranslationVar->GetFloatValue();
+ }
+
+ Vector4D translation[2];
+ translation[0].Init( 1.0f, 0.0f, 0.0f, offset[0] );
+ translation[1].Init( 0.0f, 1.0f, 0.0f, offset[1] );
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, translation[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetPixelShaderTextureScale( int pixelReg, int scaleVar )
+{
+ float scale[2] = {1, 1};
+
+ IMaterialVar* pScaleVar = s_ppParams[scaleVar];
+ if (pScaleVar)
+ {
+ if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pScaleVar->GetVecValue( scale, 2 );
+ else if (pScaleVar->IsDefined())
+ scale[0] = scale[1] = pScaleVar->GetFloatValue();
+ }
+
+ Vector4D scaleMatrix[2];
+ scaleMatrix[0].Init( scale[0], 0.0f, 0.0f, 0.0f );
+ scaleMatrix[1].Init( 0.0f, scale[1], 0.0f, 0.0f );
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, scaleMatrix[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetPixelShaderTextureTransform( int pixelReg, int transformVar )
+{
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = s_ppParams[transformVar];
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 );
+}
+
+void CBaseVSShader::SetPixelShaderTextureScaledTransform( int pixelReg, int transformVar, int scaleVar )
+{
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = s_ppParams[transformVar];
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+
+ Vector2D scale( 1, 1 );
+ IMaterialVar* pScaleVar = s_ppParams[scaleVar];
+ if (pScaleVar)
+ {
+ if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pScaleVar->GetVecValue( scale.Base(), 2 );
+ else if (pScaleVar->IsDefined())
+ scale[0] = scale[1] = pScaleVar->GetFloatValue();
+ }
+
+ // Apply the scaling
+ transformation[0][0] *= scale[0];
+ transformation[0][1] *= scale[1];
+ transformation[1][0] *= scale[0];
+ transformation[1][1] *= scale[1];
+ transformation[0][3] *= scale[0];
+ transformation[1][3] *= scale[1];
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, transformation[0].Base(), 2 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Moves a matrix into vertex shader constants
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetVertexShaderMatrix3x4( int vertexReg, int matrixVar )
+{
+ IMaterialVar* pTranslationVar = s_ppParams[matrixVar];
+ if (pTranslationVar)
+ {
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 3 );
+ }
+ else
+ {
+ VMatrix matrix;
+ MatrixSetIdentity( matrix );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 3 );
+ }
+}
+
+void CBaseVSShader::SetVertexShaderMatrix4x4( int vertexReg, int matrixVar )
+{
+ IMaterialVar* pTranslationVar = s_ppParams[matrixVar];
+ if (pTranslationVar)
+ {
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, &pTranslationVar->GetMatrixValue( )[0][0], 4 );
+ }
+ else
+ {
+ VMatrix matrix;
+ MatrixSetIdentity( matrix );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, &matrix[0][0], 4 );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads the view matrix into pixel shader constants
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadViewMatrixIntoVertexShaderConstant( int vertexReg )
+{
+ VMatrix mat, transpose;
+ s_pShaderAPI->GetMatrix( MATERIAL_VIEW, mat.m[0] );
+
+ MatrixTranspose( mat, transpose );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 3 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads the projection matrix into pixel shader constants
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg )
+{
+ VMatrix mat, transpose;
+ s_pShaderAPI->GetMatrix( MATERIAL_PROJECTION, mat.m[0] );
+
+ MatrixTranspose( mat, transpose );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, transpose.m[0], 4 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads the projection matrix into pixel shader constants
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg )
+{
+ VMatrix view, model, modelView, transpose;
+ s_pShaderAPI->GetMatrix( MATERIAL_MODEL, model.m[0] );
+ MatrixTranspose( model, model );
+ s_pShaderAPI->GetMatrix( MATERIAL_VIEW, view.m[0] );
+ MatrixTranspose( view, view );
+
+ MatrixMultiply( view, model, modelView );
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, modelView.m[0], 3 );
+}
+
+//-----------------------------------------------------------------------------
+// Loads a scale/offset version of the viewport transform into the specified constant.
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg )
+{
+ ShaderViewport_t viewport;
+
+ s_pShaderAPI->GetViewports( &viewport, 1 );
+
+ int bbWidth = 0,
+ bbHeight = 0;
+
+ s_pShaderAPI->GetBackBufferDimensions( bbWidth, bbHeight );
+
+ // (x, y, z, w) = (Width / bbWidth, Height / bbHeight, MinX / bbWidth, MinY / bbHeight)
+ Vector4D viewportTransform(
+ 1.0f * viewport.m_nWidth / bbWidth,
+ 1.0f * viewport.m_nHeight / bbHeight,
+ 1.0f * viewport.m_nTopLeftX / bbWidth,
+ 1.0f * viewport.m_nTopLeftY / bbHeight
+ );
+
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, viewportTransform.Base() );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Loads bump lightmap coordinates into the pixel shader
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg )
+{
+ Vector4D basis[3];
+ for (int i = 0; i < 3; ++i)
+ {
+ memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) );
+ basis[i][3] = 0.0f;
+ }
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, (float*)basis, 3 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads bump lightmap coordinates into the pixel shader
+//-----------------------------------------------------------------------------
+void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg )
+{
+ Vector4D basis[3];
+
+ // transpose
+ int i;
+ for (i = 0; i < 3; ++i)
+ {
+ basis[i][0] = g_localBumpBasis[0][i];
+ basis[i][1] = g_localBumpBasis[1][i];
+ basis[i][2] = g_localBumpBasis[2][i];
+ basis[i][3] = 0.0f;
+ }
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 );
+ for (i = 0; i < 3; ++i)
+ {
+ memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) );
+ basis[i][3] = 0.0f;
+ }
+ s_pShaderAPI->SetVertexShaderConstant( vertexReg + 3, (float*)basis, 3 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Helper methods for pixel shader overbrighting
+//-----------------------------------------------------------------------------
+void CBaseVSShader::EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo )
+{
+ // can't have other overbright values with pixel shaders as it stands.
+ float v[4];
+ if( bEnable )
+ {
+ v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? OVERBRIGHT / 2.0f : OVERBRIGHT;
+ }
+ else
+ {
+ v[0] = v[1] = v[2] = v[3] = bDivideByTwo ? 1.0f / 2.0f : 1.0f;
+ }
+ s_pShaderAPI->SetPixelShaderConstant( reg, v, 1 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Helper for dealing with modulation
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetModulationVertexShaderDynamicState()
+{
+ float color[4] = { 1.0, 1.0, 1.0, 1.0 };
+ ComputeModulationColor( color );
+ s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color );
+}
+
+void CBaseVSShader::SetModulationPixelShaderDynamicState( int modulationVar )
+{
+ float color[4] = { 1.0, 1.0, 1.0, 1.0 };
+ ComputeModulationColor( color );
+ s_pShaderAPI->SetPixelShaderConstant( modulationVar, color );
+}
+
+void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar )
+{
+ float color[4] = { 1.0, 1.0, 1.0, 1.0 };
+ ComputeModulationColor( color );
+ color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] );
+ color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] );
+ color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] );
+
+ s_pShaderAPI->SetPixelShaderConstant( modulationVar, color );
+}
+
+void CBaseVSShader::SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale )
+{
+ float color[4] = { 1.0, 1.0, 1.0, 1.0 };
+ ComputeModulationColor( color );
+ color[0] = ( color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ) ) * flScale;
+ color[1] = ( color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ) ) * flScale;
+ color[2] = ( color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ) ) * flScale;
+
+ s_pShaderAPI->SetPixelShaderConstant( modulationVar, color );
+}
+
+
+//-----------------------------------------------------------------------------
+// Converts a color + alpha into a vector4
+//-----------------------------------------------------------------------------
+void CBaseVSShader::ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color )
+{
+ color.Init( 1.0, 1.0, 1.0, 1.0 );
+ if ( colorVar != -1 )
+ {
+ IMaterialVar* pColorVar = s_ppParams[colorVar];
+ if ( pColorVar->GetType() == MATERIAL_VAR_TYPE_VECTOR )
+ {
+ pColorVar->GetVecValue( color.Base(), 3 );
+ }
+ else
+ {
+ color[0] = color[1] = color[2] = pColorVar->GetFloatValue();
+ }
+ }
+ if ( alphaVar != -1 )
+ {
+ float flAlpha = s_ppParams[alphaVar]->GetFloatValue();
+ color[3] = clamp( flAlpha, 0.0f, 1.0f );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets a color + alpha into shader constants
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar )
+{
+ Vector4D color;
+ ColorVarsToVector( colorVar, alphaVar, color );
+ s_pShaderAPI->SetVertexShaderConstant( nVertexReg, color.Base() );
+}
+
+void CBaseVSShader::SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar )
+{
+ Vector4D color;
+ ColorVarsToVector( colorVar, alphaVar, color );
+ s_pShaderAPI->SetPixelShaderConstant( nPixelReg, color.Base() );
+}
+
+#ifdef _DEBUG
+ConVar mat_envmaptintoverride( "mat_envmaptintoverride", "-1" );
+ConVar mat_envmaptintscale( "mat_envmaptintscale", "-1" );
+#endif
+
+//-----------------------------------------------------------------------------
+// Helpers for dealing with envmap tint
+//-----------------------------------------------------------------------------
+// set alphaVar to -1 to ignore it.
+void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear )
+{
+ float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 )
+ {
+ IMaterialVar* pAlphaVar = NULL;
+ if( alphaVar >= 0 )
+ {
+ pAlphaVar = s_ppParams[alphaVar];
+ }
+ if( pAlphaVar )
+ {
+ color[3] = pAlphaVar->GetFloatValue();
+ }
+
+ IMaterialVar* pTintVar = s_ppParams[tintVar];
+#ifdef _DEBUG
+ pTintVar->GetVecValue( color, 3 );
+
+ float envmapTintOverride = mat_envmaptintoverride.GetFloat();
+ float envmapTintScaleOverride = mat_envmaptintscale.GetFloat();
+
+ if( envmapTintOverride != -1.0f )
+ {
+ color[0] = color[1] = color[2] = envmapTintOverride;
+ }
+ if( envmapTintScaleOverride != -1.0f )
+ {
+ color[0] *= envmapTintScaleOverride;
+ color[1] *= envmapTintScaleOverride;
+ color[2] *= envmapTintScaleOverride;
+ }
+
+ if( bConvertFromGammaToLinear )
+ {
+ color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] );
+ color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] );
+ color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] );
+ }
+#else
+ if( bConvertFromGammaToLinear )
+ {
+ pTintVar->GetLinearVecValue( color, 3 );
+ }
+ else
+ {
+ pTintVar->GetVecValue( color, 3 );
+ }
+#endif
+ }
+ else
+ {
+ color[0] = color[1] = color[2] = color[3] = 0.0f;
+ }
+ s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 );
+}
+
+void CBaseVSShader::SetAmbientCubeDynamicStateVertexShader( )
+{
+ s_pShaderAPI->SetVertexShaderStateAmbientLightCube();
+}
+
+float CBaseVSShader::GetAmbientLightCubeLuminance( )
+{
+ return s_pShaderAPI->GetAmbientLightCubeLuminance();
+}
+
+#ifndef GAME_SHADER_DLL
+const char *CBaseVSShader::UnlitGeneric_ComputePixelShaderName( bool bMask,
+ bool bEnvmap,
+ bool bBaseTexture,
+ bool bBaseAlphaEnvmapMask,
+ bool bDetail,
+ bool bDetailMultiplyMode,
+ bool bMaskBaseByDetailAlpha )
+{
+ static char const* s_pPixelShaders[] =
+ {
+ "UnlitGeneric_NoTexture",
+ "UnlitGeneric",
+ "UnlitGeneric_EnvMapNoTexture",
+ "UnlitGeneric_EnvMap",
+ "UnlitGeneric_NoTexture",
+ "UnlitGeneric",
+ "UnlitGeneric_EnvMapMaskNoTexture",
+ "UnlitGeneric_EnvMapMask",
+
+ // Detail texture
+ // The other commented-out versions are used if we want to
+ // apply the detail *after* the environment map is added
+ "UnlitGeneric_DetailNoTexture",
+ "UnlitGeneric_Detail",
+ "UnlitGeneric_EnvMapNoTexture", //"UnlitGeneric_DetailEnvMapNoTexture",
+ "UnlitGeneric_DetailEnvMap",
+ "UnlitGeneric_DetailNoTexture",
+ "UnlitGeneric_Detail",
+ "UnlitGeneric_EnvMapMaskNoTexture", //"UnlitGeneric_DetailEnvMapMaskNoTexture",
+ "UnlitGeneric_DetailEnvMapMask",
+ };
+
+ // handle hud elements
+ if ( bDetail & bDetailMultiplyMode )
+ return "alphadist_ps11";
+
+ if ( bDetail & bMaskBaseByDetailAlpha )
+ return "UnlitGeneric_MaskBaseByDetailAlpha_ps11";
+
+ if (!bMask && bEnvmap && bBaseTexture && bBaseAlphaEnvmapMask)
+ {
+ if (!bDetail)
+ return "UnlitGeneric_BaseAlphaMaskedEnvMap";
+ else
+ return "UnlitGeneric_DetailBaseAlphaMaskedEnvMap";
+ }
+ else
+ {
+ int pshIndex = 0;
+ if (bBaseTexture)
+ pshIndex |= 0x1;
+ if (bEnvmap)
+ pshIndex |= 0x2;
+ if (bMask)
+ pshIndex |= 0x4;
+ if (bDetail)
+ pshIndex |= 0x8;
+ return s_pPixelShaders[pshIndex];
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets up hw morphing state for the vertex shader
+//-----------------------------------------------------------------------------
+void CBaseVSShader::SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler )
+{
+#ifndef _X360
+ if ( !s_pShaderAPI->IsHWMorphingEnabled() )
+ return;
+
+ int nMorphWidth, nMorphHeight;
+ s_pShaderAPI->GetStandardTextureDimensions( &nMorphWidth, &nMorphHeight, TEXTURE_MORPH_ACCUMULATOR );
+
+ int nDim = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_4TUPLE_COUNT );
+ float pMorphAccumSize[4] = { nMorphWidth, nMorphHeight, nDim, 0.0f };
+ s_pShaderAPI->SetVertexShaderConstant( nDimConst, pMorphAccumSize );
+
+ int nXOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_X_OFFSET );
+ int nYOffset = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_Y_OFFSET );
+ int nWidth = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_WIDTH );
+ int nHeight = s_pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_MORPH_ACCUMULATOR_SUBRECT_HEIGHT );
+ float pMorphAccumSubrect[4] = { nXOffset, nYOffset, nWidth, nHeight };
+ s_pShaderAPI->SetVertexShaderConstant( nSubrectConst, pMorphAccumSubrect );
+
+ s_pShaderAPI->BindStandardVertexTexture( morphSampler, TEXTURE_MORPH_ACCUMULATOR );
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Vertex shader unlit generic pass
+//-----------------------------------------------------------------------------
+void CBaseVSShader::VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar,
+ int baseTextureTransformVar,
+ int detailVar, int detailTransform,
+ bool bDetailTransformIsScale,
+ int envmapVar, int envMapFrameVar,
+ int envmapMaskVar, int envmapMaskFrameVar,
+ int envmapMaskScaleVar, int envmapTintVar,
+ int alphaTestReferenceVar,
+ int nDetailBlendModeVar,
+ int nOutlineVar,
+ int nOutlineColorVar,
+ int nOutlineStartVar,
+ int nOutlineEndVar,
+ int nSeparateDetailUVsVar )
+{
+ IMaterialVar** params = s_ppParams;
+
+ bool bBaseAlphaEnvmapMask = IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK);
+ bool bEnvmap = (envmapVar >= 0) && params[envmapVar]->IsTexture();
+ bool bMask = false;
+ if (bEnvmap && (envmapMaskVar >= 0))
+ {
+ bMask = params[envmapMaskVar]->IsTexture();
+ }
+ bool bDetail = (detailVar >= 0) && params[detailVar]->IsTexture();
+ bool bBaseTexture = (baseTextureVar >= 0) && params[baseTextureVar]->IsTexture();
+ bool bVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR);
+ bool bEnvmapCameraSpace = IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE);
+ bool bEnvmapSphere = IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE);
+
+ bool bDetailMultiply = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 8 );
+ bool bMaskBaseByDetailAlpha = ( nDetailBlendModeVar >= 0 ) && ( params[nDetailBlendModeVar]->GetIntValue() == 9 );
+ bool bSeparateDetailUVs = ( nSeparateDetailUVsVar >= 0 ) && ( params[nSeparateDetailUVsVar]->GetIntValue() != 0 );
+
+ if (IsSnapshotting())
+ {
+ // Alpha test
+ s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
+
+ if( alphaTestReferenceVar != -1 && params[alphaTestReferenceVar]->GetFloatValue() > 0.0f )
+ {
+ s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[alphaTestReferenceVar]->GetFloatValue() );
+ }
+
+ // Base texture on stage 0
+ if (bBaseTexture)
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ }
+
+ if (bDetail)
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ }
+
+ if (bEnvmap)
+ {
+ // envmap on stage 1
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+
+ // envmapmask on stage 2
+ if (bMask || bBaseAlphaEnvmapMask )
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ }
+
+ if (bBaseTexture)
+ SetDefaultBlendingShadowState( baseTextureVar, true );
+ else if (bMask)
+ SetDefaultBlendingShadowState( envmapMaskVar, false );
+ else
+ SetDefaultBlendingShadowState();
+
+ int fmt = VERTEX_POSITION;
+ if( bEnvmap )
+ fmt |= VERTEX_NORMAL;
+ if ( bVertexColor )
+ fmt |= VERTEX_COLOR;
+
+ int numTexCoords = 1;
+ if( bSeparateDetailUVs )
+ {
+ numTexCoords = 2;
+ }
+
+ s_pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 );
+ const char *pshName = UnlitGeneric_ComputePixelShaderName(
+ bMask,
+ bEnvmap,
+ bBaseTexture,
+ bBaseAlphaEnvmapMask,
+ bDetail,
+ bDetailMultiply,
+ bMaskBaseByDetailAlpha );
+ s_pShaderShadow->SetPixelShader( pshName );
+
+ // Compute the vertex shader index.
+ unlitgeneric_vs11_Static_Index vshIndex;
+ vshIndex.SetDETAIL( bDetail );
+ vshIndex.SetENVMAP( bEnvmap );
+ vshIndex.SetENVMAPCAMERASPACE( bEnvmap && bEnvmapCameraSpace );
+ vshIndex.SetENVMAPSPHERE( bEnvmap && bEnvmapSphere );
+ vshIndex.SetVERTEXCOLOR( bVertexColor );
+ vshIndex.SetSEPARATEDETAILUVS( bSeparateDetailUVs );
+ s_pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() );
+
+ DefaultFog();
+ }
+ else
+ {
+ if ( s_pShaderAPI->InFlashlightMode() ) // Not snapshotting && flashlight pass
+ {
+ Draw( false );
+ return;
+ }
+
+ if (bBaseTexture)
+ {
+ BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar );
+ }
+
+ if (bDetail)
+ {
+ BindTexture( SHADER_SAMPLER3, detailVar, frameVar );
+
+ if (bDetailTransformIsScale)
+ {
+ SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransformVar, detailTransform );
+ }
+ else
+ {
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, detailTransform );
+ }
+ }
+
+ if (bEnvmap)
+ {
+ BindTexture( SHADER_SAMPLER1, envmapVar, envMapFrameVar );
+
+ if (bMask || bBaseAlphaEnvmapMask)
+ {
+ if (bMask)
+ BindTexture( SHADER_SAMPLER2, envmapMaskVar, envmapMaskFrameVar );
+ else
+ BindTexture( SHADER_SAMPLER2, baseTextureVar, frameVar );
+
+ SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar, envmapMaskScaleVar );
+ }
+
+ SetEnvMapTintPixelShaderDynamicState( 2, envmapTintVar, -1 );
+
+ if (bEnvmapSphere || IS_FLAG_SET(MATERIAL_VAR_ENVMAPCAMERASPACE))
+ {
+ LoadViewMatrixIntoVertexShaderConstant( VERTEX_SHADER_VIEWMODEL );
+ }
+ }
+
+ SetModulationVertexShaderDynamicState();
+
+ float flConsts[12]={ 0, 0, 0, 1, // color
+ 0, 0, 0, 0, // max
+ 0, 0, 0, .5, // min
+ };
+
+ // set up outline pixel shader constants
+ if ( bDetailMultiply && ( nOutlineVar != -1 ) && ( params[nOutlineVar]->GetIntValue() ) )
+ {
+ if ( nOutlineColorVar != -1 )
+ params[nOutlineColorVar]->GetVecValue( flConsts, 3 );
+ if ( nOutlineEndVar != -1 )
+ flConsts[7] = params[nOutlineEndVar]->GetFloatValue();
+ if ( nOutlineStartVar != -1 )
+ flConsts[11] = params[nOutlineStartVar]->GetFloatValue();
+ }
+
+ s_pShaderAPI->SetPixelShaderConstant( 0, flConsts, 3 );
+
+ // Compute the vertex shader index.
+ unlitgeneric_vs11_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+
+ Draw();
+}
+
+
+void CBaseVSShader::DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar,
+ int frameVar, int colorVar, int alphaVar )
+{
+ if( IsSnapshotting() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->VertexShaderVertexFormat(
+ VERTEX_POSITION, 1, 0, 0 );
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BaseTexture" );
+ SetNormalBlendingShadowState();
+ lightmappedgeneric_basetexture_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BaseTexture", vshIndex.GetIndex() );
+
+ FogToOOOverbright();
+ }
+ else
+ {
+ IMaterialVar** params = s_ppParams;
+ bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
+ if( bLightingOnly )
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
+ }
+ else
+ {
+ BindTexture( SHADER_SAMPLER0, baseTextureVar, frameVar );
+ }
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar );
+ SetColorPixelShaderConstant( 0, colorVar, alphaVar );
+ lightmappedgeneric_basetexture_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar, bool bMultiply,
+ bool bSSBump )
+{
+ if( IsSnapshotting() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ if( bMultiply )
+ {
+ s_pShaderShadow->EnableBlending( true );
+ SingleTextureLightmapBlendMode();
+ }
+ s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 );
+
+ lightmappedgeneric_bumpmappedlightmap_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap", vshIndex.GetIndex() );
+
+ if ( bSSBump )
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_SSBumpmappedLightmap" );
+ else
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap" );
+ FogToFogColor();
+ }
+ else
+ {
+ if( !g_pConfig->m_bFastNoBump )
+ {
+ BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar );
+ }
+ else
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT );
+ }
+ LoadBumpLightmapCoordinateAxes_PixelShader( 0 );
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar );
+ SetModulationPixelShaderDynamicState( 3 );
+
+ lightmappedgeneric_bumpmappedlightmap_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar,
+ int baseTextureVar, int baseTextureTransformVar, int frameVar )
+{
+ if( IsSnapshotting() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 );
+
+ lightmappedgeneric_bumpmappedlightmap_base_ps14_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14", vshIndex.GetIndex() );
+
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Base_ps14" );
+ FogToFogColor();
+ }
+ else
+ {
+ if( !g_pConfig->m_bFastNoBump )
+ {
+ BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar );
+ }
+ else
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT );
+ }
+ LoadBumpLightmapCoordinateAxes_PixelShader( 0 );
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED );
+ BindTexture( SHADER_SAMPLER4, baseTextureVar, frameVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar );
+ SetModulationPixelShaderDynamicState( 3 );
+
+ lightmappedgeneric_bumpmappedlightmap_base_ps14_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar,
+ int baseTextureVar, int baseTextureTransformVar,
+ int baseTextureFrameVar,
+ int baseTexture2Var, int baseTextureTransform2Var,
+ int baseTextureFrame2Var)
+{
+ if( IsSnapshotting() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
+ s_pShaderShadow->VertexShaderVertexFormat( VERTEX_POSITION, 3, 0, 0 );
+
+ lightmappedgeneric_bumpmappedlightmap_blend_ps14_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14", vshIndex.GetIndex() );
+
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap_Blend_ps14" );
+ FogToFogColor();
+ }
+ else
+ {
+ if( !g_pConfig->m_bFastNoBump )
+ {
+ BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar );
+ }
+ else
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_NORMALMAP_FLAT );
+ }
+ LoadBumpLightmapCoordinateAxes_PixelShader( 0 );
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP_BUMPED );
+ BindTexture( SHADER_SAMPLER4, baseTextureVar, baseTextureFrameVar );
+ BindTexture( SHADER_SAMPLER5, baseTexture2Var, baseTextureFrame2Var );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransformVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, baseTextureTransform2Var );
+ SetModulationPixelShaderDynamicState( 3 );
+
+ lightmappedgeneric_bumpmappedlightmap_blend_ps14_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ Draw();
+}
+
+//#define USE_DEST_ALPHA
+#define USE_NORMALMAP_ALPHA
+
+void CBaseVSShader::DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar,
+ int bumpFrameVar, int envmapFrameVar,
+ int envmapTintVar, int alphaVar,
+ int envmapContrastVar, int envmapSaturationVar,
+ int bumpTransformVar, int fresnelReflectionVar,
+ bool bBlend, bool bNoWriteZ )
+{
+ // + BUMPED CUBEMAP
+ if( IsSnapshotting() )
+ {
+ SetInitialShadowState( );
+ if ( bNoWriteZ )
+ {
+ s_pShaderShadow->EnableDepthWrites( false );
+ }
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ }
+ if( bBlend )
+ {
+ s_pShaderShadow->EnableBlending( true );
+ s_pShaderShadow->BlendFunc( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE );
+ }
+ // FIXME: Remove the normal (needed for tangent space gen)
+ s_pShaderShadow->VertexShaderVertexFormat(
+ VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S |
+ VERTEX_TANGENT_T, 1, 0, 0 );
+
+ IMaterialVar** params = s_ppParams;
+ bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
+
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ lightmappedgeneric_bumpmappedenvmap_ps14_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", vshIndex.GetIndex() );
+
+ int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0;
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap_ps14", nPshIndex );
+ }
+ else
+ {
+ lightmappedgeneric_bumpmappedenvmap_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "LightmappedGeneric_BumpmappedEnvmap", vshIndex.GetIndex() );
+
+ int nPshIndex = bHasNormalMapAlphaEnvMapMask ? 1 : 0;
+ s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedEnvmap", nPshIndex );
+ }
+ FogToBlack();
+ }
+ else
+ {
+ IMaterialVar** params = s_ppParams;
+ s_pShaderAPI->SetDefaultState();
+ BindTexture( SHADER_SAMPLER0, bumpmapVar, bumpFrameVar );
+ BindTexture( SHADER_SAMPLER3, envmapVar, envmapFrameVar );
+
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP );
+
+ lightmappedgeneric_bumpmappedenvmap_ps14_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ else
+ {
+ lightmappedgeneric_bumpmappedenvmap_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+
+ SetEnvMapTintPixelShaderDynamicState( 0, envmapTintVar, alphaVar );
+ // GR - fudge consts a bit to fix const/lerp issues
+ SetPixelShaderConstantFudge( 1, envmapContrastVar );
+ SetPixelShaderConstantFudge( 2, envmapSaturationVar );
+ float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f };
+ s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights );
+
+ // [ 0, 0 ,0, R(0) ]
+ float fresnel[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ fresnel[3] = params[fresnelReflectionVar]->GetFloatValue();
+ s_pShaderAPI->SetPixelShaderConstant( 4, fresnel );
+ // [ 0, 0 ,0, 1-R(0) ]
+ fresnel[3] = 1.0f - fresnel[3];
+ s_pShaderAPI->SetPixelShaderConstant( 6, fresnel );
+
+ float one[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ s_pShaderAPI->SetPixelShaderConstant( 5, one );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, bumpTransformVar );
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar,
+ int envMapVar, int envMapVarFrame,
+ int envMapTintVar, int alphaVar,
+ int envMapContrastVar, int envMapSaturationVar,
+ int bumpTransformVar,
+ bool bBlendSpecular, bool bNoWriteZ )
+{
+ IMaterialVar** params = s_ppParams;
+
+ if( IsSnapshotting() )
+ {
+ SetInitialShadowState( );
+ if ( bNoWriteZ )
+ {
+ s_pShaderShadow->EnableDepthWrites( false );
+ }
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ }
+ s_pShaderShadow->EnableAlphaTest( false );
+ if( bBlendSpecular )
+ {
+ s_pShaderShadow->EnableBlending( true );
+ SetAdditiveBlendingShadowState( -1, false );
+ }
+ else
+ {
+ s_pShaderShadow->EnableBlending( false );
+ SetNormalBlendingShadowState( -1, false );
+ }
+
+ s_pShaderShadow->VertexShaderVertexFormat(
+ VERTEX_POSITION | VERTEX_NORMAL, 1, 0, 4 /* userDataSize */ );
+
+ bool bHasNormalMapAlphaEnvMapMask = IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
+
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting_ps14", vshIndex.GetIndex() );
+ if( bHasNormalMapAlphaEnvMapMask )
+ {
+ s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha_ps14" );
+ }
+ else
+ {
+ s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_ps14" );
+ }
+ }
+ else
+ {
+ vertexlitgeneric_envmappedbumpmap_nolighting_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "VertexLitGeneric_EnvmappedBumpmap_NoLighting", vshIndex.GetIndex() );
+ // This version does not multiply by lighting
+ // NOTE: We don't support multiplying by lighting for bumped specular stuff.
+ if( bHasNormalMapAlphaEnvMapMask )
+ {
+ s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2_MultByAlpha" );
+ }
+ else
+ {
+ s_pShaderShadow->SetPixelShader( "VertexLitGeneric_EnvmappedBumpmapV2" );
+ }
+ }
+ FogToBlack();
+ }
+ else
+ {
+ s_pShaderAPI->SetDefaultState();
+ BindTexture( SHADER_SAMPLER0, bumpMapVar, bumpMapFrameVar );
+ BindTexture( SHADER_SAMPLER3, envMapVar, envMapVarFrame );
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALIZATION_CUBEMAP );
+ }
+
+ if( bBlendSpecular )
+ {
+ SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, -1 );
+ }
+ else
+ {
+ SetEnvMapTintPixelShaderDynamicState( 0, envMapTintVar, alphaVar );
+ }
+ // GR - fudge consts a bit to fix const/lerp issues
+ SetPixelShaderConstantFudge( 1, envMapContrastVar );
+ SetPixelShaderConstantFudge( 2, envMapSaturationVar );
+ float greyWeights[4] = { 0.299f, 0.587f, 0.114f, 0.0f };
+ s_pShaderAPI->SetPixelShaderConstant( 3, greyWeights );
+
+ // handle scrolling of bump texture
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, bumpTransformVar );
+
+ if( g_pHardwareConfig->SupportsPixelShaders_1_4() )
+ {
+ vertexlitgeneric_envmappedbumpmap_nolighting_ps14_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ else
+ {
+ vertexlitgeneric_envmappedbumpmap_nolighting_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ vshIndex.SetSKINNING( s_pShaderAPI->GetCurrentNumBones() > 0 );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar,
+ int baseTextureFrameVar,
+ int baseTexture2Var, int baseTextureTransform2Var,
+ int baseTextureFrame2Var, int colorVar, int alphaVar )
+{
+ if( IsSnapshotting() )
+ {
+ SetInitialShadowState();
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ s_pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ s_pShaderShadow->DrawFlags( SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD0 |
+ SHADER_DRAW_LIGHTMAP_TEXCOORD1 );
+ // FIXME: Remove the normal (needed for tangent space gen)
+ s_pShaderShadow->VertexShaderVertexFormat(
+ VERTEX_POSITION, 2, 0, 0 );
+
+ lightmappedgeneric_basetextureblend_Static_Index vshIndex;
+ s_pShaderShadow->SetVertexShader( "lightmappedgeneric_basetextureblend", vshIndex.GetIndex() );
+
+ s_pShaderShadow->SetPixelShader( "lightmappedgeneric_basetextureblend", 0 );
+ FogToOOOverbright();
+ }
+ else
+ {
+ IMaterialVar** params = s_ppParams;
+ bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
+
+ s_pShaderAPI->SetDefaultState();
+ if( bLightingOnly )
+ {
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY );
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
+ }
+ else
+ {
+ BindTexture( SHADER_SAMPLER0, baseTextureVar, baseTextureFrameVar );
+ BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTextureFrame2Var );
+ }
+ s_pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_LIGHTMAP );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, baseTextureTransformVar );
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, baseTextureTransform2Var );
+ SetColorPixelShaderConstant( 0, colorVar, alphaVar );
+ lightmappedgeneric_basetextureblend_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( s_pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ s_pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ Draw();
+}
+
+void CBaseVSShader::DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar,
+ int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar,
+ int envmapMaskVar, int envmapMaskFrame,
+ int envmapVar,
+ int envmapFrameVar,
+ int envmapTintVar, int colorVar, int alphaVar,
+ int envmapContrastVar, int envmapSaturationVar,
+ int frameVar, int fresnelReflectionVar,
+ bool doBaseTexture2,
+ int baseTexture2Var, int baseTextureTransform2Var,
+ int baseTextureFrame2Var,
+ bool bSSBump
+ )
+{
+ IMaterialVar** params = s_ppParams;
+ // Draw base texture
+ bool bMultiplyDiffuseLighting = false;
+ bool bBlendSpecular = false;
+
+ // Draw base texture(s)
+ if( doBaseTexture2 && params[baseTexture2Var]->IsTexture() && params[baseTextureVar]->IsTexture() )
+ {
+ DrawBaseTextureBlend( baseTextureVar, baseTextureTransformVar, frameVar,
+ baseTexture2Var, baseTextureTransform2Var, baseTextureFrame2Var, colorVar, alphaVar );
+ bMultiplyDiffuseLighting = true;
+ bBlendSpecular = true;
+ }
+ else if( params[baseTextureVar]->IsTexture() )
+ {
+ DrawWorldBaseTexture( baseTextureVar, baseTextureTransformVar, frameVar, colorVar, alphaVar );
+ bMultiplyDiffuseLighting = true;
+ bBlendSpecular = true;
+ }
+ else
+ {
+ // Just use color here
+ }
+
+ // Draw diffuse lighting
+ if( params[baseTextureVar]->IsTexture() || !params[envmapVar]->IsTexture() )
+ {
+ DrawWorldBumpedDiffuseLighting( bumpmapVar, bumpFrameVar, bumpTransformVar,
+ bMultiplyDiffuseLighting, bSSBump );
+ bBlendSpecular = true;
+ }
+
+ // Add specular lighting
+ if( params[envmapVar]->IsTexture() )
+ {
+ DrawWorldBumpedSpecularLighting(
+ bumpmapVar, envmapVar,
+ bumpFrameVar, envmapFrameVar,
+ envmapTintVar, alphaVar,
+ envmapContrastVar, envmapSaturationVar,
+ bumpTransformVar, fresnelReflectionVar,
+ bBlendSpecular );
+ }
+}
+#endif // GAME_SHADER_DLL
+
+
+//-----------------------------------------------------------------------------
+// GR - translucency query
+//-----------------------------------------------------------------------------
+BlendType_t CBaseVSShader::EvaluateBlendRequirements( int textureVar, bool isBaseTexture,
+ int detailTextureVar )
+{
+ // Either we've got a constant modulation
+ bool isTranslucent = IsAlphaModulating();
+
+ // Or we've got a vertex alpha
+ isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA);
+
+ // Or we've got a texture alpha (for blending or alpha test)
+ isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) &&
+ !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) );
+
+ if ( ( detailTextureVar != -1 ) && ( ! isTranslucent ) )
+ {
+ isTranslucent = TextureIsTranslucent( detailTextureVar, isBaseTexture );
+ }
+
+ if ( CurrentMaterialVarFlags() & MATERIAL_VAR_ADDITIVE )
+ {
+ return isTranslucent ? BT_BLENDADD : BT_ADD; // Additive
+ }
+ else
+ {
+ return isTranslucent ? BT_BLEND : BT_NONE; // Normal blending
+ }
+}
+
+#ifndef GAME_SHADER_DLL
+
+void CBaseVSShader::SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms )
+{
+ Assert( !IsSnapshotting() );
+
+ VMatrix worldToTexture;
+ const FlashlightState_t &flashlightState = s_pShaderAPI->GetFlashlightState( worldToTexture );
+
+ // Set the flashlight origin
+ float pos[4];
+ pos[0] = flashlightState.m_vecLightOrigin[0];
+ pos[1] = flashlightState.m_vecLightOrigin[1];
+ pos[2] = flashlightState.m_vecLightOrigin[2];
+ pos[3] = 1.0f / ( ( 0.6f * flashlightState.m_FarZ ) - flashlightState.m_FarZ ); // DX8 needs this
+
+ s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, pos, 1 );
+
+ s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, worldToTexture.Base(), 4 );
+
+ // Set the flashlight attenuation factors
+ float atten[4];
+ atten[0] = flashlightState.m_fConstantAtten;
+ atten[1] = flashlightState.m_fLinearAtten;
+ atten[2] = flashlightState.m_fQuadraticAtten;
+ atten[3] = flashlightState.m_FarZ;
+ s_pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_5, atten, 1 );
+
+ if ( bDetail )
+ {
+ SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, BASETEXTURETRANSFORM, detailScaleVar );
+ }
+
+ if( bSetTextureTransforms )
+ {
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, BASETEXTURETRANSFORM );
+ if( !bDetail && bBump && bumpTransformVar != -1 )
+ {
+ SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_8, bumpTransformVar ); // aliased on top of detail transform
+ }
+ }
+}
+
+#if SUPPORT_DX8
+void CBaseVSShader::DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool bBump,
+ int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar, int flashlightTextureFrameVar,
+ bool bLightmappedGeneric, bool bWorldVertexTransition, int nWorldVertexTransitionPassID, int baseTexture2Var,
+ int baseTexture2FrameVar, bool bTeeth, int nTeethForwardVar, int nTeethIllumFactorVar )
+{
+ // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric
+ if( !bLightmappedGeneric )
+ {
+ bBump = false;
+ }
+ if( pShaderShadow )
+ {
+ SetInitialShadowState();
+ pShaderShadow->EnableDepthWrites( false );
+
+ // Be sure not to write to dest alpha
+ pShaderShadow->EnableAlphaWrites( false );
+
+ // Never alpha test the flashlight pass
+ pShaderShadow->EnableAlphaTest( false );
+
+ if ( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) )
+ {
+ // use zfunc zequals since alpha isn't guaranteed to
+ // be the same on both the regular pass and the flashlight pass.
+ pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
+ }
+
+ // Alpha blend
+ if( bWorldVertexTransition )
+ {
+ // use separate alpha blend to make sure that we aren't adding alpha from source
+ if( nWorldVertexTransitionPassID == 0 )
+ {
+ EnableAlphaBlending( SHADER_BLEND_DST_ALPHA, SHADER_BLEND_ONE );
+ }
+ else
+ {
+ EnableAlphaBlending( SHADER_BLEND_ONE_MINUS_DST_ALPHA, SHADER_BLEND_ONE );
+ }
+ }
+ else
+ {
+ SetAdditiveBlendingShadowState( BASETEXTURE, true );
+ }
+
+ pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+
+ if( bLightmappedGeneric )
+ {
+ bool bUsingVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
+ lightmappedgeneric_flashlight_vs11_Static_Index vshIndex;
+ vshIndex.SetNORMALMAP( bBump );
+ vshIndex.SetWORLDVERTEXTRANSITION( bWorldVertexTransition );
+ vshIndex.SetVERTEXCOLOR( bUsingVertexColor );
+ pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs11", vshIndex.GetIndex() );
+
+ unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
+ if( bBump )
+ {
+ flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
+ }
+ if ( bWorldVertexTransition || bUsingVertexColor )
+ {
+ flags |= VERTEX_COLOR;
+ }
+ pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, 0 );
+ }
+ else
+ {
+ vertexlitgeneric_flashlight_vs11_Static_Index vshIndex;
+ vshIndex.SetTEETH( bTeeth );
+ pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() );
+
+ unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
+ pShaderShadow->VertexShaderVertexFormat( flags, 1, 0, bBump ? 4 : 0 );
+ }
+
+ bool bNoCull = IS_FLAG_SET( MATERIAL_VAR_NOCULL );
+
+ flashlight_ps11_Static_Index pshIndex;
+ pshIndex.SetNORMALMAP( bBump );
+ pshIndex.SetNOCULL( bNoCull );
+ pShaderShadow->SetPixelShader( "flashlight_ps11", pshIndex.GetIndex() );
+
+ FogToBlack();
+ }
+ else
+ {
+ // Specify that we have XYZ texcoords that need to be divided by W before the pixel shader.
+ // NOTE Tried to divide XY by Z, but doesn't work.
+ // The dx9.0c runtime says that we shouldn't have a non-zero dimension when using vertex and pixel shaders.
+ pShaderAPI->SetTextureTransformDimension( SHADER_TEXTURE_STAGE0, 0, true );
+ BindTexture( SHADER_SAMPLER0, flashlightTextureVar, flashlightTextureFrameVar );
+
+ if( bWorldVertexTransition && ( nWorldVertexTransitionPassID == 1 ) )
+ {
+ BindTexture( SHADER_SAMPLER1, baseTexture2Var, baseTexture2FrameVar );
+ }
+ else
+ {
+ if( params[BASETEXTURE]->IsTexture() )
+ {
+ BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME );
+ }
+ else
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
+ }
+ }
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP );
+ if( bBump )
+ {
+ BindTexture( SHADER_SAMPLER3, bumpmapVar, bumpmapFrame );
+ }
+ else
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP );
+ }
+
+ if( bLightmappedGeneric )
+ {
+ lightmappedgeneric_flashlight_vs11_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+ else
+ {
+ vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+
+ if( bTeeth )
+ {
+ Assert( nTeethForwardVar >= 0 );
+ Assert( nTeethIllumFactorVar >= 0 );
+ Vector4D lighting;
+ params[nTeethForwardVar]->GetVecValue( lighting.Base(), 3 );
+ lighting[3] = params[nTeethIllumFactorVar]->GetFloatValue();
+ pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, lighting.Base() );
+ }
+
+ vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 );
+ pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+ }
+
+ flashlight_ps11_Dynamic_Index pshIndex;
+ pShaderAPI->SetPixelShaderIndex( pshIndex.GetIndex() );
+
+ SetFlashlightVertexShaderConstants( bBump, bumpTransform, false, -1, true );
+ }
+ Draw();
+}
+#endif // support_dx8
+
+#ifdef STDSHADER_DX9_DLL_EXPORT
+void CBaseVSShader::DrawFlashlight_dx90( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
+ IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars )
+{
+ // FLASHLIGHTFIXME: hack . . need to fix the vertex shader so that it can deal with and without bumps for vertexlitgeneric
+ if( !vars.m_bLightmappedGeneric )
+ {
+ vars.m_bBump = false;
+ }
+ bool bBump2 = vars.m_bWorldVertexTransition && vars.m_bBump && vars.m_nBumpmap2Var != -1 && params[vars.m_nBumpmap2Var]->IsTexture();
+ bool bSeamless = vars.m_fSeamlessScale != 0.0;
+ bool bDetail = vars.m_bLightmappedGeneric && (vars.m_nDetailVar != -1) && params[vars.m_nDetailVar]->IsDefined() && (vars.m_nDetailScale != -1);
+
+ int nDetailBlendMode = 0;
+ if ( bDetail )
+ {
+ nDetailBlendMode = GetIntParam( vars.m_nDetailTextureCombineMode, params );
+ nDetailBlendMode = nDetailBlendMode > 1 ? 1 : nDetailBlendMode;
+ }
+
+ if( pShaderShadow )
+ {
+ SetInitialShadowState();
+ pShaderShadow->EnableDepthWrites( false );
+ pShaderShadow->EnableAlphaWrites( false );
+
+ // Alpha blend
+ SetAdditiveBlendingShadowState( BASETEXTURE, true );
+
+ // Alpha test
+ pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) );
+ if ( vars.m_nAlphaTestReference != -1 && params[vars.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
+ {
+ pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[vars.m_nAlphaTestReference]->GetFloatValue() );
+ }
+
+ // Spot sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
+
+ // Base sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true );
+
+ // Normalizing cubemap sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER2, true );
+
+ // Normalizing cubemap sampler2 or normal map sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER3, true );
+
+ // RandomRotation sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
+
+ // Flashlight depth sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER7, true );
+ pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER7 );
+
+ if( vars.m_bWorldVertexTransition )
+ {
+ // $basetexture2
+ pShaderShadow->EnableTexture( SHADER_SAMPLER4, true );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true );
+ }
+ if( bBump2 )
+ {
+ // Normalmap2 sampler
+ pShaderShadow->EnableTexture( SHADER_SAMPLER6, true );
+ }
+ if( bDetail )
+ {
+ pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); // detail sampler
+ if ( nDetailBlendMode != 0 ) //Not Mod2X
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER8, true );
+ }
+
+ pShaderShadow->EnableSRGBWrite( true );
+
+ if( vars.m_bLightmappedGeneric )
+ {
+ lightmappedgeneric_flashlight_vs20_Static_Index vshIndex;
+ vshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition );
+ vshIndex.SetNORMALMAP( vars.m_bBump );
+ vshIndex.SetSEAMLESS( bSeamless );
+ vshIndex.SetDETAIL( bDetail );
+ pShaderShadow->SetVertexShader( "lightmappedgeneric_flashlight_vs20", vshIndex.GetIndex() );
+
+ unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
+ if( vars.m_bBump )
+ {
+ flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T;
+ }
+ int numTexCoords = 1;
+ if( vars.m_bWorldVertexTransition )
+ {
+ flags |= VERTEX_COLOR;
+ numTexCoords = 2; // need lightmap texcoords to get alpha.
+ }
+ pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
+ }
+ else
+ {
+ vertexlitgeneric_flashlight_vs11_Static_Index vshIndex;
+ vshIndex.SetTEETH( vars.m_bTeeth );
+ pShaderShadow->SetVertexShader( "vertexlitgeneric_flashlight_vs11", vshIndex.GetIndex() );
+
+ unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
+ int numTexCoords = 1;
+ pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, vars.m_bBump ? 4 : 0 );
+ }
+
+ int nBumpMapVariant = 0;
+ if ( vars.m_bBump )
+ {
+ nBumpMapVariant = ( vars.m_bSSBump ) ? 2 : 1;
+ }
+ if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
+ {
+ int nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode();
+
+ flashlight_ps20b_Static_Index pshIndex;
+ pshIndex.SetNORMALMAP( nBumpMapVariant );
+ pshIndex.SetNORMALMAP2( bBump2 );
+ pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition );
+ pshIndex.SetSEAMLESS( bSeamless );
+ pshIndex.SetDETAILTEXTURE( bDetail );
+ pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode );
+ pshIndex.SetFLASHLIGHTDEPTHFILTERMODE( nShadowFilterMode );
+ pShaderShadow->SetPixelShader( "flashlight_ps20b", pshIndex.GetIndex() );
+ }
+ else
+ {
+ flashlight_ps20_Static_Index pshIndex;
+ pshIndex.SetNORMALMAP( nBumpMapVariant );
+ pshIndex.SetNORMALMAP2( bBump2 );
+ pshIndex.SetWORLDVERTEXTRANSITION( vars.m_bWorldVertexTransition );
+ pshIndex.SetSEAMLESS( bSeamless );
+ pshIndex.SetDETAILTEXTURE( bDetail );
+ pshIndex.SetDETAIL_BLEND_MODE( nDetailBlendMode );
+ pShaderShadow->SetPixelShader( "flashlight_ps20", pshIndex.GetIndex() );
+ }
+ FogToBlack();
+ }
+ else
+ {
+ VMatrix worldToTexture;
+ ITexture *pFlashlightDepthTexture;
+ FlashlightState_t flashlightState = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
+
+ SetFlashLightColorFromState( flashlightState, pShaderAPI );
+
+ BindTexture( SHADER_SAMPLER0, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame );
+
+ if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && flashlightState.m_bEnableShadows )
+ {
+ BindTexture( SHADER_SAMPLER7, pFlashlightDepthTexture, 0 );
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D );
+
+ // Tweaks associated with a given flashlight
+ float tweaks[4];
+ tweaks[0] = ShadowFilterFromState( flashlightState );
+ tweaks[1] = ShadowAttenFromState( flashlightState );
+ HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
+ pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
+
+ // Dimensions of screen, used for screen-space noise map sampling
+ float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
+ int nWidth, nHeight;
+ pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
+ vScreenScale[0] = (float) nWidth / 32.0f;
+ vScreenScale[1] = (float) nHeight / 32.0f;
+ pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
+ }
+
+ if( params[BASETEXTURE]->IsTexture() && mat_fullbright.GetInt() != 2 )
+ {
+ BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME );
+ }
+ else
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER1, TEXTURE_GREY );
+ }
+ if( vars.m_bWorldVertexTransition )
+ {
+ Assert( vars.m_nBaseTexture2Var >= 0 && vars.m_nBaseTexture2FrameVar >= 0 );
+ BindTexture( SHADER_SAMPLER4, vars.m_nBaseTexture2Var, vars.m_nBaseTexture2FrameVar );
+ }
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_NORMALIZATION_CUBEMAP );
+ if( vars.m_bBump )
+ {
+ BindTexture( SHADER_SAMPLER3, vars.m_nBumpmapVar, vars.m_nBumpmapFrame );
+ }
+ else
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_NORMALIZATION_CUBEMAP );
+ }
+
+ if( bDetail )
+ {
+ BindTexture( SHADER_SAMPLER8, vars.m_nDetailVar );
+ }
+
+ if( vars.m_bWorldVertexTransition )
+ {
+ if( bBump2 )
+ {
+ BindTexture( SHADER_SAMPLER6, vars.m_nBumpmap2Var, vars.m_nBumpmap2Frame );
+ }
+ }
+
+ if( vars.m_bLightmappedGeneric )
+ {
+ DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ SET_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_flashlight_vs20 );
+ if ( bSeamless )
+ {
+ float const0[4]={ vars.m_fSeamlessScale,0,0,0};
+ pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6, const0 );
+ }
+
+ if ( bDetail )
+ {
+ float vDetailConstants[4] = {1,1,1,1};
+
+ if ( vars.m_nDetailTint != -1 )
+ {
+ params[vars.m_nDetailTint]->GetVecValue( vDetailConstants, 3 );
+ }
+
+ if ( vars.m_nDetailTextureBlendFactor != -1 )
+ {
+ vDetailConstants[3] = params[vars.m_nDetailTextureBlendFactor]->GetFloatValue();
+ }
+
+ pShaderAPI->SetPixelShaderConstant( 0, vDetailConstants, 1 );
+ }
+ }
+ else
+ {
+ vertexlitgeneric_flashlight_vs11_Dynamic_Index vshIndex;
+ vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
+ vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 );
+ pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
+
+ if( vars.m_bTeeth )
+ {
+ Assert( vars.m_nTeethForwardVar >= 0 );
+ Assert( vars.m_nTeethIllumFactorVar >= 0 );
+ Vector4D lighting;
+ params[vars.m_nTeethForwardVar]->GetVecValue( lighting.Base(), 3 );
+ lighting[3] = params[vars.m_nTeethIllumFactorVar]->GetFloatValue();
+ pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, lighting.Base() );
+ }
+ }
+
+ pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
+
+ float vEyePos_SpecExponent[4];
+ pShaderAPI->GetWorldSpaceCameraPosition( vEyePos_SpecExponent );
+ vEyePos_SpecExponent[3] = 0.0f;
+ pShaderAPI->SetPixelShaderConstant( PSREG_EYEPOS_SPEC_EXPONENT, vEyePos_SpecExponent, 1 );
+
+ if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
+ {
+ DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20b );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, flashlightState.m_bEnableShadows && ( pFlashlightDepthTexture != NULL ) );
+ SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20b );
+ }
+ else
+ {
+ DECLARE_DYNAMIC_PIXEL_SHADER( flashlight_ps20 );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
+ SET_DYNAMIC_PIXEL_SHADER( flashlight_ps20 );
+ }
+
+ float atten[4]; // Set the flashlight attenuation factors
+ atten[0] = flashlightState.m_fConstantAtten;
+ atten[1] = flashlightState.m_fLinearAtten;
+ atten[2] = flashlightState.m_fQuadraticAtten;
+ atten[3] = flashlightState.m_FarZ;
+ s_pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
+
+ SetFlashlightVertexShaderConstants( vars.m_bBump, vars.m_nBumpTransform, bDetail, vars.m_nDetailScale, bSeamless ? false : true );
+ }
+ Draw();
+}
+
+#endif
+
+void CBaseVSShader::InitParamsUnlitGeneric_DX8(
+ int baseTextureVar,
+ int detailScaleVar,
+ int envmapOptionalVar,
+ int envmapVar,
+ int envmapTintVar,
+ int envmapMaskScaleVar,
+ int nDetailBlendMode )
+{
+ IMaterialVar** params = s_ppParams;
+
+ SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
+
+ if( envmapTintVar >= 0 && !params[envmapTintVar]->IsDefined() )
+ {
+ params[envmapTintVar]->SetVecValue( 1.0f, 1.0f, 1.0f );
+ }
+
+ if( envmapMaskScaleVar >= 0 && !params[envmapMaskScaleVar]->IsDefined() )
+ {
+ params[envmapMaskScaleVar]->SetFloatValue( 1.0f );
+ }
+
+ if( detailScaleVar >= 0 && !params[detailScaleVar]->IsDefined() )
+ {
+ params[detailScaleVar]->SetFloatValue( 4.0f );
+ }
+
+ // No texture means no self-illum or env mask in base alpha
+ if ( baseTextureVar >= 0 && !params[baseTextureVar]->IsDefined() )
+ {
+ CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
+ }
+
+ // If in decal mode, no debug override...
+ if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
+ {
+ SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
+ }
+
+ // Get rid of the envmap if it's optional for this dx level.
+ if( envmapOptionalVar >= 0 && params[envmapOptionalVar]->IsDefined() && params[envmapOptionalVar]->GetIntValue() )
+ {
+ if (envmapVar >= 0)
+ {
+ params[envmapVar]->SetUndefined();
+ }
+ }
+
+ // If mat_specular 0, then get rid of envmap
+ if( envmapVar >= 0 && baseTextureVar >= 0 && !g_pConfig->UseSpecular() && params[envmapVar]->IsDefined() && params[baseTextureVar]->IsDefined() )
+ {
+ params[envmapVar]->SetUndefined();
+ }
+}
+
+void CBaseVSShader::InitUnlitGeneric_DX8(
+ int baseTextureVar,
+ int detailVar,
+ int envmapVar,
+ int envmapMaskVar )
+{
+ IMaterialVar** params = s_ppParams;
+
+ if (baseTextureVar >= 0 && params[baseTextureVar]->IsDefined())
+ {
+ LoadTexture( baseTextureVar );
+
+ if (!params[baseTextureVar]->GetTextureValue()->IsTranslucent())
+ {
+ if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK))
+ CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
+ }
+ }
+
+ // Don't alpha test if the alpha channel is used for other purposes
+ if ( IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
+ CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
+
+ // the second texture (if there is one)
+ if (detailVar >= 0 && params[detailVar]->IsDefined())
+ {
+ LoadTexture( detailVar );
+ }
+
+ if (envmapVar >= 0 && params[envmapVar]->IsDefined())
+ {
+ if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) )
+ LoadCubeMap( envmapVar );
+ else
+ LoadTexture( envmapVar );
+
+ if( !g_pHardwareConfig->SupportsCubeMaps() )
+ SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE);
+
+ if (envmapMaskVar >= 0 && params[envmapMaskVar]->IsDefined())
+ LoadTexture( envmapMaskVar );
+ }
+}
+#endif // GAME_SHADER_DLL
+
+#endif // !_STATIC_LINKED || STDSHADER_DX8_DLL_EXPORT
+
+
+// Take 0..1 seed and map to (u, v) coordinate to be used in shadow filter jittering...
+void CBaseVSShader::HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV )
+{
+ const int nTexRes = 32;
+ int nSeed = fmod (fJitterSeed, 1.0f) * nTexRes * nTexRes;
+
+ int nRow = nSeed / nTexRes;
+ int nCol = nSeed % nTexRes;
+
+ // Div and mod to get an individual texel in the fTexRes x fTexRes grid
+ *fU = nRow / (float) nTexRes; // Row
+ *fV = nCol / (float) nTexRes; // Column
+}
+
+
+void CBaseVSShader::DrawEqualDepthToDestAlpha( void )
+{
+#ifdef STDSHADER_DX9_DLL_EXPORT
+ if( g_pHardwareConfig->SupportsPixelShaders_2_b() )
+ {
+ bool bMakeActualDrawCall = false;
+ if( s_pShaderShadow )
+ {
+ s_pShaderShadow->EnableColorWrites( false );
+ s_pShaderShadow->EnableAlphaWrites( true );
+ s_pShaderShadow->EnableDepthWrites( false );
+ s_pShaderShadow->EnableAlphaTest( false );
+ s_pShaderShadow->EnableBlending( false );
+
+ s_pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
+
+ s_pShaderShadow->SetVertexShader( "depthtodestalpha_vs20", 0 );
+ s_pShaderShadow->SetPixelShader( "depthtodestalpha_ps20b", 0 );
+ }
+ if( s_pShaderAPI )
+ {
+ s_pShaderAPI->SetVertexShaderIndex( 0 );
+ s_pShaderAPI->SetPixelShaderIndex( 0 );
+
+ bMakeActualDrawCall = s_pShaderAPI->ShouldWriteDepthToDestAlpha();
+ }
+ Draw( bMakeActualDrawCall );
+ }
+#else
+ Assert( 0 ); //probably just needs a shader update to the latest
+#endif
+}
diff --git a/mp/src/materialsystem/stdshaders/BaseVSShader.h b/mp/src/materialsystem/stdshaders/BaseVSShader.h new file mode 100644 index 00000000..2a38afb1 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/BaseVSShader.h @@ -0,0 +1,439 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+// This is what all vs/ps (dx8+) shaders inherit from.
+//===========================================================================//
+
+#ifndef BASEVSSHADER_H
+#define BASEVSSHADER_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "shaderlib/cshader.h"
+#include "shaderlib/BaseShader.h"
+#include "convar.h"
+#include <renderparm.h>
+
+#ifdef _X360
+#define SUPPORT_DX8 0
+#define SUPPORT_DX7 0
+#else
+#define SUPPORT_DX8 1
+#define SUPPORT_DX7 1
+#endif
+//-----------------------------------------------------------------------------
+// Helper macro for vertex shaders
+//-----------------------------------------------------------------------------
+#define BEGIN_VS_SHADER_FLAGS(_name, _help, _flags) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, _flags )
+#define BEGIN_VS_SHADER(_name,_help) __BEGIN_SHADER_INTERNAL( CBaseVSShader, _name, _help, 0 )
+
+
+// useful parameter initialization macro
+#define INIT_FLOAT_PARM( parm, value ) \
+ if ( !params[(parm)]->IsDefined() ) \
+ { \
+ params[(parm)]->SetFloatValue( (value) ); \
+ }
+
+// useful pixel shader declaration macro for ps20/20b c++ code
+#define SET_STATIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
+ if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
+ { \
+ DECLARE_STATIC_PIXEL_SHADER( basename##_ps20b ); \
+ SET_STATIC_PIXEL_SHADER( basename##_ps20b ); \
+ } \
+ else \
+ { \
+ DECLARE_STATIC_PIXEL_SHADER( basename##_ps20 ); \
+ SET_STATIC_PIXEL_SHADER( basename##_ps20 ); \
+ }
+
+#define SET_DYNAMIC_PS2X_PIXEL_SHADER_NO_COMBOS( basename ) \
+ if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) \
+ { \
+ DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
+ SET_DYNAMIC_PIXEL_SHADER( basename##_ps20b ); \
+ } \
+ else \
+ { \
+ DECLARE_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
+ SET_DYNAMIC_PIXEL_SHADER( basename##_ps20 ); \
+ }
+
+
+//-----------------------------------------------------------------------------
+// Base class for shaders, contains helper methods.
+//-----------------------------------------------------------------------------
+class CBaseVSShader : public CBaseShader
+{
+public:
+
+ // Loads bump lightmap coordinates into the pixel shader
+ void LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg );
+
+ // Loads bump lightmap coordinates into the vertex shader
+ void LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg );
+
+ // Pixel and vertex shader constants....
+ void SetPixelShaderConstant( int pixelReg, int constantVar );
+
+ // Pixel and vertex shader constants....
+ void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar );
+
+ // This version will put constantVar into x,y,z, and constantVar2 into the w
+ void SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 );
+ void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar, int constantVar2 );
+
+ // Helpers for setting constants that need to be converted to linear space (from gamma space).
+ void SetVertexShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
+ void SetPixelShaderConstantGammaToLinear( int var, float const* pVec, int numConst = 1, bool bForce = false );
+
+ void SetVertexShaderConstant( int vertexReg, int constantVar );
+
+ // set rgb components of constant from a color parm and give an explicit w value
+ void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue );
+
+ // GR - fix for const/lerp issues
+ void SetPixelShaderConstantFudge( int pixelReg, int constantVar );
+
+ // Sets light direction for pixel shaders.
+ void SetPixelShaderLightColors( int pixelReg );
+
+ // Sets vertex shader texture transforms
+ void SetVertexShaderTextureTranslation( int vertexReg, int translationVar );
+ void SetVertexShaderTextureScale( int vertexReg, int scaleVar );
+ void SetVertexShaderTextureTransform( int vertexReg, int transformVar );
+ void SetVertexShaderTextureScaledTransform( int vertexReg,
+ int transformVar, int scaleVar );
+
+ // Set pixel shader texture transforms
+ void SetPixelShaderTextureTranslation( int pixelReg, int translationVar );
+ void SetPixelShaderTextureScale( int pixelReg, int scaleVar );
+ void SetPixelShaderTextureTransform( int pixelReg, int transformVar );
+ void SetPixelShaderTextureScaledTransform( int pixelReg,
+ int transformVar, int scaleVar );
+
+ // Moves a matrix into vertex shader constants
+ void SetVertexShaderMatrix3x4( int vertexReg, int matrixVar );
+ void SetVertexShaderMatrix4x4( int vertexReg, int matrixVar );
+
+ // Loads the view matrix into vertex shader constants
+ void LoadViewMatrixIntoVertexShaderConstant( int vertexReg );
+
+ // Loads the projection matrix into vertex shader constants
+ void LoadProjectionMatrixIntoVertexShaderConstant( int vertexReg );
+
+ // Loads the model->view matrix into vertex shader constants
+ void LoadModelViewMatrixIntoVertexShaderConstant( int vertexReg );
+
+ // Loads a scale/offset version of the viewport transform into the specified constant.
+ void LoadViewportTransformScaledIntoVertexShaderConstant( int vertexReg );
+
+ // Sets up ambient light cube...
+ void SetAmbientCubeDynamicStateVertexShader( );
+ float GetAmbientLightCubeLuminance( );
+
+ // Helpers for dealing with envmaptint
+ void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear = false );
+
+ // Helper methods for pixel shader overbrighting
+ void EnablePixelShaderOverbright( int reg, bool bEnable, bool bDivideByTwo );
+
+ // Helper for dealing with modulation
+ void SetModulationVertexShaderDynamicState();
+ void SetModulationPixelShaderDynamicState( int modulationVar );
+ void SetModulationPixelShaderDynamicState_LinearColorSpace( int modulationVar );
+ void SetModulationPixelShaderDynamicState_LinearColorSpace_LinearScale( int modulationVar, float flScale );
+
+ // Sets a color + alpha into shader constants
+ void SetColorVertexShaderConstant( int nVertexReg, int colorVar, int alphaVar );
+ void SetColorPixelShaderConstant( int nPixelReg, int colorVar, int alphaVar );
+
+
+#ifndef GAME_SHADER_DLL
+ //
+ // Standard shader passes!
+ //
+
+ void InitParamsUnlitGeneric_DX8(
+ int baseTextureVar,
+ int detailScaleVar,
+ int envmapOptionalVar,
+ int envmapVar,
+ int envmapTintVar,
+ int envmapMaskScaleVar,
+ int nDetailBlendMode );
+
+ void InitUnlitGeneric_DX8(
+ int baseTextureVar,
+ int detailVar,
+ int envmapVar,
+ int envmapMaskVar );
+
+ // Dx8 Unlit Generic pass
+ void VertexShaderUnlitGenericPass( int baseTextureVar, int frameVar,
+ int baseTextureTransformVar,
+ int detailVar, int detailTransform, bool bDetailTransformIsScale,
+ int envmapVar, int envMapFrameVar, int envmapMaskVar,
+ int envmapMaskFrameVar, int envmapMaskScaleVar, int envmapTintVar,
+ int alphaTestReferenceVar,
+ int nDetailBlendModeVar,
+ int nOutlineVar,
+ int nOutlineColorVar,
+ int nOutlineStartVar,
+ int nOutlineEndVar,
+ int nSeparateDetailUVsVar
+ );
+
+ // Helpers for drawing world bump mapped stuff.
+ void DrawModelBumpedSpecularLighting( int bumpMapVar, int bumpMapFrameVar,
+ int envMapVar, int envMapVarFrame,
+ int envMapTintVar, int alphaVar,
+ int envMapContrastVar, int envMapSaturationVar,
+ int bumpTransformVar,
+ bool bBlendSpecular, bool bNoWriteZ = false );
+ void DrawWorldBumpedSpecularLighting( int bumpmapVar, int envmapVar,
+ int bumpFrameVar, int envmapFrameVar,
+ int envmapTintVar, int alphaVar,
+ int envmapContrastVar, int envmapSaturationVar,
+ int bumpTransformVar, int fresnelReflectionVar,
+ bool bBlend, bool bNoWriteZ = false );
+
+ const char *UnlitGeneric_ComputeVertexShaderName( bool bMask,
+ bool bEnvmap,
+ bool bBaseTexture,
+ bool bBaseAlphaEnvmapMask,
+ bool bDetail,
+ bool bVertexColor,
+ bool bEnvmapCameraSpace,
+ bool bEnvmapSphere );
+
+ const char *UnlitGeneric_ComputePixelShaderName( bool bMask,
+ bool bEnvmap,
+ bool bBaseTexture,
+ bool bBaseAlphaEnvmapMask,
+ bool bDetail,
+ bool bMultiplyDetail,
+ bool bMaskBaseByDetailAlpha );
+
+ void DrawWorldBaseTexture( int baseTextureVar, int baseTextureTransformVar, int frameVar, int colorVar, int alphaVar );
+ void DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar, bool bMultiply, bool bSSBump );
+ void DrawWorldBumpedSpecularLighting( int envmapMaskVar, int envmapMaskFrame,
+ int bumpmapVar, int envmapVar,
+ int bumpFrameVar, int envmapFrameVar,
+ int envmapTintVar, int alphaVar,
+ int envmapContrastVar, int envmapSaturationVar,
+ int bumpTransformVar, int fresnelReflectionVar,
+ bool bBlend );
+ void DrawBaseTextureBlend( int baseTextureVar, int baseTextureTransformVar,
+ int baseTextureFrameVar,
+ int baseTexture2Var, int baseTextureTransform2Var,
+ int baseTextureFrame2Var, int colorVar, int alphaVar );
+ void DrawWorldBumpedDiffuseLighting_Base_ps14( int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar, int baseTextureVar, int baseTextureTransformVar, int frameVar );
+ void DrawWorldBumpedDiffuseLighting_Blend_ps14( int bumpmapVar, int bumpFrameVar, int bumpTransformVar,
+ int baseTextureVar, int baseTextureTransformVar, int baseTextureFrameVar,
+ int baseTexture2Var, int baseTextureTransform2Var, int baseTextureFrame2Var);
+ void DrawWorldBumpedUsingVertexShader( int baseTextureVar, int baseTextureTransformVar,
+ int bumpmapVar, int bumpFrameVar,
+ int bumpTransformVar,
+ int envmapMaskVar, int envmapMaskFrame,
+ int envmapVar,
+ int envmapFrameVar,
+ int envmapTintVar, int colorVar, int alphaVar,
+ int envmapContrastVar, int envmapSaturationVar, int frameVar, int fresnelReflectionVar,
+ bool doBaseTexture2,
+ int baseTexture2Var,
+ int baseTextureTransform2Var,
+ int baseTextureFrame2Var,
+ bool bSSBump
+ );
+
+ // Sets up hw morphing state for the vertex shader
+ void SetHWMorphVertexShaderState( int nDimConst, int nSubrectConst, VertexTextureSampler_t morphSampler );
+
+ // Computes the shader index for vertex lit materials
+ int ComputeVertexLitShaderIndex( bool bVertexLitGeneric, bool hasBump, bool hasEnvmap, bool hasVertexColor, bool bHasNormal ) const;
+
+ // Helper for setting up flashlight constants
+ void SetFlashlightVertexShaderConstants( bool bBump, int bumpTransformVar, bool bDetail, int detailScaleVar, bool bSetTextureTransforms );
+
+#if SUPPORT_DX8
+ void DrawFlashlight_dx80( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
+ bool bBump, int bumpmapVar, int bumpmapFrame, int bumpTransform, int flashlightTextureVar,
+ int flashlightTextureFrameVar, bool bLightmappedGeneric, bool bWorldVertexTransition,
+ int nWorldVertexTransitionPassID, int baseTexture2Var, int baseTexture2FrameVar,
+ bool bTeeth=false, int nTeethForwardVar=0, int nTeethIllumFactorVar=0 );
+#endif
+
+ struct DrawFlashlight_dx90_Vars_t
+ {
+ DrawFlashlight_dx90_Vars_t()
+ {
+ // set all ints to -1
+ memset( this, 0xFF, sizeof(DrawFlashlight_dx90_Vars_t) );
+ // set all bools to a default value.
+ m_bBump = false;
+ m_bLightmappedGeneric = false;
+ m_bWorldVertexTransition = false;
+ m_bTeeth = false;
+ m_bSSBump = false;
+ m_fSeamlessScale = 0.0;
+ }
+ bool m_bBump;
+ bool m_bLightmappedGeneric;
+ bool m_bWorldVertexTransition;
+ bool m_bTeeth;
+ int m_nBumpmapVar;
+ int m_nBumpmapFrame;
+ int m_nBumpTransform;
+ int m_nFlashlightTextureVar;
+ int m_nFlashlightTextureFrameVar;
+ int m_nBaseTexture2Var;
+ int m_nBaseTexture2FrameVar;
+ int m_nBumpmap2Var;
+ int m_nBumpmap2Frame;
+ int m_nBump2Transform;
+ int m_nDetailVar;
+ int m_nDetailScale;
+ int m_nDetailTextureCombineMode;
+ int m_nDetailTextureBlendFactor;
+ int m_nDetailTint;
+ int m_nTeethForwardVar;
+ int m_nTeethIllumFactorVar;
+ int m_nAlphaTestReference;
+ bool m_bSSBump;
+ float m_fSeamlessScale; // 0.0 = not seamless
+ };
+ void DrawFlashlight_dx90( IMaterialVar** params,
+ IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, DrawFlashlight_dx90_Vars_t &vars );
+#endif // GAME_SHADER_DLL
+
+ BlendType_t EvaluateBlendRequirements( int textureVar, bool isBaseTexture, int detailTextureVar = -1 );
+
+ void HashShadow2DJitter( const float fJitterSeed, float *fU, float* fV );
+
+ //Alpha tested materials can end up leaving garbage in the dest alpha buffer if they write depth.
+ //This pass fills in the areas that passed the alpha test with depth in dest alpha
+ //by writing only equal depth pixels and only if we should be writing depth to dest alpha
+ void DrawEqualDepthToDestAlpha( void );
+
+private:
+ // Helper methods for VertexLitGenericPass
+// void UnlitGenericShadowState( int baseTextureVar, int detailVar, int envmapVar, int envmapMaskVar, bool doSkin );
+ void UnlitGenericDynamicState( int baseTextureVar, int frameVar, int baseTextureTransformVar,
+ int detailVar, int detailTransform, bool bDetailTransformIsScale, int envmapVar,
+ int envMapFrameVar, int envmapMaskVar, int envmapMaskFrameVar,
+ int envmapMaskScaleVar, int envmapTintVar );
+
+ // Converts a color + alpha into a vector4
+ void ColorVarsToVector( int colorVar, int alphaVar, Vector4D &color );
+
+};
+
+FORCEINLINE void SetFlashLightColorFromState( FlashlightState_t const &state, IShaderDynamicAPI *pShaderAPI, int nPSRegister=28, bool bFlashlightNoLambert=false )
+{
+ // Old code
+ //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x;
+ //float flFlashlightScale = 1.0f / flToneMapScale;
+
+ // Fix to old code to keep flashlight from ever getting brighter than 1.0
+ //float flToneMapScale = ( pShaderAPI->GetToneMappingScaleLinear() ).x;
+ //if ( flToneMapScale < 1.0f )
+ // flToneMapScale = 1.0f;
+ //float flFlashlightScale = 1.0f / flToneMapScale;
+
+ // Force flashlight to 25% bright always
+ float flFlashlightScale = 0.25f;
+
+ if ( !g_pHardwareConfig->GetHDREnabled() )
+ {
+ // Non-HDR path requires 2.0 flashlight
+ flFlashlightScale = 2.0f;
+ }
+
+ // DX10 requires some hackery due to sRGB/blend ordering change from DX9
+ if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
+ {
+ flFlashlightScale *= 2.5f; // Magic number that works well on the NVIDIA 8800
+ }
+
+ // Generate pixel shader constant
+ float const *pFlashlightColor = state.m_Color;
+ float vPsConst[4] = { flFlashlightScale * pFlashlightColor[0], flFlashlightScale * pFlashlightColor[1], flFlashlightScale * pFlashlightColor[2], pFlashlightColor[3] };
+ vPsConst[3] = bFlashlightNoLambert ? 2.0f : 0.0f; // This will be added to N.L before saturate to force a 1.0 N.L term
+
+ // Red flashlight for testing
+ //vPsConst[0] = 0.5f; vPsConst[1] = 0.0f; vPsConst[2] = 0.0f;
+
+ pShaderAPI->SetPixelShaderConstant( nPSRegister, ( float * )vPsConst );
+}
+
+FORCEINLINE float ShadowAttenFromState( FlashlightState_t const &state )
+{
+ // DX10 requires some hackery due to sRGB/blend ordering change from DX9, which makes the shadows too light
+ if ( g_pHardwareConfig->UsesSRGBCorrectBlending() )
+ return state.m_flShadowAtten * 0.1f; // magic number
+
+ return state.m_flShadowAtten;
+}
+
+FORCEINLINE float ShadowFilterFromState( FlashlightState_t const &state )
+{
+ // We developed shadow maps at 1024, so we expect the penumbra size to have been tuned relative to that
+ return state.m_flShadowFilterSize / 1024.0f;
+}
+
+
+// convenient material variable access functions for helpers to use.
+FORCEINLINE bool IsTextureSet( int nVar, IMaterialVar **params )
+{
+ return ( nVar != -1 ) && ( params[nVar]->IsTexture() );
+}
+
+FORCEINLINE bool IsBoolSet( int nVar, IMaterialVar **params )
+{
+ return ( nVar != -1 ) && ( params[nVar]->GetIntValue() );
+}
+
+FORCEINLINE int GetIntParam( int nVar, IMaterialVar **params, int nDefaultValue = 0 )
+{
+ return ( nVar != -1 ) ? ( params[nVar]->GetIntValue() ) : nDefaultValue;
+}
+
+FORCEINLINE float GetFloatParam( int nVar, IMaterialVar **params, float flDefaultValue = 0.0 )
+{
+ return ( nVar != -1 ) ? ( params[nVar]->GetFloatValue() ) : flDefaultValue;
+}
+
+FORCEINLINE void InitFloatParam( int nIndex, IMaterialVar **params, float flValue )
+{
+ if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
+ {
+ params[nIndex]->SetFloatValue( flValue );
+ }
+}
+
+FORCEINLINE void InitIntParam( int nIndex, IMaterialVar **params, int nValue )
+{
+ if ( (nIndex != -1) && !params[nIndex]->IsDefined() )
+ {
+ params[nIndex]->SetIntValue( nValue );
+ }
+}
+
+
+class ConVar;
+
+#ifdef _DEBUG
+extern ConVar mat_envmaptintoverride;
+extern ConVar mat_envmaptintscale;
+#endif
+
+
+#endif // BASEVSSHADER_H
diff --git a/mp/src/materialsystem/stdshaders/buildhl2mpshaders.bat b/mp/src/materialsystem/stdshaders/buildhl2mpshaders.bat new file mode 100644 index 00000000..58b0cd26 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/buildhl2mpshaders.bat @@ -0,0 +1,21 @@ +@echo off
+setlocal
+
+rem ================================
+rem ==== MOD PATH CONFIGURATIONS ===
+
+rem == Set the absolute path to your mod's game directory here ==
+set GAMEDIR=%cd%\..\..\..\game\mod_hl2mp
+
+rem == Set the relative or absolute path to Source SDK Base 2013 Singleplayer\bin ==
+set SDKBINDIR=C:\SteamBetaLibrary\SteamApps\common\Source SDK Base 2013 Singleplayer\bin
+
+rem == Set the Path to your mod's root source code ==
+rem This should already be correct, accepts relative paths only!
+set SOURCEDIR=..\..
+
+rem ==== MOD PATH CONFIGURATIONS END ===
+rem ====================================
+
+
+call buildsdkshaders.bat
diff --git a/mp/src/materialsystem/stdshaders/buildsdkshaders.bat b/mp/src/materialsystem/stdshaders/buildsdkshaders.bat new file mode 100644 index 00000000..eeaa5b8c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/buildsdkshaders.bat @@ -0,0 +1,40 @@ +@echo off
+setlocal
+
+rem Use dynamic shaders to build .inc files only
+rem set dynamic_shaders=1
+rem == Setup path to nmake.exe, from vc 2005 common tools directory ==
+call "%VS100COMNTOOLS%vsvars32.bat"
+
+
+set TTEXE=..\..\devtools\bin\timeprecise.exe
+if not exist %TTEXE% goto no_ttexe
+goto no_ttexe_end
+
+:no_ttexe
+set TTEXE=time /t
+:no_ttexe_end
+
+
+rem echo.
+rem echo ~~~~~~ buildsdkshaders %* ~~~~~~
+%TTEXE% -cur-Q
+set tt_all_start=%ERRORLEVEL%
+set tt_all_chkpt=%tt_start%
+
+set BUILD_SHADER=call buildshaders.bat
+set ARG_EXTRA=
+
+%BUILD_SHADER% stdshader_dx9_20b -game %GAMEDIR% -source %SOURCEDIR%
+%BUILD_SHADER% stdshader_dx9_30 -game %GAMEDIR% -source %SOURCEDIR% -dx9_30 -force30
+
+
+rem echo.
+if not "%dynamic_shaders%" == "1" (
+ rem echo Finished full buildallshaders %*
+) else (
+ rem echo Finished dynamic buildallshaders %*
+)
+
+rem %TTEXE% -diff %tt_all_start% -cur
+rem echo.
diff --git a/mp/src/materialsystem/stdshaders/buildshaders.bat b/mp/src/materialsystem/stdshaders/buildshaders.bat new file mode 100644 index 00000000..64859912 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/buildshaders.bat @@ -0,0 +1,209 @@ +@echo off
+
+set TTEXE=..\..\devtools\bin\timeprecise.exe
+if not exist %TTEXE% goto no_ttexe
+goto no_ttexe_end
+
+:no_ttexe
+set TTEXE=time /t
+:no_ttexe_end
+
+echo.
+echo ==================== buildshaders %* ==================
+%TTEXE% -cur-Q
+set tt_start=%ERRORLEVEL%
+set tt_chkpt=%tt_start%
+
+
+REM ****************
+REM usage: buildshaders <shaderProjectName>
+REM ****************
+
+setlocal
+set arg_filename=%1
+set shadercompilecommand=shadercompile.exe
+set targetdir=shaders
+set SrcDirBase=..\..
+set shaderDir=shaders
+set SDKArgs=
+set SHADERINCPATH=vshtmp9/... fxctmp9/...
+
+
+if "%1" == "" goto usage
+set inputbase=%1
+
+set DIRECTX_SDK_VER=pc09.00
+set DIRECTX_SDK_BIN_DIR=dx9sdk\utilities
+
+if /i "%6" == "-dx9_30" goto dx_sdk_dx9_30
+goto dx_sdk_end
+:dx_sdk_dx9_30
+ set DIRECTX_SDK_VER=pc09.30
+ set DIRECTX_SDK_BIN_DIR=dx10sdk\utilities\dx9_30
+ goto dx_sdk_end
+:dx_sdk_end
+
+if /i "%7" == "-force30" goto set_force30_arg
+goto set_force_end
+:set_force30_arg
+ set DIRECTX_FORCE_MODEL=30
+ goto set_force_end
+:set_force_end
+
+if /i "%2" == "-game" goto set_mod_args
+goto build_shaders
+
+REM ****************
+REM USAGE
+REM ****************
+:usage
+echo.
+echo "usage: buildshaders <shaderProjectName> [-game] [gameDir if -game was specified] [-source sourceDir]"
+echo " gameDir is where gameinfo.txt is (where it will store the compiled shaders)."
+echo " sourceDir is where the source code is (where it will find scripts and compilers)."
+echo "ex : buildshaders myshaders"
+echo "ex : buildshaders myshaders -game c:\steam\steamapps\sourcemods\mymod -source c:\mymod\src"
+goto :end
+
+REM ****************
+REM MOD ARGS - look for -game or the vproject environment variable
+REM ****************
+:set_mod_args
+
+if not exist "%SDKBINDIR%\shadercompile.exe" goto NoShaderCompile
+set ChangeToDir=%SDKBINDIR%
+
+if /i "%4" NEQ "-source" goto NoSourceDirSpecified
+set SrcDirBase=%~5
+
+REM ** use the -game parameter to tell us where to put the files
+set targetdir=%~3\shaders
+set SDKArgs=-nompi -nop4 -game "%~3"
+
+if not exist "%~3\gameinfo.txt" goto InvalidGameDirectory
+goto build_shaders
+
+REM ****************
+REM ERRORS
+REM ****************
+:InvalidGameDirectory
+echo -
+echo Error: "%~3" is not a valid game directory.
+echo (The -game directory must have a gameinfo.txt file)
+echo -
+goto end
+
+:NoSourceDirSpecified
+echo ERROR: If you specify -game on the command line, you must specify -source.
+goto usage
+goto end
+
+:NoShaderCompile
+echo -
+echo - ERROR: shadercompile.exe doesn't exist in %SDKBINDIR%
+echo -
+goto end
+
+REM ****************
+REM BUILD SHADERS
+REM ****************
+:build_shaders
+
+rem echo --------------------------------
+rem echo %inputbase%
+rem echo --------------------------------
+REM make sure that target dirs exist
+REM files will be built in these targets and copied to their final destination
+if not exist %shaderDir% mkdir %shaderDir%
+if not exist %shaderDir%\fxc mkdir %shaderDir%\fxc
+if not exist %shaderDir%\vsh mkdir %shaderDir%\vsh
+if not exist %shaderDir%\psh mkdir %shaderDir%\psh
+REM Nuke some files that we will add to later.
+if exist filelist.txt del /f /q filelist.txt
+if exist filestocopy.txt del /f /q filestocopy.txt
+if exist filelistgen.txt del /f /q filelistgen.txt
+if exist inclist.txt del /f /q inclist.txt
+if exist vcslist.txt del /f /q vcslist.txt
+
+REM ****************
+REM Generate a makefile for the shader project
+REM ****************
+perl "%SrcDirBase%\devtools\bin\updateshaders.pl" -source "%SrcDirBase%" %inputbase%
+
+
+REM ****************
+REM Run the makefile, generating minimal work/build list for fxc files, go ahead and compile vsh and psh files.
+REM ****************
+rem nmake /S /C -f makefile.%inputbase% clean > clean.txt 2>&1
+echo Building inc files, asm vcs files, and VMPI worklist for %inputbase%...
+nmake /S /C -f makefile.%inputbase%
+
+REM ****************
+REM Copy the inc files to their target
+REM ****************
+if exist "inclist.txt" (
+ echo Publishing shader inc files to target...
+ perl %SrcDirBase%\devtools\bin\copyshaderincfiles.pl inclist.txt
+)
+
+REM ****************
+REM Add the executables to the worklist.
+REM ****************
+if /i "%DIRECTX_SDK_VER%" == "pc09.00" (
+ rem echo "Copy extra files for dx 9 std
+)
+if /i "%DIRECTX_SDK_VER%" == "pc09.30" (
+ echo %SrcDirBase%\devtools\bin\d3dx9_33.dll >> filestocopy.txt
+)
+
+echo %SrcDirBase%\%DIRECTX_SDK_BIN_DIR%\dx_proxy.dll >> filestocopy.txt
+
+echo %SDKBINDIR%\shadercompile.exe >> filestocopy.txt
+echo %SDKBINDIR%\shadercompile_dll.dll >> filestocopy.txt
+echo %SDKBINDIR%\vstdlib.dll >> filestocopy.txt
+echo %SDKBINDIR%\tier0.dll >> filestocopy.txt
+
+REM ****************
+REM Cull duplicate entries in work/build list
+REM ****************
+if exist filestocopy.txt type filestocopy.txt | perl "%SrcDirBase%\devtools\bin\uniqifylist.pl" > uniquefilestocopy.txt
+if exist filelistgen.txt if not "%dynamic_shaders%" == "1" (
+ echo Generating action list...
+ copy filelistgen.txt filelist.txt >nul
+)
+
+REM ****************
+REM Execute distributed process on work/build list
+REM ****************
+
+set shader_path_cd=%cd%
+if exist "filelist.txt" if exist "uniquefilestocopy.txt" if not "%dynamic_shaders%" == "1" (
+ echo Running distributed shader compilation...
+
+ cd /D %ChangeToDir%
+ echo %shadercompilecommand% %SDKArgs% -shaderpath "%shader_path_cd:/=\%" -allowdebug
+ %shadercompilecommand% %SDKArgs% -shaderpath "%shader_path_cd:/=\%" -allowdebug
+ cd /D %shader_path_cd%
+)
+
+REM ****************
+REM PC Shader copy
+REM Publish the generated files to the output dir using XCOPY
+REM This batch file may have been invoked standalone or slaved (master does final smart mirror copy)
+REM ****************
+:DoXCopy
+if not "%dynamic_shaders%" == "1" (
+if not exist "%targetdir%" md "%targetdir%"
+if not "%targetdir%"=="%shaderDir%" xcopy %shaderDir%\*.* "%targetdir%" /e /y
+)
+goto end
+
+REM ****************
+REM END
+REM ****************
+:end
+
+
+%TTEXE% -diff %tt_start%
+echo.
+
diff --git a/mp/src/materialsystem/stdshaders/clean.bat b/mp/src/materialsystem/stdshaders/clean.bat new file mode 100644 index 00000000..eec63804 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/clean.bat @@ -0,0 +1,33 @@ +@echo off
+setlocal
+
+if /i "%1" == "-game" goto CleanGameDir
+
+rem Clean out hl2
+if exist ..\..\..\game\hl2\shaders rd /s /q ..\..\..\game\hl2\shaders
+goto CleanOtherStuff
+
+:CleanGameDir
+set __GameDir=%~2
+if not exist "%__GameDir%\gameinfo.txt" goto MissingGameInfo
+if exist "%__GameDir%\shaders" rd /s /q "%2\shaders"
+goto CleanOtherStuff
+
+:CleanOtherStuff
+if exist debug_dx9 rd /s /q debug_dx9
+
+if exist fxctmp9 rd /s /q fxctmp9
+if exist vshtmp9 rd /s /q vshtmp9
+if exist pshtmp9 rd /s /q pshtmp9
+if exist fxctmp9_tmp rd /s /q fxctmp9_tmp
+if exist vshtmp9_tmp rd /s /q vshtmp9_tmp
+if exist pshtmp9_tmp rd /s /q pshtmp9_tmp
+if exist shaders rd /s /q shaders
+goto end
+
+:MissingGameInfo
+echo Invalid -game parameter specified (no "%__GameDir%\gameinfo.txt" exists).
+goto end
+
+
+:end
\ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/cleantemps.bat b/mp/src/materialsystem/stdshaders/cleantemps.bat new file mode 100644 index 00000000..51478ee4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cleantemps.bat @@ -0,0 +1,12 @@ +@echo off
+setlocal
+
+if exist fxctmp9_tmp rd /s /q fxctmp9_tmp
+if exist vshtmp9_tmp rd /s /q vshtmp9_tmp
+if exist pshtmp9_tmp rd /s /q pshtmp9_tmp
+
+if exist fxctmp9_360_tmp rd /s /q fxctmp9_360_tmp
+if exist vshtmp9_360_tmp rd /s /q vshtmp9_360_tmp
+if exist pshtmp9_360_tmp rd /s /q pshtmp9_360_tmp
+
+if exist shaders rd /s /q shaders
diff --git a/mp/src/materialsystem/stdshaders/commandbuilder.h b/mp/src/materialsystem/stdshaders/commandbuilder.h new file mode 100644 index 00000000..13a68ede --- /dev/null +++ b/mp/src/materialsystem/stdshaders/commandbuilder.h @@ -0,0 +1,407 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+// Utility class for building command buffers into memory
+//===========================================================================//
+
+#ifndef COMMANDBUILDER_H
+#define COMMANDBUILDER_H
+
+#ifndef COMMANDBUFFER_H
+#include "shaderapi/commandbuffer.h"
+#endif
+
+#include "BaseVSShader.h"
+#include "shaderapi/ishaderapi.h"
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+extern ConVar my_mat_fullbright;
+
+template<int N> class CFixedCommandStorageBuffer
+{
+public:
+ uint8 m_Data[N];
+
+ uint8 *m_pDataOut;
+#ifdef DBGFLAG_ASSERT
+ size_t m_nNumBytesRemaining;
+#endif
+
+ FORCEINLINE CFixedCommandStorageBuffer( void )
+ {
+ m_pDataOut = m_Data;
+#ifdef DBGFLAG_ASSERT
+ m_nNumBytesRemaining = N;
+#endif
+
+ }
+
+ FORCEINLINE void EnsureCapacity( size_t sz )
+ {
+ Assert( m_nNumBytesRemaining >= sz );
+ }
+
+ template<class T> FORCEINLINE void Put( T const &nValue )
+ {
+ EnsureCapacity( sizeof( T ) );
+ *( reinterpret_cast<T *>( m_pDataOut ) ) = nValue;
+ m_pDataOut += sizeof( nValue );
+#ifdef DBGFLAG_ASSERT
+ m_nNumBytesRemaining -= sizeof( nValue );
+#endif
+ }
+
+ FORCEINLINE void PutInt( int nValue )
+ {
+ Put( nValue );
+ }
+
+ FORCEINLINE void PutFloat( float nValue )
+ {
+ Put( nValue );
+ }
+
+ FORCEINLINE void PutPtr( void * pPtr )
+ {
+ Put( pPtr );
+ }
+
+ FORCEINLINE void PutMemory( const void *pMemory, size_t nBytes )
+ {
+ EnsureCapacity( nBytes );
+ memcpy( m_pDataOut, pMemory, nBytes );
+ m_pDataOut += nBytes;
+ }
+
+ FORCEINLINE uint8 *Base( void )
+ {
+ return m_Data;
+ }
+
+ FORCEINLINE void Reset( void )
+ {
+ m_pDataOut = m_Data;
+#ifdef DBGFLAG_ASSERT
+ m_nNumBytesRemaining = N;
+#endif
+ }
+
+ FORCEINLINE size_t Size( void ) const
+ {
+ return m_pDataOut - m_Data;
+ }
+
+};
+
+template<class S> class CCommandBufferBuilder
+{
+public:
+ S m_Storage;
+
+ FORCEINLINE void End( void )
+ {
+ m_Storage.PutInt( CBCMD_END );
+ }
+
+
+ FORCEINLINE IMaterialVar *Param( int nVar ) const
+ {
+ return CBaseShader::s_ppParams[nVar];
+ }
+
+ FORCEINLINE void SetPixelShaderConstants( int nFirstConstant, int nConstants )
+ {
+ m_Storage.PutInt( CBCMD_SET_PIXEL_SHADER_FLOAT_CONST );
+ m_Storage.PutInt( nFirstConstant );
+ m_Storage.PutInt( nConstants );
+ }
+
+ FORCEINLINE void OutputConstantData( float const *pSrcData )
+ {
+ m_Storage.PutFloat( pSrcData[0] );
+ m_Storage.PutFloat( pSrcData[1] );
+ m_Storage.PutFloat( pSrcData[2] );
+ m_Storage.PutFloat( pSrcData[3] );
+ }
+
+ FORCEINLINE void OutputConstantData4( float flVal0, float flVal1, float flVal2, float flVal3 )
+ {
+ m_Storage.PutFloat( flVal0 );
+ m_Storage.PutFloat( flVal1 );
+ m_Storage.PutFloat( flVal2 );
+ m_Storage.PutFloat( flVal3 );
+ }
+
+ FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData, int nNumConstantsToSet )
+ {
+ SetPixelShaderConstants( nFirstConstant, nNumConstantsToSet );
+ m_Storage.PutMemory( pSrcData, 4 * sizeof( float ) * nNumConstantsToSet );
+ }
+
+ FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, int nVar )
+ {
+ SetPixelShaderConstant( nFirstConstant, Param( nVar )->GetVecValue() );
+ }
+
+ void SetPixelShaderConstantGammaToLinear( int pixelReg, int constantVar )
+ {
+ float val[4];
+ Param(constantVar)->GetVecValue( val, 3 );
+ val[0] = val[0] > 1.0f ? val[0] : GammaToLinear( val[0] );
+ val[1] = val[1] > 1.0f ? val[1] : GammaToLinear( val[1] );
+ val[2] = val[2] > 1.0f ? val[2] : GammaToLinear( val[2] );
+ val[3] = 1.0;
+ SetPixelShaderConstant( pixelReg, val );
+ }
+
+ FORCEINLINE void SetPixelShaderConstant( int nFirstConstant, float const *pSrcData )
+ {
+ SetPixelShaderConstants( nFirstConstant, 1 );
+ OutputConstantData( pSrcData );
+ }
+
+ FORCEINLINE void SetPixelShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 )
+ {
+ SetPixelShaderConstants( nFirstConstant, 1 );
+ OutputConstantData4( flVal0, flVal1, flVal2, flVal3 );
+ }
+
+ FORCEINLINE void SetPixelShaderConstant_W( int pixelReg, int constantVar, float fWValue )
+ {
+ if ( constantVar != -1 )
+ {
+ float val[3];
+ Param(constantVar)->GetVecValue( val, 3);
+ SetPixelShaderConstant4( pixelReg, val[0], val[1], val[2], fWValue );
+ }
+ }
+
+ FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData )
+ {
+ m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST );
+ m_Storage.PutInt( nFirstConstant );
+ m_Storage.PutInt( 1 );
+ OutputConstantData( pSrcData );
+ }
+
+ FORCEINLINE void SetVertexShaderConstant( int nFirstConstant, float const *pSrcData, int nConsts )
+ {
+ m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST );
+ m_Storage.PutInt( nFirstConstant );
+ m_Storage.PutInt( nConsts );
+ m_Storage.PutMemory( pSrcData, 4 * nConsts * sizeof( float ) );
+ }
+
+
+ FORCEINLINE void SetVertexShaderConstant4( int nFirstConstant, float flVal0, float flVal1, float flVal2, float flVal3 )
+ {
+ m_Storage.PutInt( CBCMD_SET_VERTEX_SHADER_FLOAT_CONST );
+ m_Storage.PutInt( nFirstConstant );
+ m_Storage.PutInt( 1 );
+ m_Storage.PutFloat( flVal0 );
+ m_Storage.PutFloat( flVal1 );
+ m_Storage.PutFloat( flVal2 );
+ m_Storage.PutFloat( flVal3 );
+ }
+
+ void SetVertexShaderTextureTransform( int vertexReg, int transformVar )
+ {
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = Param( transformVar );
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+ SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
+ }
+
+
+ void SetVertexShaderTextureScaledTransform( int vertexReg, int transformVar, int scaleVar )
+ {
+ Vector4D transformation[2];
+ IMaterialVar* pTransformationVar = Param( transformVar );
+ if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX))
+ {
+ const VMatrix &mat = pTransformationVar->GetMatrixValue();
+ transformation[0].Init( mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
+ transformation[1].Init( mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
+ }
+ else
+ {
+ transformation[0].Init( 1.0f, 0.0f, 0.0f, 0.0f );
+ transformation[1].Init( 0.0f, 1.0f, 0.0f, 0.0f );
+ }
+
+ Vector2D scale( 1, 1 );
+ IMaterialVar* pScaleVar = Param( scaleVar );
+ if (pScaleVar)
+ {
+ if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR)
+ pScaleVar->GetVecValue( scale.Base(), 2 );
+ else if (pScaleVar->IsDefined())
+ scale[0] = scale[1] = pScaleVar->GetFloatValue();
+ }
+
+ // Apply the scaling
+ transformation[0][0] *= scale[0];
+ transformation[0][1] *= scale[1];
+ transformation[1][0] *= scale[0];
+ transformation[1][1] *= scale[1];
+ transformation[0][3] *= scale[0];
+ transformation[1][3] *= scale[1];
+ SetVertexShaderConstant( vertexReg, transformation[0].Base(), 2 );
+ }
+
+ FORCEINLINE void SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar )
+ {
+ if( g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 )
+ {
+ SetPixelShaderConstant( pixelReg, Param( tintVar)->GetVecValue() );
+ }
+ else
+ {
+ SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, 0.0 );
+ }
+ }
+
+ FORCEINLINE void SetEnvMapTintPixelShaderDynamicStateGammaToLinear( int pixelReg, int tintVar, float flAlphaValue = 1.0 )
+ {
+ if( ( tintVar != -1 ) && g_pConfig->bShowSpecular && my_mat_fullbright.GetInt() != 2 )
+ {
+ float color[4];
+ color[3] = flAlphaValue;
+ Param( tintVar)->GetLinearVecValue( color, 3 );
+ SetPixelShaderConstant( pixelReg, color );
+ }
+ else
+ {
+ SetPixelShaderConstant4( pixelReg, 0.0, 0.0, 0.0, flAlphaValue );
+ }
+ }
+
+ FORCEINLINE void StoreEyePosInPixelShaderConstant( int nConst )
+ {
+ m_Storage.PutInt( CBCMD_STORE_EYE_POS_IN_PSCONST );
+ m_Storage.PutInt( nConst );
+ }
+
+ FORCEINLINE void CommitPixelShaderLighting( int nConst )
+ {
+ m_Storage.PutInt( CBCMD_COMMITPIXELSHADERLIGHTING );
+ m_Storage.PutInt( nConst );
+ }
+
+ FORCEINLINE void SetPixelShaderStateAmbientLightCube( int nConst )
+ {
+ m_Storage.PutInt( CBCMD_SETPIXELSHADERSTATEAMBIENTLIGHTCUBE );
+ m_Storage.PutInt( nConst );
+ }
+
+ FORCEINLINE void SetAmbientCubeDynamicStateVertexShader( void )
+ {
+ m_Storage.PutInt( CBCMD_SETAMBIENTCUBEDYNAMICSTATEVERTEXSHADER );
+ }
+
+ FORCEINLINE void SetPixelShaderFogParams( int nReg )
+ {
+ m_Storage.PutInt( CBCMD_SETPIXELSHADERFOGPARAMS );
+ m_Storage.PutInt( nReg );
+ }
+
+ FORCEINLINE void BindStandardTexture( Sampler_t nSampler, StandardTextureId_t nTextureId )
+ {
+ m_Storage.PutInt( CBCMD_BIND_STANDARD_TEXTURE );
+ m_Storage.PutInt( nSampler );
+ m_Storage.PutInt( nTextureId );
+ }
+
+
+ FORCEINLINE void BindTexture( Sampler_t nSampler, ShaderAPITextureHandle_t hTexture )
+ {
+ Assert( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE );
+ if ( hTexture != INVALID_SHADERAPI_TEXTURE_HANDLE )
+ {
+ m_Storage.PutInt( CBCMD_BIND_SHADERAPI_TEXTURE_HANDLE );
+ m_Storage.PutInt( nSampler );
+ m_Storage.PutInt( hTexture );
+ }
+ }
+
+ FORCEINLINE void BindTexture( CBaseVSShader *pShader, Sampler_t nSampler, int nTextureVar, int nFrameVar )
+ {
+ ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar );
+ BindTexture( nSampler, hTexture );
+ }
+
+ FORCEINLINE void BindMultiTexture( CBaseVSShader *pShader, Sampler_t nSampler1, Sampler_t nSampler2, int nTextureVar, int nFrameVar )
+ {
+ ShaderAPITextureHandle_t hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 0 );
+ BindTexture( nSampler1, hTexture );
+ hTexture = pShader->GetShaderAPITextureBindHandle( nTextureVar, nFrameVar, 1 );
+ BindTexture( nSampler2, hTexture );
+ }
+
+ FORCEINLINE void SetPixelShaderIndex( int nIndex )
+ {
+ m_Storage.PutInt( CBCMD_SET_PSHINDEX );
+ m_Storage.PutInt( nIndex );
+ }
+
+ FORCEINLINE void SetVertexShaderIndex( int nIndex )
+ {
+ m_Storage.PutInt( CBCMD_SET_VSHINDEX );
+ m_Storage.PutInt( nIndex );
+ }
+
+ FORCEINLINE void SetDepthFeatheringPixelShaderConstant( int iConstant, float fDepthBlendScale )
+ {
+ m_Storage.PutInt( CBCMD_SET_DEPTH_FEATHERING_CONST );
+ m_Storage.PutInt( iConstant );
+ m_Storage.PutFloat( fDepthBlendScale );
+ }
+
+ FORCEINLINE void Goto( uint8 *pCmdBuf )
+ {
+ m_Storage.PutInt( CBCMD_JUMP );
+ m_Storage.PutPtr( pCmdBuf );
+ }
+
+ FORCEINLINE void Call( uint8 *pCmdBuf )
+ {
+ m_Storage.PutInt( CBCMD_JSR );
+ m_Storage.PutPtr( pCmdBuf );
+ }
+
+ FORCEINLINE void Reset( void )
+ {
+ m_Storage.Reset();
+ }
+
+ FORCEINLINE size_t Size( void ) const
+ {
+ return m_Storage.Size();
+ }
+
+ FORCEINLINE uint8 *Base( void )
+ {
+ return m_Storage.Base();
+ }
+
+
+
+};
+
+
+#endif // commandbuilder_h
diff --git a/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h b/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h new file mode 100644 index 00000000..f9256a59 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_flashlight_fxc.h @@ -0,0 +1,821 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Common pixel shader code specific to flashlights
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_FLASHLIGHT_FXC_H_
+#define COMMON_FLASHLIGHT_FXC_H_
+
+#include "common_ps_fxc.h"
+
+
+// JasonM - TODO: remove this simpleton version
+float DoShadow( sampler DepthSampler, float4 texCoord )
+{
+ const float g_flShadowBias = 0.0005f;
+ float2 uoffset = float2( 0.5f/512.f, 0.0f );
+ float2 voffset = float2( 0.0f, 0.5f/512.f );
+ float3 projTexCoord = texCoord.xyz / texCoord.w;
+ float4 flashlightDepth = float4( tex2D( DepthSampler, projTexCoord + uoffset + voffset ).x,
+ tex2D( DepthSampler, projTexCoord + uoffset - voffset ).x,
+ tex2D( DepthSampler, projTexCoord - uoffset + voffset ).x,
+ tex2D( DepthSampler, projTexCoord - uoffset - voffset ).x );
+
+# if ( defined( REVERSE_DEPTH_ON_X360 ) )
+ {
+ flashlightDepth = 1.0f - flashlightDepth;
+ }
+# endif
+
+ float shadowed = 0.0f;
+ float z = texCoord.z/texCoord.w;
+ float4 dz = float4(z,z,z,z) - (flashlightDepth + float4( g_flShadowBias, g_flShadowBias, g_flShadowBias, g_flShadowBias));
+ float4 shadow = float4(0.25f,0.25f,0.25f,0.25f);
+
+ if( dz.x <= 0.0f )
+ shadowed += shadow.x;
+ if( dz.y <= 0.0f )
+ shadowed += shadow.y;
+ if( dz.z <= 0.0f )
+ shadowed += shadow.z;
+ if( dz.w <= 0.0f )
+ shadowed += shadow.w;
+
+ return shadowed;
+}
+
+
+float DoShadowNvidiaRAWZOneTap( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float ooW = 1.0f / shadowMapPos.w; // 1 / w
+ float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once
+
+ float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter
+ float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
+
+ float fDepth = dot(tex2D(DepthSampler, shadowMapCenter).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5));
+
+ return fDepth > objDepth;
+}
+
+
+float DoShadowNvidiaRAWZ( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float fE = 1.0f / 512.0f; // Epsilon
+
+ float ooW = 1.0f / shadowMapPos.w; // 1 / w
+ float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once
+
+ float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter
+ float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
+
+ float4 vDepths;
+ vDepths.x = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5));
+ vDepths.y = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5));
+ vDepths.z = dot(tex2D(DepthSampler, shadowMapCenter + float2( fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5));
+ vDepths.w = dot(tex2D(DepthSampler, shadowMapCenter + float2( -fE, -fE )).arg, float3(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5));
+
+ return dot(vDepths > objDepth.xxxx, float4(0.25, 0.25, 0.25, 0.25));
+}
+
+
+float DoShadowNvidiaCheap( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float fTexelEpsilon = 1.0f / 1024.0f;
+
+ float ooW = 1.0f / shadowMapPos.w; // 1 / w
+ float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once
+
+ float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter
+ float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
+
+ float4 vTaps;
+ vTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x;
+ vTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon), objDepth, 1 ) ).x;
+ vTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x;
+ vTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon), objDepth, 1 ) ).x;
+
+ return dot(vTaps, float4(0.25, 0.25, 0.25, 0.25));
+}
+
+float DoShadowNvidiaPCF3x3Box( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float fTexelEpsilon = 1.0f / 1024.0f;
+
+ float ooW = 1.0f / shadowMapPos.w; // 1 / w
+ float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once
+
+ float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter
+ float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
+
+ float4 vOneTaps;
+ vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, fTexelEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, -fTexelEpsilon ), objDepth, 1 ) ).x;
+ float flOneTaps = dot( vOneTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f));
+
+ float4 vTwoTaps;
+ vTwoTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTexelEpsilon, 0 ), objDepth, 1 ) ).x;
+ vTwoTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTexelEpsilon, 0 ), objDepth, 1 ) ).x;
+ vTwoTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x;
+ vTwoTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTexelEpsilon ), objDepth, 1 ) ).x;
+ float flTwoTaps = dot( vTwoTaps, float4(1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f, 1.0f / 9.0f));
+
+ float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (1.0f / 9.0f);
+
+ // Sum all 9 Taps
+ return flOneTaps + flTwoTaps + flCenterTap;
+}
+
+
+//
+// 1 4 7 4 1
+// 4 20 33 20 4
+// 7 33 55 33 7
+// 4 20 33 20 4
+// 1 4 7 4 1
+//
+float DoShadowNvidiaPCF5x5Gaussian( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float fEpsilon = 1.0f / 512.0f;
+ float fTwoEpsilon = 2.0f * fEpsilon;
+
+ float ooW = 1.0f / shadowMapPos.w; // 1 / w
+ float3 shadowMapCenter_objDepth = shadowMapPos.xyz * ooW; // Do both projections at once
+
+ float2 shadowMapCenter = shadowMapCenter_objDepth.xy; // Center of shadow filter
+ float objDepth = shadowMapCenter_objDepth.z; // Object depth in shadow space
+
+ float4 vOneTaps;
+ vOneTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ vOneTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ float flOneTaps = dot( vOneTaps, float4(1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f, 1.0f / 331.0f));
+
+ float4 vSevenTaps;
+ vSevenTaps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, 0 ), objDepth, 1 ) ).x;
+ vSevenTaps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, 0 ), objDepth, 1 ) ).x;
+ vSevenTaps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ vSevenTaps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ float flSevenTaps = dot( vSevenTaps, float4( 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f, 7.0f / 331.0f ) );
+
+ float4 vFourTapsA, vFourTapsB;
+ vFourTapsA.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsA.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsA.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fTwoEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsA.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, fEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsB.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsB.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsB.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fTwoEpsilon ), objDepth, 1 ) ).x;
+ vFourTapsB.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fTwoEpsilon, -fEpsilon ), objDepth, 1 ) ).x;
+ float flFourTapsA = dot( vFourTapsA, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) );
+ float flFourTapsB = dot( vFourTapsB, float4( 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f, 4.0f / 331.0f ) );
+
+ float4 v20Taps;
+ v20Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, fEpsilon ), objDepth, 1 ) ).x;
+ v20Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, fEpsilon ), objDepth, 1 ) ).x;
+ v20Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, -fEpsilon ), objDepth, 1 ) ).x;
+ v20Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, -fEpsilon ), objDepth, 1 ) ).x;
+ float fl20Taps = dot( v20Taps, float4(20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f, 20.0f / 331.0f));
+
+ float4 v33Taps;
+ v33Taps.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( fEpsilon, 0 ), objDepth, 1 ) ).x;
+ v33Taps.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -fEpsilon, 0 ), objDepth, 1 ) ).x;
+ v33Taps.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x;
+ v33Taps.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( 0, -fEpsilon ), objDepth, 1 ) ).x;
+ float fl33Taps = dot( v33Taps, float4(33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f, 33.0f / 331.0f));
+
+ float flCenterTap = tex2Dproj( DepthSampler, float4( shadowMapCenter, objDepth, 1 ) ).x * (55.0f / 331.0f);
+
+ // Sum all 25 Taps
+ return flOneTaps + flSevenTaps + +flFourTapsA + flFourTapsB + fl20Taps + fl33Taps + flCenterTap;
+}
+
+
+float DoShadowATICheap( sampler DepthSampler, const float4 shadowMapPos )
+{
+ float2 shadowMapCenter = shadowMapPos.xy/shadowMapPos.w;
+ float objDepth = shadowMapPos.z / shadowMapPos.w;
+ float fSampleDepth = tex2D( DepthSampler, shadowMapCenter ).x;
+
+ objDepth = min( objDepth, 0.99999 ); //HACKHACK: On 360, surfaces at or past the far flashlight plane have an abrupt cutoff. This is temp until a smooth falloff is implemented
+
+ return fSampleDepth > objDepth;
+}
+
+
+// Poisson disc, randomly rotated at different UVs
+float DoShadowPoisson16Sample( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks, bool bNvidiaHardwarePCF, bool bFetch4 )
+{
+ float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ),
+ float2( 0.8806f, 0.3430f ),
+ float2( -0.0041f, -0.6197f ),
+ float2( 0.0472f, 0.4964f ),
+ float2( -0.3730f, 0.0874f ),
+ float2( -0.9217f, -0.3177f ),
+ float2( -0.6289f, 0.7388f ),
+ float2( 0.5744f, -0.7741f ) };
+
+ float flScaleOverMapSize = vShadowTweaks.x * 2; // Tweak parameters to shader
+ float2 vNoiseOffset = vShadowTweaks.zw;
+ float4 vLightDepths = 0, accum = 0.0f;
+ float2 rotOffset = 0;
+
+ float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter
+ float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space
+
+ // 2D Rotation Matrix setup
+ float3 RMatTop = 0, RMatBottom = 0;
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5) + vNoiseOffset) * 2.0 - 1.0;
+ RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple
+#endif
+
+ RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution
+ RMatBottom *= flScaleOverMapSize;
+
+ RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below
+ RMatBottom.z = shadowMapCenter.y;
+
+ float fResult = 0.0f;
+
+ if ( bNvidiaHardwarePCF )
+ {
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z;
+ vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z;
+ vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z;
+ vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z;
+ vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z;
+ vLightDepths.x += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z;
+ vLightDepths.y += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z;
+ vLightDepths.z += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z;
+ vLightDepths.w += tex2Dproj( DepthSampler, float4(rotOffset, objDepth, 1) ).x;
+
+ fResult = dot( vLightDepths, float4( 0.25, 0.25, 0.25, 0.25) );
+ }
+ else if ( bFetch4 )
+ {
+/*
+
+TODO: Fix this contact hardening stuff
+
+ float flNumCloserSamples = 1;
+ float flAccumulatedCloserSamples = objDepth;
+ float4 vBlockerDepths;
+
+ // First, search for blockers
+ for( int j=0; j<8; j++ )
+ {
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[j].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[j].xy) + RMatBottom.z;
+ vBlockerDepths = tex2D( DepthSampler, rotOffset.xy );
+
+ // Which samples are closer than the pixel we're rendering?
+ float4 vCloserSamples = (vBlockerDepths < objDepth.xxxx ); // Binary comparison results
+ flNumCloserSamples += dot( vCloserSamples, float4(1, 1, 1, 1) ); // How many samples are closer than receiver?
+ flAccumulatedCloserSamples += dot (vCloserSamples, vBlockerDepths ); // Total depths from samples closer than receiver
+ }
+
+ float flBlockerDepth = flAccumulatedCloserSamples / flNumCloserSamples;
+ float flContactHardeningScale = (objDepth - flBlockerDepth) / flBlockerDepth;
+
+ // Scale the kernel
+ RMatTop.xy *= flContactHardeningScale;
+ RMatBottom.xy *= flContactHardeningScale;
+*/
+
+ for( int i=0; i<8; i++ )
+ {
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[i].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[i].xy) + RMatBottom.z;
+ vLightDepths = tex2D( DepthSampler, rotOffset.xy );
+ accum += (vLightDepths > objDepth.xxxx);
+ }
+
+ fResult = dot( accum, float4( 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f, 1.0f/32.0f) );
+ }
+ else // ATI vanilla hardware shadow mapping
+ {
+ for( int i=0; i<2; i++ )
+ {
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+0].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+0].xy) + RMatBottom.z;
+ vLightDepths.x = tex2D( DepthSampler, rotOffset.xy ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+1].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+1].xy) + RMatBottom.z;
+ vLightDepths.y = tex2D( DepthSampler, rotOffset.xy ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+2].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+2].xy) + RMatBottom.z;
+ vLightDepths.z = tex2D( DepthSampler, rotOffset.xy ).x;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4*i+3].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4*i+3].xy) + RMatBottom.z;
+ vLightDepths.w = tex2D( DepthSampler, rotOffset.xy ).x;
+
+ accum += (vLightDepths > objDepth.xxxx);
+ }
+
+ fResult = dot( accum, float4( 0.125, 0.125, 0.125, 0.125) );
+ }
+
+ return fResult;
+}
+
+#if defined( _X360 )
+
+// Poisson disc, randomly rotated at different UVs
+float DoShadow360Simple( sampler DepthSampler, const float3 vProjCoords )
+{
+ float fLOD;
+ float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter
+ float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ objDepth = 1.0f - objDepth;
+#endif
+
+ float4 vSampledDepths, vWeights;
+
+ asm {
+ getCompTexLOD2D fLOD.x, shadowMapCenter.xy, DepthSampler, AnisoFilter=max16to1
+ setTexLOD fLOD.x
+
+ tfetch2D vSampledDepths.x___, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths._x__, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.__x_, shadowMapCenter, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.___x, shadowMapCenter, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+
+ getWeights2D vWeights, shadowMapCenter.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true
+ };
+
+ vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y );
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ float4 vCompare = (vSampledDepths < objDepth.xxxx);
+#else
+ float4 vCompare = (vSampledDepths > objDepth.xxxx);
+#endif
+
+ return dot( vCompare, vWeights );
+}
+
+
+float Do360PCFFetch( sampler DepthSampler, float2 tc, float objDepth )
+{
+ float fLOD;
+ float4 vSampledDepths, vWeights;
+
+ asm {
+ getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1
+ setTexLOD fLOD.x
+
+ tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+
+ getWeights2D vWeights, tc.xy, DepthSampler, MagFilter=linear, MinFilter=linear, UseComputedLOD=false, UseRegisterLOD=true
+ };
+
+ vWeights = float4( (1-vWeights.x)*(1-vWeights.y), vWeights.x*(1-vWeights.y), (1-vWeights.x)*vWeights.y, vWeights.x*vWeights.y );
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ float4 vCompare = (vSampledDepths < objDepth.xxxx);
+#else
+ float4 vCompare = (vSampledDepths > objDepth.xxxx);
+#endif
+
+ return dot( vCompare, vWeights );
+}
+
+
+
+float Do360NearestFetch( sampler DepthSampler, float2 tc, float objDepth )
+{
+ float fLOD;
+ float4 vSampledDepth;
+
+ asm {
+ getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1
+ setTexLOD fLOD.x
+
+ tfetch2D vSampledDepth.x___, tc, DepthSampler, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ };
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ return (vSampledDepth.x < objDepth.x);
+#else
+ return (vSampledDepth.x > objDepth.x);
+#endif
+
+}
+
+
+float AmountShadowed_8Tap_360( sampler DepthSampler, float2 tc, float objDepth )
+{
+ float fLOD;
+ float4 vSampledDepthsA, vSampledDepthsB;
+
+ // Optimal 8 rooks pattern to get an idea about whether we're at a penumbra or not
+ // From [Kallio07] "Scanline Edge-Flag Algorithm for Antialiasing"
+ //
+ // +---+---+---+---+---+---+---+---+
+ // | | | | | | o | | |
+ // +---+---+---+---+---+---+---+---+
+ // | o | | | | | | | |
+ // +---+---+---+---+---+---+---+---+
+ // | | | | o | | | | |
+ // +---+---+---+---+---+---+---+---+
+ // | | | | | | | o | |
+ // +---+---+---+---+---+---+---+---+
+ // | | o | | | | | | |
+ // +---+---+---+---+---+---+---+---+
+ // | | | | | o | | | |
+ // +---+---+---+---+---+---+---+---+
+ // | | | | | | | | o |
+ // +---+---+---+---+---+---+---+---+
+ // | | | o | | | | | |
+ // +---+---+---+---+---+---+---+---+
+ //
+ asm {
+ getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1
+ setTexLOD fLOD.x
+
+ tfetch2D vSampledDepthsA.x___, tc, DepthSampler, OffsetX = -2.0, OffsetY = -1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsA._x__, tc, DepthSampler, OffsetX = -1.5, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsA.__x_, tc, DepthSampler, OffsetX = -1.0, OffsetY = 2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsA.___x, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+
+ tfetch2D vSampledDepthsB.x___, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsB._x__, tc, DepthSampler, OffsetX = 1.0, OffsetY = -2.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsB.__x_, tc, DepthSampler, OffsetX = 1.5, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepthsB.___x, tc, DepthSampler, OffsetX = 2.0, OffsetY = 1.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ };
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ float4 vCompareA = (vSampledDepthsA < objDepth.xxxx);
+ float4 vCompareB = (vSampledDepthsB < objDepth.xxxx);
+#else
+ float4 vCompareA = (vSampledDepthsA > objDepth.xxxx);
+ float4 vCompareB = (vSampledDepthsB > objDepth.xxxx);
+#endif
+
+ return dot( vCompareA, float4(0.125,0.125,0.125,0.125) ) + dot( vCompareB, float4(0.125,0.125,0.125,0.125) );
+}
+
+
+float AmountShadowed_4Tap_360( sampler DepthSampler, float2 tc, float objDepth )
+{
+ float fLOD;
+ float4 vSampledDepths;
+
+ // Rotated grid pattern to get an idea about whether we're at a penumbra or not
+ asm {
+ getCompTexLOD2D fLOD.x, tc.xy, DepthSampler, AnisoFilter=max16to1
+ setTexLOD fLOD.x
+
+ tfetch2D vSampledDepths.x___, tc, DepthSampler, OffsetX = -1.0, OffsetY = 0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths._x__, tc, DepthSampler, OffsetX = -0.5, OffsetY = -1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.__x_, tc, DepthSampler, OffsetX = 0.5, OffsetY = 1.0, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ tfetch2D vSampledDepths.___x, tc, DepthSampler, OffsetX = 1.0, OffsetY = -0.5, UseComputedLOD=false, UseRegisterLOD=true, MagFilter = point, MinFilter = point
+ };
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ float4 vCompare = (vSampledDepths < objDepth.xxxx);
+#else
+ float4 vCompare = (vSampledDepths > objDepth.xxxx);
+#endif
+
+ return dot( vCompare, float4(0.25,0.25,0.25,0.25) );
+}
+
+// Poisson disc, randomly rotated at different UVs
+float DoShadowPoisson360( sampler DepthSampler, sampler RandomRotationSampler, const float3 vProjCoords, const float2 vScreenPos, const float4 vShadowTweaks )
+{
+ float2 vPoissonOffset[8] = { float2( 0.3475f, 0.0042f ), float2( 0.8806f, 0.3430f ),
+ float2( -0.0041f, -0.6197f ), float2( 0.0472f, 0.4964f ),
+ float2( -0.3730f, 0.0874f ), float2( -0.9217f, -0.3177f ),
+ float2( -0.6289f, 0.7388f ), float2( 0.5744f, -0.7741f ) };
+
+ float2 shadowMapCenter = vProjCoords.xy; // Center of shadow filter
+ float objDepth = min( vProjCoords.z, 0.99999 ); // Object depth in shadow space
+
+#if defined( REVERSE_DEPTH_ON_X360 )
+ objDepth = 1.0f - objDepth;
+#endif
+
+ float fAmountShadowed = AmountShadowed_4Tap_360( DepthSampler, shadowMapCenter, objDepth );
+
+ if ( fAmountShadowed >= 1.0f ) // Fully in light
+ {
+ return 1.0f;
+ }
+ else // Do the expensive filtering since we're at least partially shadowed
+ {
+ float flScaleOverMapSize = 1.7f / 512.0f; // Tweak parameters to shader
+
+ // 2D Rotation Matrix setup
+ float3 RMatTop = 0, RMatBottom = 0;
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ RMatTop.xy = tex2D( RandomRotationSampler, cFlashlightScreenScale.xy * (vScreenPos * 0.5 + 0.5)) * 2.0 - 1.0;
+ RMatBottom.xy = float2(-1.0, 1.0) * RMatTop.yx; // 2x2 rotation matrix in 4-tuple
+#endif
+
+ RMatTop *= flScaleOverMapSize; // Scale up kernel while accounting for texture resolution
+ RMatBottom *= flScaleOverMapSize;
+ RMatTop.z = shadowMapCenter.x; // To be added in d2adds generated below
+ RMatBottom.z = shadowMapCenter.y;
+ float2 rotOffset = float2(0,0);
+ float4 vAccum = 0;
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[0].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[0].xy) + RMatBottom.z;
+ vAccum.x = Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[1].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[1].xy) + RMatBottom.z;
+ vAccum.y = Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[2].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[2].xy) + RMatBottom.z;
+ vAccum.z = Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[3].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[3].xy) + RMatBottom.z;
+ vAccum.w = Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[4].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[4].xy) + RMatBottom.z;
+ vAccum.x += Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[5].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[5].xy) + RMatBottom.z;
+ vAccum.y += Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[6].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[6].xy) + RMatBottom.z;
+ vAccum.z += Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ rotOffset.x = dot (RMatTop.xy, vPoissonOffset[7].xy) + RMatTop.z;
+ rotOffset.y = dot (RMatBottom.xy, vPoissonOffset[7].xy) + RMatBottom.z;
+ vAccum.w += Do360NearestFetch( DepthSampler, rotOffset, objDepth );
+
+ return dot( vAccum, float4( 0.25, 0.25, 0.25, 0.25) );
+ }
+}
+
+#endif // _X360
+
+
+float DoFlashlightShadow( sampler DepthSampler, sampler RandomRotationSampler, float3 vProjCoords, float2 vScreenPos, int nShadowLevel, float4 vShadowTweaks, bool bAllowHighQuality )
+{
+ float flShadow = 1.0f;
+
+#if !defined( _X360 ) //PC
+ if( nShadowLevel == NVIDIA_PCF_POISSON )
+ flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, true, false );
+ else if( nShadowLevel == ATI_NOPCF )
+ flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, false );
+ else if( nShadowLevel == ATI_NO_PCF_FETCH4 )
+ flShadow = DoShadowPoisson16Sample( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks, false, true );
+
+ return flShadow;
+#else
+
+ // Compile-time switch for shaders which allow high quality modes on 360
+ if ( bAllowHighQuality )
+ {
+ // Static control flow switch for shadow quality. Some non-interactive sequences use the high quality path
+ if ( g_bHighQualityShadows )
+ {
+ flShadow = DoShadowPoisson360( DepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, vShadowTweaks );
+ }
+ else
+ {
+ flShadow = DoShadow360Simple( DepthSampler, vProjCoords );
+ }
+ }
+ else
+ {
+ flShadow = DoShadow360Simple( DepthSampler, vProjCoords );
+ }
+
+ return flShadow;
+
+#endif
+}
+
+float3 SpecularLight( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent,
+ const float3 vEyeDir, const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel )
+{
+ float3 result = float3(0.0f, 0.0f, 0.0f);
+
+ //float3 vReflect = reflect( -vEyeDir, vWorldNormal );
+ float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal
+ float3 vSpecular = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?)
+ vSpecular = pow( vSpecular.x, fSpecularExponent ); // Raise to specular power
+
+ // Optionally warp as function of scalar specular and fresnel
+ if ( bDoSpecularWarp )
+ vSpecular *= tex2D( specularWarpSampler, float2(vSpecular.x, fFresnel) ); // Sample at { (L.R)^k, fresnel }
+
+ return vSpecular;
+}
+
+void DoSpecularFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal,
+ float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler, sampler RandomRotationSampler,
+ int nShadowLevel, bool bDoShadows, bool bAllowHighQuality, const float2 vScreenPos, const float fSpecularExponent, const float3 vEyeDir,
+ const bool bDoSpecularWarp, sampler specularWarpSampler, float fFresnel, float4 vShadowTweaks,
+
+ // Outputs of this shader...separate shadowed diffuse and specular from the flashlight
+ out float3 diffuseLighting, out float3 specularLighting )
+{
+ float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w;
+ float3 flashlightColor = float3(1,1,1);
+
+#if ( defined( _X360 ) )
+
+ float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f );
+ float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f );
+
+ [branch]
+ if ( dot(ltz + gto, float3(1,1,1)) > 0 )
+ {
+ clip(-1);
+ diffuseLighting = specularLighting = float3(0,0,0);
+ return;
+ }
+ else
+ {
+ flashlightColor = tex2D( FlashlightSampler, vProjCoords );
+
+ [branch]
+ if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 )
+ {
+ clip(-1);
+ diffuseLighting = specularLighting = float3(0,0,0);
+ return;
+ }
+ }
+#else
+ flashlightColor = tex2D( FlashlightSampler, vProjCoords );
+#endif
+
+
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ flashlightColor *= cFlashlightColor.xyz; // Flashlight color
+#endif
+
+ float3 delta = flashlightPos - worldPos;
+ float3 L = normalize( delta );
+ float distSquared = dot( delta, delta );
+ float dist = sqrt( distSquared );
+
+ float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f );
+
+ // Attenuation for light and to fade out shadow over distance
+ float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) );
+
+ // Shadowing and coloring terms
+#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))
+ if ( bDoShadows )
+ {
+ float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality );
+ float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated
+ flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation
+ flashlightColor *= flShadow; // Shadow term
+ }
+#endif
+
+ diffuseLighting = fAtten;
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) + flFlashlightNoLambertValue ); // Lambertian term
+#else
+ diffuseLighting *= saturate( dot( L.xyz, worldNormal.xyz ) ); // Lambertian (not Half-Lambert) term
+#endif
+ diffuseLighting *= flashlightColor;
+ diffuseLighting *= endFalloffFactor;
+
+ // Specular term (masked by diffuse)
+ specularLighting = diffuseLighting * SpecularLight ( worldNormal, L, fSpecularExponent, vEyeDir, bDoSpecularWarp, specularWarpSampler, fFresnel );
+}
+
+// Diffuse only version
+float3 DoFlashlight( float3 flashlightPos, float3 worldPos, float4 flashlightSpacePosition, float3 worldNormal,
+ float3 attenuationFactors, float farZ, sampler FlashlightSampler, sampler FlashlightDepthSampler,
+ sampler RandomRotationSampler, int nShadowLevel, bool bDoShadows, bool bAllowHighQuality,
+ const float2 vScreenPos, bool bClip, float4 vShadowTweaks = float4(3/1024.0f, 0.0005f, 0.0f, 0.0f), bool bHasNormal = true )
+{
+ float3 vProjCoords = flashlightSpacePosition.xyz / flashlightSpacePosition.w;
+ float3 flashlightColor = float3(1,1,1);
+
+#if ( defined( _X360 ) )
+
+ float3 ltz = vProjCoords.xyz < float3( 0.0f, 0.0f, 0.0f );
+ float3 gto = vProjCoords.xyz > float3( 1.0f, 1.0f, 1.0f );
+
+ [branch]
+ if ( dot(ltz + gto, float3(1,1,1)) > 0 )
+ {
+ if ( bClip )
+ {
+ clip(-1);
+ }
+ return float3(0,0,0);
+ }
+ else
+ {
+ flashlightColor = tex2D( FlashlightSampler, vProjCoords );
+
+ [branch]
+ if ( dot(flashlightColor.xyz, float3(1,1,1)) <= 0 )
+ {
+ if ( bClip )
+ {
+ clip(-1);
+ }
+ return float3(0,0,0);
+ }
+ }
+#else
+ flashlightColor = tex2D( FlashlightSampler, vProjCoords );
+#endif
+
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ flashlightColor *= cFlashlightColor.xyz; // Flashlight color
+#endif
+
+ float3 delta = flashlightPos - worldPos;
+ float3 L = normalize( delta );
+ float distSquared = dot( delta, delta );
+ float dist = sqrt( distSquared );
+
+ float endFalloffFactor = RemapValClamped( dist, farZ, 0.6f * farZ, 0.0f, 1.0f );
+
+ // Attenuation for light and to fade out shadow over distance
+ float fAtten = saturate( dot( attenuationFactors, float3( 1.0f, 1.0f/dist, 1.0f/distSquared ) ) );
+
+ // Shadowing and coloring terms
+#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))
+ if ( bDoShadows )
+ {
+ float flShadow = DoFlashlightShadow( FlashlightDepthSampler, RandomRotationSampler, vProjCoords, vScreenPos, nShadowLevel, vShadowTweaks, bAllowHighQuality );
+ float flAttenuated = lerp( flShadow, 1.0f, vShadowTweaks.y ); // Blend between fully attenuated and not attenuated
+ flShadow = saturate( lerp( flAttenuated, flShadow, fAtten ) ); // Blend between shadow and above, according to light attenuation
+ flashlightColor *= flShadow; // Shadow term
+ }
+#endif
+
+ float3 diffuseLighting = fAtten;
+
+ float flLDotWorldNormal;
+ if ( bHasNormal )
+ {
+ flLDotWorldNormal = dot( L.xyz, worldNormal.xyz );
+ }
+ else
+ {
+ flLDotWorldNormal = 1.0f;
+ }
+
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ diffuseLighting *= saturate( flLDotWorldNormal + flFlashlightNoLambertValue ); // Lambertian term
+#else
+ diffuseLighting *= saturate( flLDotWorldNormal ); // Lambertian (not Half-Lambert) term
+#endif
+
+ diffuseLighting *= flashlightColor;
+ diffuseLighting *= endFalloffFactor;
+
+ return diffuseLighting;
+}
+
+#endif //#ifndef COMMON_FLASHLIGHT_FXC_H_
diff --git a/mp/src/materialsystem/stdshaders/common_fxc.h b/mp/src/materialsystem/stdshaders/common_fxc.h new file mode 100644 index 00000000..b81c9a46 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_fxc.h @@ -0,0 +1,326 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_FXC_H_
+#define COMMON_FXC_H_
+
+#include "common_pragmas.h"
+#include "common_hlsl_cpp_consts.h"
+
+#ifdef NV3X
+# define HALF half
+# define HALF2 half2
+# define HALF3 half3
+# define HALF4 half4
+# define HALF3x3 half3x3
+# define HALF3x4 half3x4
+# define HALF4x3 half4x3
+# define HALF_CONSTANT( _constant ) ((HALF)_constant)
+#else
+# define HALF float
+# define HALF2 float2
+# define HALF3 float3
+# define HALF4 float4
+# define HALF3x3 float3x3
+# define HALF3x4 float3x4
+# define HALF4x3 float4x3
+# define HALF_CONSTANT( _constant ) _constant
+#endif
+
+// This is where all common code for both vertex and pixel shaders.
+#define OO_SQRT_3 0.57735025882720947f
+static const HALF3 bumpBasis[3] = {
+ HALF3( 0.81649661064147949f, 0.0f, OO_SQRT_3 ),
+ HALF3( -0.40824833512306213f, 0.70710676908493042f, OO_SQRT_3 ),
+ HALF3( -0.40824821591377258f, -0.7071068286895752f, OO_SQRT_3 )
+};
+static const HALF3 bumpBasisTranspose[3] = {
+ HALF3( 0.81649661064147949f, -0.40824833512306213f, -0.40824833512306213f ),
+ HALF3( 0.0f, 0.70710676908493042f, -0.7071068286895752f ),
+ HALF3( OO_SQRT_3, OO_SQRT_3, OO_SQRT_3 )
+};
+
+#if defined( _X360 )
+#define REVERSE_DEPTH_ON_X360 //uncomment to use D3DFMT_D24FS8 with an inverted depth viewport for better performance. Keep this in sync with the same named #define in public/shaderapi/shareddefs.h
+//Note that the reversal happens in the viewport. So ONLY reading back from a depth texture should be affected. Projected math is unaffected.
+#endif
+
+HALF3 CalcReflectionVectorNormalized( HALF3 normal, HALF3 eyeVector )
+{
+ // FIXME: might be better of normalizing with a normalizing cube map and
+ // get rid of the dot( normal, normal )
+ // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v
+ return 2.0 * ( dot( normal, eyeVector ) / dot( normal, normal ) ) * normal - eyeVector;
+}
+
+HALF3 CalcReflectionVectorUnnormalized( HALF3 normal, HALF3 eyeVector )
+{
+ // FIXME: might be better of normalizing with a normalizing cube map and
+ // get rid of the dot( normal, normal )
+ // compute reflection vector r = 2 * ((n dot v)/(n dot n)) n - v
+ // multiply all values through by N.N. uniformly scaling reflection vector won't affect result
+ // since it is used in a cubemap lookup
+ return (2.0*(dot( normal, eyeVector ))*normal) - (dot( normal, normal )*eyeVector);
+}
+
+float3 HuePreservingColorClamp( float3 c )
+{
+ // Get the max of all of the color components and a specified maximum amount
+ float maximum = max( max( c.x, c.y ), max( c.z, 1.0f ) );
+
+ return (c / maximum);
+}
+
+HALF3 HuePreservingColorClamp( HALF3 c, HALF maxVal )
+{
+ // Get the max of all of the color components and a specified maximum amount
+ float maximum = max( max( c.x, c.y ), max( c.z, maxVal ) );
+ return (c * ( maxVal / maximum ) );
+}
+
+#if (AA_CLAMP==1)
+HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord )
+{
+ HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99;
+ result += Lightmap3Coord;
+ return result;
+}
+
+void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord,
+ out HALF2 bumpCoord1,
+ out HALF2 bumpCoord2,
+ out HALF2 bumpCoord3 )
+{
+ HALF2 result = saturate(Lightmap1and2Coord.xy) * Lightmap1and2Coord.wz * 0.99;
+ result += Lightmap3Coord;
+ bumpCoord1 = result + HALF2(Lightmap1and2Coord.z, 0);
+ bumpCoord2 = result + 2*HALF2(Lightmap1and2Coord.z, 0);
+ bumpCoord3 = result + 3*HALF2(Lightmap1and2Coord.z, 0);
+}
+#else
+HALF2 ComputeLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord )
+{
+ return Lightmap1and2Coord.xy;
+}
+
+void ComputeBumpedLightmapCoordinates( HALF4 Lightmap1and2Coord, HALF2 Lightmap3Coord,
+ out HALF2 bumpCoord1,
+ out HALF2 bumpCoord2,
+ out HALF2 bumpCoord3 )
+{
+ bumpCoord1 = Lightmap1and2Coord.xy;
+ bumpCoord2 = Lightmap1and2Coord.wz; // reversed order!!!
+ bumpCoord3 = Lightmap3Coord.xy;
+}
+#endif
+
+// Versions of matrix multiply functions which force HLSL compiler to explictly use DOTs,
+// not giving it the option of using MAD expansion. In a perfect world, the compiler would
+// always pick the best strategy, and these shouldn't be needed.. but.. well.. umm..
+//
+// lorenmcq
+
+float3 mul3x3(float3 v, float3x3 m)
+{
+#if !defined( _X360 )
+ return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2]));
+#else
+ // xbox360 fxc.exe (new back end) borks with transposes, generates bad code
+ return mul( v, m );
+#endif
+}
+
+float3 mul4x3(float4 v, float4x3 m)
+{
+#if !defined( _X360 )
+ return float3(dot(v, transpose(m)[0]), dot(v, transpose(m)[1]), dot(v, transpose(m)[2]));
+#else
+ // xbox360 fxc.exe (new back end) borks with transposes, generates bad code
+ return mul( v, m );
+#endif
+}
+
+float3 DecompressHDR( float4 input )
+{
+ return input.rgb * input.a * MAX_HDR_OVERBRIGHT;
+}
+
+float4 CompressHDR( float3 input )
+{
+ // FIXME: want to use min so that we clamp to white, but what happens if we
+ // have an albedo component that's less than 1/MAX_HDR_OVERBRIGHT?
+ // float fMax = max( max( color.r, color.g ), color.b );
+ float4 output;
+ float fMax = min( min( input.r, input.g ), input.b );
+ if( fMax > 1.0f )
+ {
+ float oofMax = 1.0f / fMax;
+ output.rgb = oofMax * input.rgb;
+ output.a = min( fMax / MAX_HDR_OVERBRIGHT, 1.0f );
+ }
+ else
+ {
+ output.rgb = input.rgb;
+ output.a = 0.0f;
+ }
+ return output;
+}
+
+
+float3 LinearToGamma( const float3 f3linear )
+{
+ return pow( f3linear, 1.0f / 2.2f );
+}
+
+float4 LinearToGamma( const float4 f4linear )
+{
+ return float4( pow( f4linear.xyz, 1.0f / 2.2f ), f4linear.w );
+}
+
+float LinearToGamma( const float f1linear )
+{
+ return pow( f1linear, 1.0f / 2.2f );
+}
+
+float3 GammaToLinear( const float3 gamma )
+{
+ return pow( gamma, 2.2f );
+}
+
+float4 GammaToLinear( const float4 gamma )
+{
+ return float4( pow( gamma.xyz, 2.2f ), gamma.w );
+}
+
+float GammaToLinear( const float gamma )
+{
+ return pow( gamma, 2.2f );
+}
+
+// These two functions use the actual sRGB math
+float SrgbGammaToLinear( float flSrgbGammaValue )
+{
+ float x = saturate( flSrgbGammaValue );
+ return ( x <= 0.04045f ) ? ( x / 12.92f ) : ( pow( ( x + 0.055f ) / 1.055f, 2.4f ) );
+}
+
+float SrgbLinearToGamma( float flLinearValue )
+{
+ float x = saturate( flLinearValue );
+ return ( x <= 0.0031308f ) ? ( x * 12.92f ) : ( 1.055f * pow( x, ( 1.0f / 2.4f ) ) ) - 0.055f;
+}
+
+// These twofunctions use the XBox 360's exact piecewise linear algorithm
+float X360GammaToLinear( float fl360GammaValue )
+{
+ float flLinearValue;
+
+ fl360GammaValue = saturate( fl360GammaValue );
+ if ( fl360GammaValue < ( 96.0f / 255.0f ) )
+ {
+ if ( fl360GammaValue < ( 64.0f / 255.0f ) )
+ {
+ flLinearValue = fl360GammaValue * 255.0f;
+ }
+ else
+ {
+ flLinearValue = fl360GammaValue * ( 255.0f * 2.0f ) - 64.0f;
+ flLinearValue += floor( flLinearValue * ( 1.0f / 512.0f ) );
+ }
+ }
+ else
+ {
+ if( fl360GammaValue < ( 192.0f / 255.0f ) )
+ {
+ flLinearValue = fl360GammaValue * ( 255.0f * 4.0f ) - 256.0f;
+ flLinearValue += floor( flLinearValue * ( 1.0f / 256.0f ) );
+ }
+ else
+ {
+ flLinearValue = fl360GammaValue * ( 255.0f * 8.0f ) - 1024.0f;
+ flLinearValue += floor( flLinearValue * ( 1.0f / 128.0f ) );
+ }
+ }
+
+ flLinearValue *= 1.0f / 1023.0f;
+
+ flLinearValue = saturate( flLinearValue );
+ return flLinearValue;
+}
+
+float X360LinearToGamma( float flLinearValue )
+{
+ float fl360GammaValue;
+
+ flLinearValue = saturate( flLinearValue );
+ if ( flLinearValue < ( 128.0f / 1023.0f ) )
+ {
+ if ( flLinearValue < ( 64.0f / 1023.0f ) )
+ {
+ fl360GammaValue = flLinearValue * ( 1023.0f * ( 1.0f / 255.0f ) );
+ }
+ else
+ {
+ fl360GammaValue = flLinearValue * ( ( 1023.0f / 2.0f ) * ( 1.0f / 255.0f ) ) + ( 32.0f / 255.0f );
+ }
+ }
+ else
+ {
+ if ( flLinearValue < ( 512.0f / 1023.0f ) )
+ {
+ fl360GammaValue = flLinearValue * ( ( 1023.0f / 4.0f ) * ( 1.0f / 255.0f ) ) + ( 64.0f / 255.0f );
+ }
+ else
+ {
+ fl360GammaValue = flLinearValue * ( ( 1023.0f /8.0f ) * ( 1.0f / 255.0f ) ) + ( 128.0f /255.0f ); // 1.0 -> 1.0034313725490196078431372549016
+ if ( fl360GammaValue > 1.0f )
+ {
+ fl360GammaValue = 1.0f;
+ }
+ }
+ }
+
+ fl360GammaValue = saturate( fl360GammaValue );
+ return fl360GammaValue;
+}
+
+float SrgbGammaTo360Gamma( float flSrgbGammaValue )
+{
+ float flLinearValue = SrgbGammaToLinear( flSrgbGammaValue );
+ float fl360GammaValue = X360LinearToGamma( flLinearValue );
+ return fl360GammaValue;
+}
+
+float3 Vec3WorldToTangent( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
+{
+ float3 vTangentVector;
+ vTangentVector.x = dot( iWorldVector.xyz, iWorldTangent.xyz );
+ vTangentVector.y = dot( iWorldVector.xyz, iWorldBinormal.xyz );
+ vTangentVector.z = dot( iWorldVector.xyz, iWorldNormal.xyz );
+ return vTangentVector.xyz; // Return without normalizing
+}
+
+float3 Vec3WorldToTangentNormalized( float3 iWorldVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
+{
+ return normalize( Vec3WorldToTangent( iWorldVector, iWorldNormal, iWorldTangent, iWorldBinormal ) );
+}
+
+float3 Vec3TangentToWorld( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
+{
+ float3 vWorldVector;
+ vWorldVector.xyz = iTangentVector.x * iWorldTangent.xyz;
+ vWorldVector.xyz += iTangentVector.y * iWorldBinormal.xyz;
+ vWorldVector.xyz += iTangentVector.z * iWorldNormal.xyz;
+ return vWorldVector.xyz; // Return without normalizing
+}
+
+float3 Vec3TangentToWorldNormalized( float3 iTangentVector, float3 iWorldNormal, float3 iWorldTangent, float3 iWorldBinormal )
+{
+ return normalize( Vec3TangentToWorld( iTangentVector, iWorldNormal, iWorldTangent, iWorldBinormal ) );
+}
+
+#endif //#ifndef COMMON_FXC_H_
diff --git a/mp/src/materialsystem/stdshaders/common_fxc2.h b/mp/src/materialsystem/stdshaders/common_fxc2.h new file mode 100644 index 00000000..7ee8b48c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_fxc2.h @@ -0,0 +1,19 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_FXC2_H_
+#define COMMON_FXC2_H_
+
+// This file is here so you can add new utility functions without
+// changing common_fxc.h and causing a recompile of the entire universe.
+
+float LinearToMonochrome ( float3 r )
+{
+ return dot( r, float3( 0.299f, 0.587f, 0.114f ) );
+}
+
+#endif //#ifndef COMMON_FXC2_H_
diff --git a/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h b/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h new file mode 100644 index 00000000..523feee4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_hlsl_cpp_consts.h @@ -0,0 +1,27 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_HLSL_CONSTS_H_
+#define COMMON_HLSL_CONSTS_H_
+
+#ifdef NV3X
+ #define PSHADER_VECT_SCALE 20.0
+ #define VSHADER_VECT_SCALE (1.0 / (PSHADER_VECT_SCALE) )
+#else
+ #define PSHADER_VECT_SCALE 1.0
+ #define VSHADER_VECT_SCALE 1.0
+#endif
+
+// GR - HDR luminance maps to 0..n range
+// IMPORTANT: Keep the same value as in materialsystem_global.h
+// HDRFIXME: Make this a pixel shader constant?
+#define MAX_HDR_OVERBRIGHT 16.0f
+
+#define LINEAR_FOG_COLOR 29
+#define TONE_MAPPING_SCALE_PSH_CONSTANT 30
+
+#endif //#ifndef COMMON_HLSL_CONSTS_H_
diff --git a/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h b/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h new file mode 100644 index 00000000..e82bdf65 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_lightmappedgeneric_fxc.h @@ -0,0 +1,202 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+
+
+#if defined( _X360 )
+
+void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights,
+ out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump )
+{
+ vResultBase = 0;
+ vResultBase2 = 0;
+ vResultBump = 0;
+
+ if ( !bBump )
+ {
+ vResultBump = float4(0, 0, 1, 1);
+ }
+
+#if SEAMLESS
+
+ vWeights = max( vWeights - 0.3, 0 );
+
+ vWeights *= 1.0f / dot( vWeights, float3(1,1,1) );
+
+ [branch]
+ if (vWeights.x > 0)
+ {
+ vResultBase += vWeights.x * tex2D( base, coords.zy );
+
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.x * tex2D( base2, coords.zy );
+ }
+
+ if ( bBump )
+ {
+ vResultBump += vWeights.x * tex2D( bump, coords.zy );
+ }
+ }
+
+ [branch]
+ if (vWeights.y > 0)
+ {
+ vResultBase += vWeights.y * tex2D( base, coords.xz );
+
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.y * tex2D( base2, coords.xz );
+ }
+ if ( bBump )
+ {
+ vResultBump += vWeights.y * tex2D( bump, coords.xz );
+ }
+ }
+
+ [branch]
+ if (vWeights.z > 0)
+ {
+ vResultBase += vWeights.z * tex2D( base, coords.xy );
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.z * tex2D( base2, coords.xy );
+ }
+
+ if ( bBump )
+ {
+ vResultBump += vWeights.z * tex2D( bump, coords.xy );
+ }
+ }
+
+#else // not seamless
+
+ vResultBase = tex2D( base, coords.xy );
+
+ if ( bBase2 )
+ {
+ vResultBase2 = tex2D( base2, coords.xy );
+ }
+
+ if ( bBump )
+ {
+ vResultBump = tex2D( bump, coords.xy );
+ }
+
+#endif
+
+
+}
+
+#else // PC
+
+void GetBaseTextureAndNormal( sampler base, sampler base2, sampler bump, bool bBase2, bool bBump, float3 coords, float3 vWeights,
+ out float4 vResultBase, out float4 vResultBase2, out float4 vResultBump )
+{
+ vResultBase = 0;
+ vResultBase2 = 0;
+ vResultBump = 0;
+
+ if ( !bBump )
+ {
+ vResultBump = float4(0, 0, 1, 1);
+ }
+
+#if SEAMLESS
+
+ vResultBase += vWeights.x * tex2D( base, coords.zy );
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.x * tex2D( base2, coords.zy );
+ }
+ if ( bBump )
+ {
+ vResultBump += vWeights.x * tex2D( bump, coords.zy );
+ }
+
+ vResultBase += vWeights.y * tex2D( base, coords.xz );
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.y * tex2D( base2, coords.xz );
+ }
+ if ( bBump )
+ {
+ vResultBump += vWeights.y * tex2D( bump, coords.xz );
+ }
+
+ vResultBase += vWeights.z * tex2D( base, coords.xy );
+ if ( bBase2 )
+ {
+ vResultBase2 += vWeights.z * tex2D( base2, coords.xy );
+ }
+ if ( bBump )
+ {
+ vResultBump += vWeights.z * tex2D( bump, coords.xy );
+ }
+
+#else // not seamless
+
+ vResultBase = tex2D( base, coords.xy );
+ if ( bBase2 )
+ {
+ vResultBase2 = tex2D( base2, coords.xy );
+ }
+ if ( bBump )
+ {
+ vResultBump = tex2D( bump, coords.xy );
+ }
+#endif
+
+}
+
+#endif
+
+
+
+
+float3 LightMapSample( sampler LightmapSampler, float2 vTexCoord )
+{
+# if ( !defined( _X360 ) || !defined( USE_32BIT_LIGHTMAPS_ON_360 ) )
+ {
+ float3 sample = tex2D( LightmapSampler, vTexCoord );
+
+ return sample;
+ }
+# else
+ {
+# if 0 //1 for cheap sampling, 0 for accurate scaling from the individual samples
+ {
+ float4 sample = tex2D( LightmapSampler, vTexCoord );
+
+ return sample.rgb * sample.a;
+ }
+# else
+ {
+ float4 Weights;
+ float4 samples_0; //no arrays allowed in inline assembly
+ float4 samples_1;
+ float4 samples_2;
+ float4 samples_3;
+
+ asm {
+ tfetch2D samples_0, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false
+ tfetch2D samples_1, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = -0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false
+ tfetch2D samples_2, vTexCoord.xy, LightmapSampler, OffsetX = -0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false
+ tfetch2D samples_3, vTexCoord.xy, LightmapSampler, OffsetX = 0.5, OffsetY = 0.5, MinFilter=point, MagFilter=point, MipFilter=keep, UseComputedLOD=false
+
+ getWeights2D Weights, vTexCoord.xy, LightmapSampler
+ };
+
+ Weights = float4( (1-Weights.x)*(1-Weights.y), Weights.x*(1-Weights.y), (1-Weights.x)*Weights.y, Weights.x*Weights.y );
+
+ float3 result;
+ result.rgb = samples_0.rgb * (samples_0.a * Weights.x);
+ result.rgb += samples_1.rgb * (samples_1.a * Weights.y);
+ result.rgb += samples_2.rgb * (samples_2.a * Weights.z);
+ result.rgb += samples_3.rgb * (samples_3.a * Weights.w);
+
+ return result;
+ }
+# endif
+ }
+# endif
+}
+
diff --git a/mp/src/materialsystem/stdshaders/common_pragmas.h b/mp/src/materialsystem/stdshaders/common_pragmas.h new file mode 100644 index 00000000..50b61ff0 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_pragmas.h @@ -0,0 +1,38 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Common shader compiler pragmas
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_PRAGMAS_H_
+#define COMMON_PRAGMAS_H_
+
+//
+// Validated shader models:
+//
+// SHADER_MODEL_VS_1_1
+// SHADER_MODEL_VS_2_0
+// SHADER_MODEL_VS_3_0
+//
+// SHADER_MODEL_PS_1_1
+// SHADER_MODEL_PS_1_4
+// SHADER_MODEL_PS_2_0
+// SHADER_MODEL_PS_2_B
+// SHADER_MODEL_PS_3_0
+//
+//
+//
+// Platforms:
+//
+// PC
+// _X360
+//
+
+// Special pragmas silencing common warnings
+#pragma warning ( disable : 3557 ) // warning X3557: Loop only executes for N iteration(s), forcing loop to unroll
+#pragma warning ( disable : 3595 ) // warning X3595: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused
+#pragma warning ( disable : 3596 ) // warning X3596: Microcode Compiler possible performance issue: pixel shader input semantic ___ is unused
+#pragma warning ( disable : 4702 ) // warning X4702: complement opportunity missed because input result WAS clamped from 0 to 1
+
+#endif //#ifndef COMMON_PRAGMAS_H_
diff --git a/mp/src/materialsystem/stdshaders/common_ps_fxc.h b/mp/src/materialsystem/stdshaders/common_ps_fxc.h new file mode 100644 index 00000000..d4a47ea5 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_ps_fxc.h @@ -0,0 +1,804 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Common pixel shader code
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMON_PS_FXC_H_
+#define COMMON_PS_FXC_H_
+
+#include "common_fxc.h"
+
+// Put global skip commands here. . make sure and check that the appropriate vars are defined
+// so these aren't used on the wrong shaders!
+
+// --------------------------------------------------------------------------------
+// HDR should never be enabled if we don't aren't running in float or integer HDR mode.
+// SKIP: defined $HDRTYPE && defined $HDRENABLED && !$HDRTYPE && $HDRENABLED
+// --------------------------------------------------------------------------------
+// We don't ever write water fog to dest alpha if we aren't doing water fog.
+// SKIP: defined $PIXELFOGTYPE && defined $WRITEWATERFOGTODESTALPHA && ( $PIXELFOGTYPE != 1 ) && $WRITEWATERFOGTODESTALPHA
+// --------------------------------------------------------------------------------
+// We don't need fog in the pixel shader if we aren't in float fog mode2
+// NOSKIP: defined $HDRTYPE && defined $HDRENABLED && defined $PIXELFOGTYPE && $HDRTYPE != HDR_TYPE_FLOAT && $FOGTYPE != 0
+// --------------------------------------------------------------------------------
+// We don't do HDR and LIGHTING_PREVIEW at the same time since it's running LDR in hammer.
+// SKIP: defined $LIGHTING_PREVIEW && defined $HDRTYPE && $LIGHTING_PREVIEW && $HDRTYPE != 0
+// --------------------------------------------------------------------------------
+// Ditch all fastpath attempts if we are doing LIGHTING_PREVIEW.
+// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPTINT && $LIGHTING_PREVIEW && $FASTPATHENVMAPTINT
+// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATHENVMAPCONTRAST && $LIGHTING_PREVIEW && $FASTPATHENVMAPCONTRAST
+// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH
+// --------------------------------------------------------------------------------
+// Ditch flashlight depth when flashlight is disabled
+// SKIP: ($FLASHLIGHT || $FLASHLIGHTSHADOWS) && $LIGHTING_PREVIEW
+// --------------------------------------------------------------------------------
+
+// System defined pixel shader constants
+
+#if defined( _X360 )
+const bool g_bHighQualityShadows : register( b0 );
+#endif
+
+// NOTE: w == 1.0f / (Dest alpha compressed depth range).
+const float4 g_LinearFogColor : register( c29 );
+#define OO_DESTALPHA_DEPTH_RANGE (g_LinearFogColor.w)
+
+// Linear and gamma light scale values
+const float4 cLightScale : register( c30 );
+#define LINEAR_LIGHT_SCALE (cLightScale.x)
+#define LIGHT_MAP_SCALE (cLightScale.y)
+#define ENV_MAP_SCALE (cLightScale.z)
+#define GAMMA_LIGHT_SCALE (cLightScale.w)
+
+// Flashlight constants
+#if defined(SHADER_MODEL_PS_2_0) || defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)
+ const float4 cFlashlightColor : register( c28 );
+ const float4 cFlashlightScreenScale : register( c31 ); // .zw are currently unused
+ #define flFlashlightNoLambertValue cFlashlightColor.w // This is either 0.0 or 2.0
+#endif
+
+#define HDR_INPUT_MAP_SCALE 16.0f
+
+#define TONEMAP_SCALE_NONE 0
+#define TONEMAP_SCALE_LINEAR 1
+#define TONEMAP_SCALE_GAMMA 2
+
+#define PIXEL_FOG_TYPE_NONE -1 //MATERIAL_FOG_NONE is handled by PIXEL_FOG_TYPE_RANGE, this is for explicitly disabling fog in the shader
+#define PIXEL_FOG_TYPE_RANGE 0 //range+none packed together in ps2b. Simply none in ps20 (instruction limits)
+#define PIXEL_FOG_TYPE_HEIGHT 1
+
+// If you change these, make the corresponding change in hardwareconfig.cpp
+#define NVIDIA_PCF_POISSON 0
+#define ATI_NOPCF 1
+#define ATI_NO_PCF_FETCH4 2
+
+struct LPREVIEW_PS_OUT
+{
+ float4 color : COLOR0;
+ float4 normal : COLOR1;
+ float4 position : COLOR2;
+ float4 flags : COLOR3;
+};
+
+/*
+// unused
+HALF Luminance( HALF3 color )
+{
+ return dot( color, HALF3( HALF_CONSTANT(0.30f), HALF_CONSTANT(0.59f), HALF_CONSTANT(0.11f) ) );
+}
+*/
+
+/*
+// unused
+HALF LuminanceScaled( HALF3 color )
+{
+ return dot( color, HALF3( HALF_CONSTANT(0.30f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.59f) / MAX_HDR_OVERBRIGHT, HALF_CONSTANT(0.11f) / MAX_HDR_OVERBRIGHT ) );
+}
+*/
+
+/*
+// unused
+HALF AvgColor( HALF3 color )
+{
+ return dot( color, HALF3( HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f), HALF_CONSTANT(0.33333f) ) );
+}
+*/
+
+/*
+// unused
+HALF4 DiffuseBump( sampler lightmapSampler,
+ float2 lightmapTexCoord1,
+ float2 lightmapTexCoord2,
+ float2 lightmapTexCoord3,
+ HALF3 normal )
+{
+ HALF3 lightmapColor1 = tex2D( lightmapSampler, lightmapTexCoord1 );
+ HALF3 lightmapColor2 = tex2D( lightmapSampler, lightmapTexCoord2 );
+ HALF3 lightmapColor3 = tex2D( lightmapSampler, lightmapTexCoord3 );
+
+ HALF3 diffuseLighting;
+ diffuseLighting = saturate( dot( normal, bumpBasis[0] ) ) * lightmapColor1 +
+ saturate( dot( normal, bumpBasis[1] ) ) * lightmapColor2 +
+ saturate( dot( normal, bumpBasis[2] ) ) * lightmapColor3;
+
+ return HALF4( diffuseLighting, LuminanceScaled( diffuseLighting ) );
+}
+*/
+
+
+/*
+// unused
+HALF Fresnel( HALF3 normal,
+ HALF3 eye,
+ HALF2 scaleBias )
+{
+ HALF fresnel = HALF_CONSTANT(1.0f) - dot( normal, eye );
+ fresnel = pow( fresnel, HALF_CONSTANT(5.0f) );
+
+ return fresnel * scaleBias.x + scaleBias.y;
+}
+*/
+
+/*
+// unused
+HALF4 GetNormal( sampler normalSampler,
+ float2 normalTexCoord )
+{
+ HALF4 normal = tex2D( normalSampler, normalTexCoord );
+ normal.rgb = HALF_CONSTANT(2.0f) * normal.rgb - HALF_CONSTANT(1.0f);
+
+ return normal;
+}
+*/
+
+// Needs to match NormalDecodeMode_t enum in imaterialsystem.h
+#define NORM_DECODE_NONE 0
+#define NORM_DECODE_ATI2N 1
+#define NORM_DECODE_ATI2N_ALPHA 2
+
+float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode, sampler AlphaSampler )
+{
+ float4 normalTexel = tex2D( NormalSampler, tc );
+ float4 result;
+
+ if ( nDecompressionMode == NORM_DECODE_NONE )
+ {
+ result = float4(normalTexel.xyz * 2.0f - 1.0f, normalTexel.a );
+ }
+ else if ( nDecompressionMode == NORM_DECODE_ATI2N )
+ {
+ result.xy = normalTexel.xy * 2.0f - 1.0f;
+ result.z = sqrt( 1.0f - dot(result.xy, result.xy) );
+ result.a = 1.0f;
+ }
+ else // ATI2N plus ATI1N for alpha
+ {
+ result.xy = normalTexel.xy * 2.0f - 1.0f;
+ result.z = sqrt( 1.0f - dot(result.xy, result.xy) );
+ result.a = tex2D( AlphaSampler, tc ).x; // Note that this comes in on the X channel
+ }
+
+ return result;
+}
+
+float4 DecompressNormal( sampler NormalSampler, float2 tc, int nDecompressionMode )
+{
+ return DecompressNormal( NormalSampler, tc, nDecompressionMode, NormalSampler );
+}
+
+
+HALF3 NormalizeWithCubemap( sampler normalizeSampler, HALF3 input )
+{
+// return texCUBE( normalizeSampler, input ) * 2.0f - 1.0f;
+ return texCUBE( normalizeSampler, input );
+}
+
+/*
+HALF4 EnvReflect( sampler envmapSampler,
+ sampler normalizeSampler,
+ HALF3 normal,
+ float3 eye,
+ HALF2 fresnelScaleBias )
+{
+ HALF3 normEye = NormalizeWithCubemap( normalizeSampler, eye );
+ HALF fresnel = Fresnel( normal, normEye, fresnelScaleBias );
+ HALF3 reflect = CalcReflectionVectorUnnormalized( normal, eye );
+ return texCUBE( envmapSampler, reflect );
+}
+*/
+
+float CalcWaterFogAlpha( const float flWaterZ, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ, const float flFogOORange )
+{
+// float flDepthFromWater = flWaterZ - flWorldPosZ + 2.0f; // hackity hack . .this is for the DF_FUDGE_UP in view_scene.cpp
+ float flDepthFromWater = flWaterZ - flWorldPosZ;
+
+ // if flDepthFromWater < 0, then set it to 0
+ // This is the equivalent of moving the vert to the water surface if it's above the water surface
+ // We'll do this with the saturate at the end instead.
+// flDepthFromWater = max( 0.0f, flDepthFromWater );
+
+ // Calculate the ratio of water fog to regular fog (ie. how much of the distance from the viewer
+ // to the vert is actually underwater.
+ float flDepthFromEye = flEyePosZ - flWorldPosZ;
+ float f = saturate(flDepthFromWater * (1.0/flDepthFromEye));
+
+ // $tmp.w is now the distance that we see through water.
+ return saturate(f * flProjPosZ * flFogOORange);
+}
+
+float CalcRangeFog( const float flProjPosZ, const float flFogStartOverRange, const float flFogMaxDensity, const float flFogOORange )
+{
+#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b
+ return saturate( min( flFogMaxDensity, (flProjPosZ * flFogOORange) - flFogStartOverRange ) );
+#else
+ return 0.0f; //ps20 shaders will never have range fog enabled because too many ran out of slots.
+#endif
+}
+
+float CalcPixelFogFactor( int iPIXELFOGTYPE, const float4 fogParams, const float flEyePosZ, const float flWorldPosZ, const float flProjPosZ )
+{
+ float retVal;
+ if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE )
+ {
+ retVal = 0.0f;
+ }
+ if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //range fog, or no fog depending on fog parameters
+ {
+ retVal = CalcRangeFog( flProjPosZ, fogParams.x, fogParams.z, fogParams.w );
+ }
+ else if ( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT ) //height fog
+ {
+ retVal = CalcWaterFogAlpha( fogParams.y, flEyePosZ, flWorldPosZ, flProjPosZ, fogParams.w );
+ }
+
+ return retVal;
+}
+
+//g_FogParams not defined by default, but this is the same layout for every shader that does define it
+#define g_FogEndOverRange g_FogParams.x
+#define g_WaterZ g_FogParams.y
+#define g_FogMaxDensity g_FogParams.z
+#define g_FogOORange g_FogParams.w
+
+float3 BlendPixelFog( const float3 vShaderColor, float pixelFogFactor, const float3 vFogColor, const int iPIXELFOGTYPE )
+{
+ if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_RANGE ) //either range fog or no fog depending on fog parameters and whether this is ps20 or ps2b
+ {
+# if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b
+ pixelFogFactor = saturate( pixelFogFactor );
+ return lerp( vShaderColor.rgb, vFogColor.rgb, pixelFogFactor * pixelFogFactor ); //squaring the factor will get the middle range mixing closer to hardware fog
+# else
+ return vShaderColor;
+# endif
+ }
+ else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT )
+ {
+ return lerp( vShaderColor.rgb, vFogColor.rgb, saturate( pixelFogFactor ) );
+ }
+ else if( iPIXELFOGTYPE == PIXEL_FOG_TYPE_NONE )
+ {
+ return vShaderColor;
+ }
+}
+
+
+#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)) && ( CONVERT_TO_SRGB != 0 ) )
+sampler1D GammaTableSampler : register( s15 );
+
+float3 SRGBOutput( const float3 vShaderColor )
+{
+ //On ps2b capable hardware we always have the linear->gamma conversion table texture in sampler s15.
+ float3 result;
+ result.r = tex1D( GammaTableSampler, vShaderColor.r ).r;
+ result.g = tex1D( GammaTableSampler, vShaderColor.g ).r;
+ result.b = tex1D( GammaTableSampler, vShaderColor.b ).r;
+ return result;
+}
+
+#else
+
+float3 SRGBOutput( const float3 vShaderColor )
+{
+ return vShaderColor; //ps 1.1, 1.4, and 2.0 never do srgb conversion in the pixel shader
+}
+
+#endif
+
+
+float SoftParticleDepth( float flDepth )
+{
+ return flDepth * OO_DESTALPHA_DEPTH_RANGE;
+}
+
+
+float DepthToDestAlpha( const float flProjZ )
+{
+#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b
+ return SoftParticleDepth( flProjZ );
+#else
+ return 1.0f;
+#endif
+}
+
+
+float4 FinalOutput( const float4 vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE, const bool bWriteDepthToDestAlpha = false, const float flProjZ = 1.0f )
+{
+ float4 result;
+ if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_LINEAR )
+ {
+ result.rgb = vShaderColor.rgb * LINEAR_LIGHT_SCALE;
+ }
+ else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_GAMMA )
+ {
+ result.rgb = vShaderColor.rgb * GAMMA_LIGHT_SCALE;
+ }
+ else if( iTONEMAP_SCALE_TYPE == TONEMAP_SCALE_NONE )
+ {
+ result.rgb = vShaderColor.rgb;
+ }
+
+ if( bWriteDepthToDestAlpha )
+ result.a = DepthToDestAlpha( flProjZ );
+ else
+ result.a = vShaderColor.a;
+
+ result.rgb = BlendPixelFog( result.rgb, pixelFogFactor, g_LinearFogColor.rgb, iPIXELFOGTYPE );
+
+#if !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) //Minimum requirement of ps2b
+ result.rgb = SRGBOutput( result.rgb ); //SRGB in pixel shader conversion
+#endif
+
+ return result;
+}
+
+LPREVIEW_PS_OUT FinalOutput( const LPREVIEW_PS_OUT vShaderColor, float pixelFogFactor, const int iPIXELFOGTYPE, const int iTONEMAP_SCALE_TYPE )
+{
+ LPREVIEW_PS_OUT result;
+ result.color = FinalOutput( vShaderColor.color, pixelFogFactor, iPIXELFOGTYPE, iTONEMAP_SCALE_TYPE );
+ result.normal.rgb = SRGBOutput( vShaderColor.normal.rgb );
+ result.normal.a = vShaderColor.normal.a;
+
+ result.position.rgb = SRGBOutput( vShaderColor.position.rgb );
+ result.position.a = vShaderColor.position.a;
+
+ result.flags.rgb = SRGBOutput( vShaderColor.flags.rgb );
+ result.flags.a = vShaderColor.flags.a;
+
+ return result;
+}
+
+
+
+
+float RemapValClamped( float val, float A, float B, float C, float D)
+{
+ float cVal = (val - A) / (B - A);
+ cVal = saturate( cVal );
+
+ return C + (D - C) * cVal;
+}
+
+
+//===================================================================================//
+// This is based on Natasha Tatarchuk's Parallax Occlusion Mapping (ATI)
+//===================================================================================//
+// INPUT:
+// inTexCoord:
+// the texcoord for the height/displacement map before parallaxing
+//
+// vParallax:
+// Compute initial parallax displacement direction:
+// float2 vParallaxDirection = normalize( vViewTS.xy );
+// float fLength = length( vViewTS );
+// float fParallaxLength = sqrt( fLength * fLength - vViewTS.z * vViewTS.z ) / vViewTS.z;
+// Out.vParallax = vParallaxDirection * fParallaxLength * fProjectedBumpHeight;
+//
+// vNormal:
+// tangent space normal
+//
+// vViewW:
+// float3 vViewW = /*normalize*/(mul( matViewInverse, float4( 0, 0, 0, 1)) - inPosition );
+//
+// OUTPUT:
+// the new texcoord after parallaxing
+float2 CalcParallaxedTexCoord( float2 inTexCoord, float2 vParallax, float3 vNormal,
+ float3 vViewW, sampler HeightMapSampler )
+{
+ const int nMinSamples = 8;
+ const int nMaxSamples = 50;
+
+ // Normalize the incoming view vector to avoid artifacts:
+// vView = normalize( vView );
+ vViewW = normalize( vViewW );
+// vLight = normalize( vLight );
+
+ // Change the number of samples per ray depending on the viewing angle
+ // for the surface. Oblique angles require smaller step sizes to achieve
+ // more accurate precision
+ int nNumSteps = (int) lerp( nMaxSamples, nMinSamples, dot( vViewW, vNormal ) );
+
+ float4 cResultColor = float4( 0, 0, 0, 1 );
+
+ //===============================================//
+ // Parallax occlusion mapping offset computation //
+ //===============================================//
+ float fCurrHeight = 0.0;
+ float fStepSize = 1.0 / (float) nNumSteps;
+ float fPrevHeight = 1.0;
+ float fNextHeight = 0.0;
+
+ int nStepIndex = 0;
+// bool bCondition = true;
+
+ float2 dx = ddx( inTexCoord );
+ float2 dy = ddy( inTexCoord );
+
+ float2 vTexOffsetPerStep = fStepSize * vParallax;
+
+ float2 vTexCurrentOffset = inTexCoord;
+ float fCurrentBound = 1.0;
+
+ float x = 0;
+ float y = 0;
+ float xh = 0;
+ float yh = 0;
+
+ float2 texOffset2 = 0;
+
+ bool bCondition = true;
+ while ( bCondition == true && nStepIndex < nNumSteps )
+ {
+ vTexCurrentOffset -= vTexOffsetPerStep;
+
+ fCurrHeight = tex2Dgrad( HeightMapSampler, vTexCurrentOffset, dx, dy ).r;
+
+ fCurrentBound -= fStepSize;
+
+ if ( fCurrHeight > fCurrentBound )
+ {
+ x = fCurrentBound;
+ y = fCurrentBound + fStepSize;
+ xh = fCurrHeight;
+ yh = fPrevHeight;
+
+ texOffset2 = vTexCurrentOffset - vTexOffsetPerStep;
+
+ bCondition = false;
+ }
+ else
+ {
+ nStepIndex++;
+ fPrevHeight = fCurrHeight;
+ }
+
+ } // End of while ( bCondition == true && nStepIndex > -1 )#else
+
+ fCurrentBound -= fStepSize;
+
+ float fParallaxAmount;
+ float numerator = (x * (y - yh) - y * (x - xh));
+ float denomenator = ((y - yh) - (x - xh));
+ // avoid NaN generation
+ if( ( numerator == 0.0f ) && ( denomenator == 0.0f ) )
+ {
+ fParallaxAmount = 0.0f;
+ }
+ else
+ {
+ fParallaxAmount = numerator / denomenator;
+ }
+
+ float2 vParallaxOffset = vParallax * (1 - fParallaxAmount );
+
+ // Sample the height at the next possible step:
+ fNextHeight = tex2Dgrad( HeightMapSampler, texOffset2, dx, dy ).r;
+
+ // Original offset:
+ float2 texSampleBase = inTexCoord - vParallaxOffset;
+
+ return texSampleBase;
+
+#if 0
+ cResultColor.rgb = ComputeDiffuseColor( texSampleBase, vLight );
+
+ float fBound = 1.0 - fStepSize * nStepIndex;
+ if ( fNextHeight < fCurrentBound )
+// if( 0 )
+ {
+ //void DoIteration( in float2 vParallaxJittered, in float3 vLight, inout float4 cResultColor )
+ //cResultColor.rgb = float3(1,0,0);
+ DoIteration( vParallax + vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor );
+ DoIteration( vParallax - vPixelSize, vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor );
+ DoIteration( vParallax + float2( -vPixelSize.x, vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor );
+ DoIteration( vParallax + float2( vPixelSize.x, -vPixelSize.y ), vLight, fStepSize, inTexCoord, nStepIndex, dx, dy, fBound, cResultColor );
+
+ cResultColor.rgb /= 5;
+// cResultColor.rgb = float3( 1.0f, 0.0f, 0.0f );
+ } // End of if ( fNextHeight < fCurrentBound )
+
+#if DOSHADOWS
+ {
+ //============================================//
+ // Soft shadow and self-occlusion computation //
+ //============================================//
+ // Compute the blurry shadows (note that this computation takes into
+ // account self-occlusion for shadow computation):
+ float sh0 = tex2D( sNormalMap, texSampleBase).w;
+ float shA = (tex2D( sNormalMap, texSampleBase + inXY * 0.88 ).w - sh0 - 0.88 ) * 1 * fShadowSoftening;
+ float sh9 = (tex2D( sNormalMap, texSampleBase + inXY * 0.77 ).w - sh0 - 0.77 ) * 2 * fShadowSoftening;
+ float sh8 = (tex2D( sNormalMap, texSampleBase + inXY * 0.66 ).w - sh0 - 0.66 ) * 4 * fShadowSoftening;
+ float sh7 = (tex2D( sNormalMap, texSampleBase + inXY * 0.55 ).w - sh0 - 0.55 ) * 6 * fShadowSoftening;
+ float sh6 = (tex2D( sNormalMap, texSampleBase + inXY * 0.44 ).w - sh0 - 0.44 ) * 8 * fShadowSoftening;
+ float sh5 = (tex2D( sNormalMap, texSampleBase + inXY * 0.33 ).w - sh0 - 0.33 ) * 10 * fShadowSoftening;
+ float sh4 = (tex2D( sNormalMap, texSampleBase + inXY * 0.22 ).w - sh0 - 0.22 ) * 12 * fShadowSoftening;
+
+ // Compute the actual shadow strength:
+ float fShadow = 1 - max( max( max( max( max( max( shA, sh9 ), sh8 ), sh7 ), sh6 ), sh5 ), sh4 );
+
+ cResultColor.rgb *= fShadow * 0.6 + 0.4;
+ }
+#endif
+
+ return cResultColor;
+#endif
+}
+
+
+//======================================//
+// HSL Color space conversion routines //
+//======================================//
+
+#define HUE 0
+#define SATURATION 1
+#define LIGHTNESS 2
+
+// Convert from RGB to HSL color space
+float4 RGBtoHSL( float4 inColor )
+{
+ float h, s;
+ float flMax = max( inColor.r, max( inColor.g, inColor.b ) );
+ float flMin = min( inColor.r, min( inColor.g, inColor.b ) );
+
+ float l = (flMax + flMin) / 2.0f;
+
+ if (flMax == flMin) // achromatic case
+ {
+ s = h = 0;
+ }
+ else // chromatic case
+ {
+ // Next, calculate the hue
+ float delta = flMax - flMin;
+
+ // First, calculate the saturation
+ if (l < 0.5f) // If we're in the lower hexcone
+ {
+ s = delta/(flMax + flMin);
+ }
+ else
+ {
+ s = delta/(2 - flMax - flMin);
+ }
+
+ if ( inColor.r == flMax )
+ {
+ h = (inColor.g - inColor.b)/delta; // color between yellow and magenta
+ }
+ else if ( inColor.g == flMax )
+ {
+ h = 2 + (inColor.b - inColor.r)/delta; // color between cyan and yellow
+ }
+ else // blue must be max
+ {
+ h = 4 + (inColor.r - inColor.g)/delta; // color between magenta and cyan
+ }
+
+ h *= 60.0f;
+
+ if (h < 0.0f)
+ {
+ h += 360.0f;
+ }
+
+ h /= 360.0f;
+ }
+
+ return float4 (h, s, l, 1.0f);
+}
+
+float HueToRGB( float v1, float v2, float vH )
+{
+ float fResult = v1;
+
+ vH = fmod (vH + 1.0f, 1.0f);
+
+ if ( ( 6.0f * vH ) < 1.0f )
+ {
+ fResult = ( v1 + ( v2 - v1 ) * 6.0f * vH );
+ }
+ else if ( ( 2.0f * vH ) < 1.0f )
+ {
+ fResult = ( v2 );
+ }
+ else if ( ( 3.0f * vH ) < 2.0f )
+ {
+ fResult = ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3.0f ) - vH ) * 6.0f );
+ }
+
+ return fResult;
+}
+
+// Convert from HSL to RGB color space
+float4 HSLtoRGB( float4 hsl )
+{
+ float r, g, b;
+ float h = hsl[HUE];
+ float s = hsl[SATURATION];
+ float l = hsl[LIGHTNESS];
+
+ if ( s == 0 )
+ {
+ r = g = b = l;
+ }
+ else
+ {
+ float v1, v2;
+
+ if ( l < 0.5f )
+ v2 = l * ( 1.0f + s );
+ else
+ v2 = ( l + s ) - ( s * l );
+
+ v1 = 2 * l - v2;
+
+ r = HueToRGB( v1, v2, h + ( 1.0f / 3.0f ) );
+ g = HueToRGB( v1, v2, h );
+ b = HueToRGB( v1, v2, h - ( 1.0f / 3.0f ) );
+ }
+
+ return float4( r, g, b, 1.0f );
+}
+
+
+// texture combining modes for combining base and detail/basetexture2
+#define TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2 0 // original mode
+#define TCOMBINE_RGB_ADDITIVE 1 // base.rgb+detail.rgb*fblend
+#define TCOMBINE_DETAIL_OVER_BASE 2
+#define TCOMBINE_FADE 3 // straight fade between base and detail.
+#define TCOMBINE_BASE_OVER_DETAIL 4 // use base alpha for blend over detail
+#define TCOMBINE_RGB_ADDITIVE_SELFILLUM 5 // add detail color post lighting
+#define TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE 6
+#define TCOMBINE_MOD2X_SELECT_TWO_PATTERNS 7 // use alpha channel of base to select between mod2x channels in r+a of detail
+#define TCOMBINE_MULTIPLY 8
+#define TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA 9 // use alpha channel of detail to mask base
+#define TCOMBINE_SSBUMP_BUMP 10 // use detail to modulate lighting as an ssbump
+#define TCOMBINE_SSBUMP_NOBUMP 11 // detail is an ssbump but use it as an albedo. shader does the magic here - no user needs to specify mode 11
+
+float4 TextureCombine( float4 baseColor, float4 detailColor, int combine_mode,
+ float fBlendFactor )
+{
+ if ( combine_mode == TCOMBINE_MOD2X_SELECT_TWO_PATTERNS)
+ {
+ float3 dc=lerp(detailColor.r,detailColor.a, baseColor.a);
+ baseColor.rgb*=lerp(float3(1,1,1),2.0*dc,fBlendFactor);
+ }
+ if ( combine_mode == TCOMBINE_RGB_EQUALS_BASE_x_DETAILx2)
+ baseColor.rgb*=lerp(float3(1,1,1),2.0*detailColor.rgb,fBlendFactor);
+ if ( combine_mode == TCOMBINE_RGB_ADDITIVE )
+ baseColor.rgb += fBlendFactor * detailColor.rgb;
+ if ( combine_mode == TCOMBINE_DETAIL_OVER_BASE )
+ {
+ float fblend=fBlendFactor * detailColor.a;
+ baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend);
+ }
+ if ( combine_mode == TCOMBINE_FADE )
+ {
+ baseColor = lerp( baseColor, detailColor, fBlendFactor);
+ }
+ if ( combine_mode == TCOMBINE_BASE_OVER_DETAIL )
+ {
+ float fblend=fBlendFactor * (1-baseColor.a);
+ baseColor.rgb = lerp( baseColor.rgb, detailColor.rgb, fblend );
+ baseColor.a = detailColor.a;
+ }
+ if ( combine_mode == TCOMBINE_MULTIPLY )
+ {
+ baseColor = lerp( baseColor, baseColor*detailColor, fBlendFactor);
+ }
+
+ if (combine_mode == TCOMBINE_MASK_BASE_BY_DETAIL_ALPHA )
+ {
+ baseColor.a = lerp( baseColor.a, baseColor.a*detailColor.a, fBlendFactor );
+ }
+ if ( combine_mode == TCOMBINE_SSBUMP_NOBUMP )
+ {
+ baseColor.rgb = baseColor.rgb * dot( detailColor.rgb, 2.0/3.0 );
+ }
+ return baseColor;
+}
+
+float3 lerp5(float3 f1, float3 f2, float i1, float i2, float x)
+{
+ return f1+(f2-f1)*(x-i1)/(i2-i1);
+}
+
+float3 TextureCombinePostLighting( float3 lit_baseColor, float4 detailColor, int combine_mode,
+ float fBlendFactor )
+{
+ if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM )
+ lit_baseColor += fBlendFactor * detailColor.rgb;
+ if ( combine_mode == TCOMBINE_RGB_ADDITIVE_SELFILLUM_THRESHOLD_FADE )
+ {
+ // fade in an unusual way - instead of fading out color, remap an increasing band of it from
+ // 0..1
+ //if (fBlendFactor > 0.5)
+ // lit_baseColor += min(1, (1.0/fBlendFactor)*max(0, detailColor.rgb-(1-fBlendFactor) ) );
+ //else
+ // lit_baseColor += 2*fBlendFactor*2*max(0, detailColor.rgb-.5);
+
+ float f = fBlendFactor - 0.5;
+ float fMult = (f >= 0) ? 1.0/fBlendFactor : 4*fBlendFactor;
+ float fAdd = (f >= 0) ? 1.0-fMult : -0.5*fMult;
+ lit_baseColor += saturate(fMult * detailColor.rgb + fAdd);
+ }
+ return lit_baseColor;
+}
+
+//NOTE: On X360. fProjZ is expected to be pre-reversed for cheaper math here in the pixel shader
+float DepthFeathering( sampler DepthSampler, const float2 vScreenPos, float fProjZ, float fProjW, float4 vDepthBlendConstants )
+{
+# if ( !(defined(SHADER_MODEL_PS_1_1) || defined(SHADER_MODEL_PS_1_4) || defined(SHADER_MODEL_PS_2_0)) ) //minimum requirement of ps2b
+ {
+ float flFeatheredAlpha;
+ float2 flDepths;
+#define flSceneDepth flDepths.x
+#define flSpriteDepth flDepths.y
+
+# if ( defined( _X360 ) )
+ {
+ //Get depth from the depth texture. Need to sample with the offset of (0.5, 0.5) to fix rounding errors
+ asm {
+ tfetch2D flDepths.x___, vScreenPos, DepthSampler, OffsetX=0.5, OffsetY=0.5, MinFilter=point, MagFilter=point, MipFilter=point
+ };
+
+# if( !defined( REVERSE_DEPTH_ON_X360 ) )
+ flSceneDepth = 1.0f - flSceneDepth;
+# endif
+
+ //get the sprite depth into the same range as the texture depth
+ flSpriteDepth = fProjZ / fProjW;
+
+ //unproject to get at the pre-projection z. This value is much more linear than depth
+ flDepths = vDepthBlendConstants.z / flDepths;
+ flDepths = vDepthBlendConstants.y - flDepths;
+
+ flFeatheredAlpha = flSceneDepth - flSpriteDepth;
+ flFeatheredAlpha *= vDepthBlendConstants.x;
+ flFeatheredAlpha = saturate( flFeatheredAlpha );
+ }
+# else
+ {
+ flSceneDepth = tex2D( DepthSampler, vScreenPos ).a; // PC uses dest alpha of the frame buffer
+ flSpriteDepth = SoftParticleDepth( fProjZ );
+
+ flFeatheredAlpha = abs(flSceneDepth - flSpriteDepth) * vDepthBlendConstants.x;
+ flFeatheredAlpha = max( smoothstep( 0.75f, 1.0f, flSceneDepth ), flFeatheredAlpha ); //as the sprite approaches the edge of our compressed depth space, the math stops working. So as the sprite approaches the far depth, smoothly remove feathering.
+ flFeatheredAlpha = saturate( flFeatheredAlpha );
+ }
+# endif
+
+#undef flSceneDepth
+#undef flSpriteDepth
+
+ return flFeatheredAlpha;
+ }
+# else
+ {
+ return 1.0f;
+ }
+# endif
+}
+
+#endif //#ifndef COMMON_PS_FXC_H_
diff --git a/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h b/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h new file mode 100644 index 00000000..66cc642a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_vertexlitgeneric_dx9.h @@ -0,0 +1,423 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef COMMON_VERTEXLITGENERIC_DX9_H_
+#define COMMON_VERTEXLITGENERIC_DX9_H_
+
+#include "common_ps_fxc.h"
+
+// We store four light colors and positions in an
+// array of three of these structures like so:
+//
+// x y z w
+// +------+------+------+------+
+// | L0.rgb | |
+// +------+------+------+ |
+// | L0.pos | L3 |
+// +------+------+------+ rgb |
+// | L1.rgb | |
+// +------+------+------+------+
+// | L1.pos | |
+// +------+------+------+ |
+// | L2.rgb | L3 |
+// +------+------+------+ pos |
+// | L2.pos | |
+// +------+------+------+------+
+//
+struct PixelShaderLightInfo
+{
+ float4 color;
+ float4 pos;
+};
+
+#define cOverbright 2.0f
+#define cOOOverbright 0.5f
+
+#define LIGHTTYPE_NONE 0
+#define LIGHTTYPE_SPOT 1
+#define LIGHTTYPE_POINT 2
+#define LIGHTTYPE_DIRECTIONAL 3
+
+// Better suited to Pixel shader models, 11 instructions in pixel shader
+// ... actually, now only 9: mul, cmp, cmp, mul, mad, mad, mad, mad, mad
+float3 PixelShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] )
+{
+ float3 linearColor, nSquared = worldNormal * worldNormal;
+ float3 isNegative = ( worldNormal >= 0.0 ) ? 0 : nSquared;
+ float3 isPositive = ( worldNormal >= 0.0 ) ? nSquared : 0;
+ linearColor = isPositive.x * cAmbientCube[0] + isNegative.x * cAmbientCube[1] +
+ isPositive.y * cAmbientCube[2] + isNegative.y * cAmbientCube[3] +
+ isPositive.z * cAmbientCube[4] + isNegative.z * cAmbientCube[5];
+ return linearColor;
+}
+
+// Better suited to Vertex shader models
+// Six VS instructions due to use of constant indexing (slt, mova, mul, mul, mad, mad)
+float3 VertexShaderAmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] )
+{
+ float3 nSquared = worldNormal * worldNormal;
+ int3 isNegative = ( worldNormal < 0.0 );
+ float3 linearColor;
+ linearColor = nSquared.x * cAmbientCube[isNegative.x] +
+ nSquared.y * cAmbientCube[isNegative.y+2] +
+ nSquared.z * cAmbientCube[isNegative.z+4];
+ return linearColor;
+}
+
+float3 AmbientLight( const float3 worldNormal, const float3 cAmbientCube[6] )
+{
+ // Vertex shader cases
+#ifdef SHADER_MODEL_VS_1_0
+ return VertexShaderAmbientLight( worldNormal, cAmbientCube );
+#elif SHADER_MODEL_VS_1_1
+ return VertexShaderAmbientLight( worldNormal, cAmbientCube );
+#elif SHADER_MODEL_VS_2_0
+ return VertexShaderAmbientLight( worldNormal, cAmbientCube );
+#elif SHADER_MODEL_VS_3_0
+ return VertexShaderAmbientLight( worldNormal, cAmbientCube );
+#else
+ // Pixel shader case
+ return PixelShaderAmbientLight( worldNormal, cAmbientCube );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Compute scalar diffuse term with various optional tweaks such as
+// Half Lambert and ambient occlusion
+//-----------------------------------------------------------------------------
+float3 DiffuseTerm(const bool bHalfLambert, const float3 worldNormal, const float3 lightDir,
+ const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoLightingWarp, in sampler lightWarpSampler )
+{
+ float fResult;
+
+ float NDotL = dot( worldNormal, lightDir ); // Unsaturated dot (-1 to 1 range)
+
+ if ( bHalfLambert )
+ {
+ fResult = saturate(NDotL * 0.5 + 0.5); // Scale and bias to 0 to 1 range
+
+ if ( !bDoLightingWarp )
+ {
+ fResult *= fResult; // Square
+ }
+ }
+ else
+ {
+ fResult = saturate( NDotL ); // Saturate pure Lambertian term
+ }
+
+ if ( bDoAmbientOcclusion )
+ {
+ // Raise to higher powers for darker AO values
+// float fAOPower = lerp( 4.0f, 1.0f, fAmbientOcclusion );
+// result *= pow( NDotL * 0.5 + 0.5, fAOPower );
+ fResult *= fAmbientOcclusion;
+ }
+
+ float3 fOut = float3( fResult, fResult, fResult );
+ if ( bDoLightingWarp )
+ {
+ fOut = 2.0f * tex1D( lightWarpSampler, fResult );
+ }
+
+ return fOut;
+}
+
+float3 PixelShaderDoGeneralDiffuseLight( const float fAtten, const float3 worldPos, const float3 worldNormal,
+ in sampler NormalizeSampler,
+ const float3 vPosition, const float3 vColor, const bool bHalfLambert,
+ const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoLightingWarp, in sampler lightWarpSampler )
+{
+#if (defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0))
+ float3 lightDir = normalize( vPosition - worldPos );
+#else
+ float3 lightDir = NormalizeWithCubemap( NormalizeSampler, vPosition - worldPos );
+#endif
+ return vColor * fAtten * DiffuseTerm( bHalfLambert, worldNormal, lightDir, bDoAmbientOcclusion, fAmbientOcclusion, bDoLightingWarp, lightWarpSampler );
+}
+
+float3 PixelShaderGetLightVector( const float3 worldPos, PixelShaderLightInfo cLightInfo[3], int nLightIndex )
+{
+ if ( nLightIndex == 3 )
+ {
+ // Unpack light 3 from w components...
+ float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w );
+ return normalize( vLight3Pos - worldPos );
+ }
+ else
+ {
+ return normalize( cLightInfo[nLightIndex].pos - worldPos );
+ }
+}
+
+float3 PixelShaderGetLightColor( PixelShaderLightInfo cLightInfo[3], int nLightIndex )
+{
+ if ( nLightIndex == 3 )
+ {
+ // Unpack light 3 from w components...
+ return float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w );
+ }
+ else
+ {
+ return cLightInfo[nLightIndex].color.rgb;
+ }
+}
+
+
+void SpecularAndRimTerms( const float3 vWorldNormal, const float3 vLightDir, const float fSpecularExponent,
+ const float3 vEyeDir, const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoSpecularWarp, in sampler specularWarpSampler, const float fFresnel,
+ const float3 color, const bool bDoRimLighting, const float fRimExponent,
+
+ // Outputs
+ out float3 specularLighting, out float3 rimLighting )
+{
+ rimLighting = float3(0.0f, 0.0f, 0.0f);
+
+ //float3 vReflect = reflect( -vEyeDir, vWorldNormal ); // Reflect view through normal
+ float3 vReflect = 2 * vWorldNormal * dot( vWorldNormal , vEyeDir ) - vEyeDir; // Reflect view through normal
+ float LdotR = saturate(dot( vReflect, vLightDir )); // L.R (use half-angle instead?)
+ specularLighting = pow( LdotR, fSpecularExponent ); // Raise to specular exponent
+
+ // Optionally warp as function of scalar specular and fresnel
+ if ( bDoSpecularWarp )
+ specularLighting *= tex2D( specularWarpSampler, float2(specularLighting.x, fFresnel) ); // Sample at { (L.R)^k, fresnel }
+
+ specularLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L
+ specularLighting *= color; // Modulate with light color
+
+ if ( bDoAmbientOcclusion ) // Optionally modulate with ambient occlusion
+ specularLighting *= fAmbientOcclusion;
+
+ if ( bDoRimLighting ) // Optionally do rim lighting
+ {
+ rimLighting = pow( LdotR, fRimExponent ); // Raise to rim exponent
+ rimLighting *= saturate(dot( vWorldNormal, vLightDir )); // Mask with N.L
+ rimLighting *= color; // Modulate with light color
+ }
+}
+
+// Traditional fresnel term approximation
+float Fresnel( const float3 vNormal, const float3 vEyeDir )
+{
+ float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term
+ return fresnel * fresnel; // Square for a more subtle look
+}
+
+// Traditional fresnel term approximation which uses 4th power (square twice)
+float Fresnel4( const float3 vNormal, const float3 vEyeDir )
+{
+ float fresnel = saturate( 1 - dot( vNormal, vEyeDir ) ); // 1-(N.V) for Fresnel term
+ fresnel = fresnel * fresnel; // Square
+ return fresnel * fresnel; // Square again for a more subtle look
+}
+
+
+//
+// Custom Fresnel with low, mid and high parameters defining a piecewise continuous function
+// with traditional fresnel (0 to 1 range) as input. The 0 to 0.5 range blends between
+// low and mid while the 0.5 to 1 range blends between mid and high
+//
+// |
+// | . M . . . H
+// | .
+// L
+// |
+// +----------------
+// 0 1
+//
+float Fresnel( const float3 vNormal, const float3 vEyeDir, float3 vRanges )
+{
+ //float result, f = Fresnel( vNormal, vEyeDir ); // Traditional Fresnel
+ //if ( f > 0.5f )
+ // result = lerp( vRanges.y, vRanges.z, (2*f)-1 ); // Blend between mid and high values
+ //else
+ // result = lerp( vRanges.x, vRanges.y, 2*f ); // Blend between low and mid values
+
+ // note: vRanges is now encoded as ((mid-min)*2, mid, (max-mid)*2) to optimize math
+ float f = saturate( 1 - dot( vNormal, vEyeDir ) );
+ f = f*f - 0.5;
+ return vRanges.y + (f >= 0.0 ? vRanges.z : vRanges.x) * f;
+}
+
+void PixelShaderDoSpecularLight( const float3 vWorldPos, const float3 vWorldNormal, const float fSpecularExponent, const float3 vEyeDir,
+ const float fAtten, const float3 vLightColor, const float3 vLightDir,
+ const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel,
+ const bool bDoRimLighting, const float fRimExponent,
+
+ // Outputs
+ out float3 specularLighting, out float3 rimLighting )
+{
+ // Compute Specular and rim terms
+ SpecularAndRimTerms( vWorldNormal, vLightDir, fSpecularExponent,
+ vEyeDir, bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoSpecularWarp, specularWarpSampler, fFresnel, vLightColor * fAtten,
+ bDoRimLighting, fRimExponent, specularLighting, rimLighting );
+}
+
+float3 PixelShaderDoLightingLinear( const float3 worldPos, const float3 worldNormal,
+ const float3 staticLightingColor, const bool bStaticLight,
+ const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6],
+ in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3],
+ const bool bHalfLambert, const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoLightingWarp, in sampler lightWarpSampler )
+{
+ float3 linearColor = 0.0f;
+
+ if ( bStaticLight )
+ {
+ // The static lighting comes in in gamma space and has also been premultiplied by $cOOOverbright
+ // need to get it into
+ // linear space so that we can do adds.
+ linearColor += GammaToLinear( staticLightingColor * cOverbright );
+ }
+
+ if ( bAmbientLight )
+ {
+ float3 ambient = AmbientLight( worldNormal, cAmbientCube );
+
+ if ( bDoAmbientOcclusion )
+ ambient *= fAmbientOcclusion * fAmbientOcclusion; // Note squaring...
+
+ linearColor += ambient;
+ }
+
+ if ( nNumLights > 0 )
+ {
+ linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.x, worldPos, worldNormal, NormalizeSampler,
+ cLightInfo[0].pos, cLightInfo[0].color, bHalfLambert,
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoLightingWarp, lightWarpSampler );
+ if ( nNumLights > 1 )
+ {
+ linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.y, worldPos, worldNormal, NormalizeSampler,
+ cLightInfo[1].pos, cLightInfo[1].color, bHalfLambert,
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoLightingWarp, lightWarpSampler );
+ if ( nNumLights > 2 )
+ {
+ linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.z, worldPos, worldNormal, NormalizeSampler,
+ cLightInfo[2].pos, cLightInfo[2].color, bHalfLambert,
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoLightingWarp, lightWarpSampler );
+ if ( nNumLights > 3 )
+ {
+ // Unpack the 4th light's data from tight constant packing
+ float3 vLight3Color = float3( cLightInfo[0].color.w, cLightInfo[0].pos.w, cLightInfo[1].color.w );
+ float3 vLight3Pos = float3( cLightInfo[1].pos.w, cLightInfo[2].color.w, cLightInfo[2].pos.w );
+ linearColor += PixelShaderDoGeneralDiffuseLight( lightAtten.w, worldPos, worldNormal, NormalizeSampler,
+ vLight3Pos, vLight3Color, bHalfLambert,
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoLightingWarp, lightWarpSampler );
+ }
+ }
+ }
+ }
+
+ return linearColor;
+}
+
+void PixelShaderDoSpecularLighting( const float3 worldPos, const float3 worldNormal, const float fSpecularExponent, const float3 vEyeDir,
+ const float4 lightAtten, const int nNumLights, PixelShaderLightInfo cLightInfo[3],
+ const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoSpecularWarp, in sampler specularWarpSampler, float fFresnel,
+ const bool bDoRimLighting, const float fRimExponent,
+
+ // Outputs
+ out float3 specularLighting, out float3 rimLighting )
+{
+ specularLighting = rimLighting = float3( 0.0f, 0.0f, 0.0f );
+ float3 localSpecularTerm, localRimTerm;
+
+ if( nNumLights > 0 )
+ {
+ PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir,
+ lightAtten.x, PixelShaderGetLightColor( cLightInfo, 0 ),
+ PixelShaderGetLightVector( worldPos, cLightInfo, 0 ),
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoSpecularWarp, specularWarpSampler, fFresnel,
+ bDoRimLighting, fRimExponent,
+ localSpecularTerm, localRimTerm );
+
+ specularLighting += localSpecularTerm; // Accumulate specular and rim terms
+ rimLighting += localRimTerm;
+ }
+
+ if( nNumLights > 1 )
+ {
+ PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir,
+ lightAtten.y, PixelShaderGetLightColor( cLightInfo, 1 ),
+ PixelShaderGetLightVector( worldPos, cLightInfo, 1 ),
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoSpecularWarp, specularWarpSampler, fFresnel,
+ bDoRimLighting, fRimExponent,
+ localSpecularTerm, localRimTerm );
+
+ specularLighting += localSpecularTerm; // Accumulate specular and rim terms
+ rimLighting += localRimTerm;
+ }
+
+
+ if( nNumLights > 2 )
+ {
+ PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir,
+ lightAtten.z, PixelShaderGetLightColor( cLightInfo, 2 ),
+ PixelShaderGetLightVector( worldPos, cLightInfo, 2 ),
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoSpecularWarp, specularWarpSampler, fFresnel,
+ bDoRimLighting, fRimExponent,
+ localSpecularTerm, localRimTerm );
+
+ specularLighting += localSpecularTerm; // Accumulate specular and rim terms
+ rimLighting += localRimTerm;
+ }
+
+ if( nNumLights > 3 )
+ {
+ PixelShaderDoSpecularLight( worldPos, worldNormal, fSpecularExponent, vEyeDir,
+ lightAtten.w, PixelShaderGetLightColor( cLightInfo, 3 ),
+ PixelShaderGetLightVector( worldPos, cLightInfo, 3 ),
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoSpecularWarp, specularWarpSampler, fFresnel,
+ bDoRimLighting, fRimExponent,
+ localSpecularTerm, localRimTerm );
+
+ specularLighting += localSpecularTerm; // Accumulate specular and rim terms
+ rimLighting += localRimTerm;
+ }
+
+}
+
+float3 PixelShaderDoRimLighting( const float3 worldNormal, const float3 vEyeDir, const float3 cAmbientCube[6], float fFresnel )
+{
+ float3 vReflect = reflect( -vEyeDir, worldNormal ); // Reflect view through normal
+
+ return fFresnel * PixelShaderAmbientLight( vEyeDir, cAmbientCube );
+}
+
+// Called directly by newer shaders or through the following wrapper for older shaders
+float3 PixelShaderDoLighting( const float3 worldPos, const float3 worldNormal,
+ const float3 staticLightingColor, const bool bStaticLight,
+ const bool bAmbientLight, const float4 lightAtten, const float3 cAmbientCube[6],
+ in sampler NormalizeSampler, const int nNumLights, PixelShaderLightInfo cLightInfo[3],
+ const bool bHalfLambert,
+
+ // New optional/experimental parameters
+ const bool bDoAmbientOcclusion, const float fAmbientOcclusion,
+ const bool bDoLightingWarp, in sampler lightWarpSampler )
+{
+ float3 linearColor = PixelShaderDoLightingLinear( worldPos, worldNormal, staticLightingColor,
+ bStaticLight, bAmbientLight, lightAtten,
+ cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, bHalfLambert,
+ bDoAmbientOcclusion, fAmbientOcclusion,
+ bDoLightingWarp, lightWarpSampler );
+
+ // go ahead and clamp to the linear space equivalent of overbright 2 so that we match
+ // everything else.
+// linearColor = HuePreservingColorClamp( linearColor, pow( 2.0f, 2.2 ) );
+
+ return linearColor;
+}
+
+#endif //#ifndef COMMON_VERTEXLITGENERIC_DX9_H_
diff --git a/mp/src/materialsystem/stdshaders/common_vs_fxc.h b/mp/src/materialsystem/stdshaders/common_vs_fxc.h new file mode 100644 index 00000000..fe2e117a --- /dev/null +++ b/mp/src/materialsystem/stdshaders/common_vs_fxc.h @@ -0,0 +1,955 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This is where all common code for vertex shaders go.
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+
+
+
+#ifndef COMMON_VS_FXC_H_
+#define COMMON_VS_FXC_H_
+
+#include "common_fxc.h"
+
+// Put global skip commands here. . make sure and check that the appropriate vars are defined
+// so these aren't used on the wrong shaders!
+// --------------------------------------------------------------------------------
+// Ditch all fastpath attemps if we are doing LIGHTING_PREVIEW.
+// SKIP: defined $LIGHTING_PREVIEW && defined $FASTPATH && $LIGHTING_PREVIEW && $FASTPATH
+// --------------------------------------------------------------------------------
+
+
+#ifndef COMPRESSED_VERTS
+// Default to no vertex compression
+#define COMPRESSED_VERTS 0
+#endif
+
+#if ( !defined( SHADER_MODEL_VS_2_0 ) && !defined( SHADER_MODEL_VS_3_0 ) )
+#if COMPRESSED_VERTS == 1
+#error "Vertex compression is only for DX9 and up!"
+#endif
+#endif
+
+// We're testing 2 normal compression methods
+// One compressed normals+tangents into a SHORT2 each (8 bytes total)
+// The other compresses them together, into a single UBYTE4 (4 bytes total)
+// FIXME: pick one or the other, compare lighting quality in important cases
+#define COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 0
+#define COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 1
+//#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2
+#define COMPRESSED_NORMALS_TYPE COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4
+
+
+#define FOGTYPE_RANGE 0
+#define FOGTYPE_HEIGHT 1
+
+#define COMPILE_ERROR ( 1/0; )
+
+// -------------------------
+// CONSTANTS
+// -------------------------
+
+#pragma def ( vs, c0, 0.0f, 1.0f, 2.0f, 0.5f )
+
+const float4 cConstants1 : register(c1);
+#define cOOGamma cConstants1.x
+#define cOverbright 2.0f
+#define cOneThird cConstants1.z
+#define cOOOverbright ( 1.0f / 2.0f )
+
+
+// The g_bLightEnabled registers and g_nLightCountRegister hold the same information regarding
+// enabling lights, but callers internal to this file tend to use the loops, while external
+// callers will end up using the booleans
+const bool g_bLightEnabled[4] : register(b0);
+ // through b3
+
+const int g_nLightCountRegister : register(i0);
+
+
+#define g_nLightCount g_nLightCountRegister.x
+
+const float4 cEyePosWaterZ : register(c2);
+#define cEyePos cEyePosWaterZ.xyz
+
+// Only cFlexScale.x is used
+// It is a binary value used to switch on/off the addition of the flex delta stream
+const float4 cFlexScale : register( c3 );
+
+const float4x4 cModelViewProj : register(c4);
+const float4x4 cViewProj : register(c8);
+
+// Used to compute projPosZ in shaders without skinning
+// Using cModelViewProj with FastClip generates incorrect results
+// This is just row two of the non-FastClip cModelViewProj matrix
+const float4 cModelViewProjZ : register(c12);
+
+// More constants working back from the top...
+const float4 cViewProjZ : register(c13);
+
+const float4 cFogParams : register(c16);
+#define cFogEndOverFogRange cFogParams.x
+#define cFogOne cFogParams.y
+#define cFogMaxDensity cFogParams.z
+#define cOOFogRange cFogParams.w
+
+const float4x4 cViewModel : register(c17);
+
+const float3 cAmbientCubeX [ 2 ] : register ( c21 ) ;
+const float3 cAmbientCubeY [ 2 ] : register ( c23 ) ;
+const float3 cAmbientCubeZ [ 2 ] : register ( c25 ) ;
+
+#if defined ( SHADER_MODEL_VS_3_0 )
+const float4 cFlexWeights [ 512 ] : register ( c1024 ) ;
+#endif
+
+struct LightInfo
+{
+ float4 color; // {xyz} is color w is light type code (see comment below)
+ float4 dir; // {xyz} is dir w is light type code
+ float4 pos;
+ float4 spotParams;
+ float4 atten;
+};
+
+// w components of color and dir indicate light type:
+// 1x - directional
+// 01 - spot
+// 00 - point
+
+// Four lights x 5 constants each = 20 constants
+LightInfo cLightInfo[4] : register(c27);
+#define LIGHT_0_POSITION_REG c29
+
+#ifdef SHADER_MODEL_VS_1_1
+
+const float4 cModulationColor : register(c37);
+
+#define SHADER_SPECIFIC_CONST_0 c38
+#define SHADER_SPECIFIC_CONST_1 c39
+#define SHADER_SPECIFIC_CONST_2 c40
+#define SHADER_SPECIFIC_CONST_3 c41
+#define SHADER_SPECIFIC_CONST_4 c42
+#define SHADER_SPECIFIC_CONST_5 c43
+#define SHADER_SPECIFIC_CONST_6 c44
+#define SHADER_SPECIFIC_CONST_7 c45
+#define SHADER_SPECIFIC_CONST_8 c46
+#define SHADER_SPECIFIC_CONST_9 c47
+#define SHADER_SPECIFIC_CONST_10 c14
+#define SHADER_SPECIFIC_CONST_11 c15
+
+static const int cModel0Index = 48;
+const float4x3 cModel[16] : register(c48);
+// last cmodel is c105 for dx80, c214 for dx90
+
+#else // DX9 shaders (vs20 and beyond)
+
+const float4 cModulationColor : register( c47 );
+
+#define SHADER_SPECIFIC_CONST_0 c48
+#define SHADER_SPECIFIC_CONST_1 c49
+#define SHADER_SPECIFIC_CONST_2 c50
+#define SHADER_SPECIFIC_CONST_3 c51
+#define SHADER_SPECIFIC_CONST_4 c52
+#define SHADER_SPECIFIC_CONST_5 c53
+#define SHADER_SPECIFIC_CONST_6 c54
+#define SHADER_SPECIFIC_CONST_7 c55
+#define SHADER_SPECIFIC_CONST_8 c56
+#define SHADER_SPECIFIC_CONST_9 c57
+#define SHADER_SPECIFIC_CONST_10 c14
+#define SHADER_SPECIFIC_CONST_11 c15
+
+static const int cModel0Index = 58;
+const float4x3 cModel[53] : register( c58 );
+// last cmodel is c105 for dx80, c216 for dx90
+
+
+#define SHADER_SPECIFIC_BOOL_CONST_0 b4
+#define SHADER_SPECIFIC_BOOL_CONST_1 b5
+#define SHADER_SPECIFIC_BOOL_CONST_2 b6
+#define SHADER_SPECIFIC_BOOL_CONST_3 b7
+#define SHADER_SPECIFIC_BOOL_CONST_4 b8
+#define SHADER_SPECIFIC_BOOL_CONST_5 b9
+#define SHADER_SPECIFIC_BOOL_CONST_6 b10
+#define SHADER_SPECIFIC_BOOL_CONST_7 b11
+#endif // vertex shader model constant packing changes
+
+
+//=======================================================================================
+// Methods to decompress vertex normals
+//=======================================================================================
+
+//-----------------------------------------------------------------------------------
+// Decompress a normal from two-component compressed format
+// We expect this data to come from a signed SHORT2 stream in the range of -32768..32767
+//
+// -32678 and 0 are invalid encodings
+// w contains the sign to use in the cross product when generating a binormal
+void _DecompressShort2Tangent( float2 inputTangent, out float4 outputTangent )
+{
+ float2 ztSigns = sign( inputTangent ); // sign bits for z and tangent (+1 or -1)
+ float2 xyAbs = abs( inputTangent ); // 1..32767
+ outputTangent.xy = (xyAbs - 16384.0f) / 16384.0f; // x and y
+ outputTangent.z = ztSigns.x * sqrt( saturate( 1.0f - dot( outputTangent.xy, outputTangent.xy ) ) );
+ outputTangent.w = ztSigns.y;
+}
+
+//-----------------------------------------------------------------------------------
+// Same code as _DecompressShort2Tangent, just one returns a float4, one a float3
+void _DecompressShort2Normal( float2 inputNormal, out float3 outputNormal )
+{
+ float4 result;
+ _DecompressShort2Tangent( inputNormal, result );
+ outputNormal = result.xyz;
+}
+
+//-----------------------------------------------------------------------------------
+// Decompress normal+tangent together
+void _DecompressShort2NormalTangent( float2 inputNormal, float2 inputTangent, out float3 outputNormal, out float4 outputTangent )
+{
+ // FIXME: if we end up sticking with the SHORT2 format, pack the normal and tangent into a single SHORT4 element
+ // (that would make unpacking normal+tangent here together much cheaper than the sum of their parts)
+ _DecompressShort2Normal( inputNormal, outputNormal );
+ _DecompressShort2Tangent( inputTangent, outputTangent );
+}
+
+//=======================================================================================
+// Decompress a normal and tangent from four-component compressed format
+// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255
+// The final vTangent.w contains the sign to use in the cross product when generating a binormal
+void _DecompressUByte4NormalTangent( float4 inputNormal,
+ out float3 outputNormal, // {nX, nY, nZ}
+ out float4 outputTangent ) // {tX, tY, tZ, sign of binormal}
+{
+ float fOne = 1.0f;
+
+ float4 ztztSignBits = ( inputNormal - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction
+ float4 xyxyAbs = abs( inputNormal - 128.0f ) - ztztSignBits; // 0..127
+ float4 xyxySignBits = ( xyxyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0)
+ float4 normTan = (abs( xyxyAbs - 64.0f ) - xyxySignBits) / 63.0f; // abs({nX, nY, tX, tY})
+ outputNormal.xy = normTan.xy; // abs({nX, nY, __, __})
+ outputTangent.xy = normTan.zw; // abs({tX, tY, __, __})
+
+ float4 xyxySigns = 1 - 2*xyxySignBits; // Convert sign bits to signs
+ float4 ztztSigns = 1 - 2*ztztSignBits; // ( [1,0] -> [-1,+1] )
+
+ outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1
+ outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere
+ outputNormal.xy *= xyxySigns.xy; // Restore x and y signs
+ outputNormal.z *= ztztSigns.x; // Restore z sign
+
+ outputTangent.z = 1.0f - outputTangent.x - outputTangent.y; // Project onto x+y+z=1
+ outputTangent.xyz = normalize( outputTangent.xyz ); // Normalize onto unit sphere
+ outputTangent.xy *= xyxySigns.zw; // Restore x and y signs
+ outputTangent.z *= ztztSigns.z; // Restore z sign
+ outputTangent.w = ztztSigns.w; // Binormal sign
+}
+
+
+//-----------------------------------------------------------------------------------
+// Decompress just a normal from four-component compressed format (same as above)
+// We expect this data to come from an unsigned UBYTE4 stream in the range of 0..255
+// [ When compiled, this works out to approximately 17 asm instructions ]
+void _DecompressUByte4Normal( float4 inputNormal,
+ out float3 outputNormal) // {nX, nY, nZ}
+{
+ float fOne = 1.0f;
+
+ float2 ztSigns = ( inputNormal.xy - 128.0f ) < 0; // sign bits for zs and binormal (1 or 0) set-less-than (slt) asm instruction
+ float2 xyAbs = abs( inputNormal.xy - 128.0f ) - ztSigns; // 0..127
+ float2 xySigns = ( xyAbs - 64.0f ) < 0; // sign bits for xs and ys (1 or 0)
+ outputNormal.xy = ( abs( xyAbs - 64.0f ) - xySigns ) / 63.0f; // abs({nX, nY})
+
+ outputNormal.z = 1.0f - outputNormal.x - outputNormal.y; // Project onto x+y+z=1
+ outputNormal.xyz = normalize( outputNormal.xyz ); // Normalize onto unit sphere
+
+ outputNormal.xy *= lerp( fOne.xx, -fOne.xx, xySigns ); // Restore x and y signs
+ outputNormal.z *= lerp( fOne.x, -fOne.x, ztSigns.x ); // Restore z sign
+}
+
+
+void DecompressVertex_Normal( float4 inputNormal, out float3 outputNormal )
+{
+ if ( COMPRESSED_VERTS == 1 )
+ {
+ if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
+ {
+ _DecompressShort2Normal( inputNormal.xy, outputNormal );
+ }
+ else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
+ {
+ _DecompressUByte4Normal( inputNormal, outputNormal );
+ }
+ }
+ else
+ {
+ outputNormal = inputNormal.xyz;
+ }
+}
+
+void DecompressVertex_NormalTangent( float4 inputNormal, float4 inputTangent, out float3 outputNormal, out float4 outputTangent )
+{
+ if ( COMPRESSED_VERTS == 1 )
+ {
+ if ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_SEPARATETANGENTS_SHORT2 )
+ {
+ _DecompressShort2NormalTangent( inputNormal.xy, inputTangent.xy, outputNormal, outputTangent );
+ }
+ else // ( COMPRESSED_NORMALS_TYPE == COMPRESSED_NORMALS_COMBINEDTANGENTS_UBYTE4 )
+ {
+ _DecompressUByte4NormalTangent( inputNormal, outputNormal, outputTangent );
+ }
+ }
+ else
+ {
+ outputNormal = inputNormal.xyz;
+ outputTangent = inputTangent;
+ }
+}
+
+
+#ifdef SHADER_MODEL_VS_3_0
+
+//-----------------------------------------------------------------------------
+// Methods to sample morph data from a vertex texture
+// NOTE: vMorphTargetTextureDim.x = width, cVertexTextureDim.y = height, cVertexTextureDim.z = # of float4 fields per vertex
+// For position + normal morph for example, there will be 2 fields.
+//-----------------------------------------------------------------------------
+float4 SampleMorphDelta( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, const float flField )
+{
+ float flColumn = floor( flVertexID / vMorphSubrect.w );
+
+ float4 t;
+ t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + flField + 0.5f;
+ t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f;
+ t.xy /= vMorphTargetTextureDim.xy;
+ t.z = t.w = 0.f;
+
+ return tex2Dlod( vt, t );
+}
+
+// Optimized version which reads 2 deltas
+void SampleMorphDelta2( sampler2D vt, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect, const float flVertexID, out float4 delta1, out float4 delta2 )
+{
+ float flColumn = floor( flVertexID / vMorphSubrect.w );
+
+ float4 t;
+ t.x = vMorphSubrect.x + vMorphTargetTextureDim.z * flColumn + 0.5f;
+ t.y = vMorphSubrect.y + flVertexID - flColumn * vMorphSubrect.w + 0.5f;
+ t.xy /= vMorphTargetTextureDim.xy;
+ t.z = t.w = 0.f;
+
+ delta1 = tex2Dlod( vt, t );
+ t.x += 1.0f / vMorphTargetTextureDim.x;
+ delta2 = tex2Dlod( vt, t );
+}
+
+#endif // SHADER_MODEL_VS_3_0
+
+
+#if ( defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 ) )
+
+//-----------------------------------------------------------------------------
+// Method to apply morphs
+//-----------------------------------------------------------------------------
+bool ApplyMorph( float3 vPosFlex, inout float3 vPosition )
+{
+ // Flexes coming in from a separate stream
+ float3 vPosDelta = vPosFlex.xyz * cFlexScale.x;
+ vPosition.xyz += vPosDelta;
+ return true;
+}
+
+bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex, inout float3 vPosition, inout float3 vNormal )
+{
+ // Flexes coming in from a separate stream
+ float3 vPosDelta = vPosFlex.xyz * cFlexScale.x;
+ float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x;
+ vPosition.xyz += vPosDelta;
+ vNormal += vNormalDelta;
+ return true;
+}
+
+bool ApplyMorph( float3 vPosFlex, float3 vNormalFlex,
+ inout float3 vPosition, inout float3 vNormal, inout float3 vTangent )
+{
+ // Flexes coming in from a separate stream
+ float3 vPosDelta = vPosFlex.xyz * cFlexScale.x;
+ float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x;
+ vPosition.xyz += vPosDelta;
+ vNormal += vNormalDelta;
+ vTangent.xyz += vNormalDelta;
+ return true;
+}
+
+bool ApplyMorph( float4 vPosFlex, float3 vNormalFlex,
+ inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle )
+{
+ // Flexes coming in from a separate stream
+ float3 vPosDelta = vPosFlex.xyz * cFlexScale.x;
+ float3 vNormalDelta = vNormalFlex.xyz * cFlexScale.x;
+ flWrinkle = vPosFlex.w * cFlexScale.y;
+ vPosition.xyz += vPosDelta;
+ vNormal += vNormalDelta;
+ vTangent.xyz += vNormalDelta;
+ return true;
+}
+
+#endif // defined( SHADER_MODEL_VS_2_0 ) || defined( SHADER_MODEL_VS_3_0 )
+
+
+#ifdef SHADER_MODEL_VS_3_0
+
+bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect,
+ const float flVertexID, const float3 vMorphTexCoord,
+ inout float3 vPosition )
+{
+#if MORPHING
+
+#if !DECAL
+ // Flexes coming in from a separate stream
+ float4 vPosDelta = SampleMorphDelta( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, 0 );
+ vPosition += vPosDelta.xyz;
+#else
+ float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f );
+ float3 vPosDelta = tex2Dlod( morphSampler, t );
+ vPosition += vPosDelta.xyz * vMorphTexCoord.z;
+#endif // DECAL
+
+ return true;
+
+#else // !MORPHING
+ return false;
+#endif
+}
+
+bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect,
+ const float flVertexID, const float3 vMorphTexCoord,
+ inout float3 vPosition, inout float3 vNormal )
+{
+#if MORPHING
+
+#if !DECAL
+ float4 vPosDelta, vNormalDelta;
+ SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta );
+ vPosition += vPosDelta.xyz;
+ vNormal += vNormalDelta.xyz;
+#else
+ float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f );
+ float3 vPosDelta = tex2Dlod( morphSampler, t );
+ t.x += 1.0f / vMorphTargetTextureDim.x;
+ float3 vNormalDelta = tex2Dlod( morphSampler, t );
+ vPosition += vPosDelta.xyz * vMorphTexCoord.z;
+ vNormal += vNormalDelta.xyz * vMorphTexCoord.z;
+#endif // DECAL
+
+ return true;
+
+#else // !MORPHING
+ return false;
+#endif
+}
+
+bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect,
+ const float flVertexID, const float3 vMorphTexCoord,
+ inout float3 vPosition, inout float3 vNormal, inout float3 vTangent )
+{
+#if MORPHING
+
+#if !DECAL
+ float4 vPosDelta, vNormalDelta;
+ SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta );
+ vPosition += vPosDelta.xyz;
+ vNormal += vNormalDelta.xyz;
+ vTangent += vNormalDelta.xyz;
+#else
+ float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f );
+ float3 vPosDelta = tex2Dlod( morphSampler, t );
+ t.x += 1.0f / vMorphTargetTextureDim.x;
+ float3 vNormalDelta = tex2Dlod( morphSampler, t );
+ vPosition += vPosDelta.xyz * vMorphTexCoord.z;
+ vNormal += vNormalDelta.xyz * vMorphTexCoord.z;
+ vTangent += vNormalDelta.xyz * vMorphTexCoord.z;
+#endif // DECAL
+
+ return true;
+
+#else // MORPHING
+
+ return false;
+#endif
+}
+
+bool ApplyMorph( sampler2D morphSampler, const float3 vMorphTargetTextureDim, const float4 vMorphSubrect,
+ const float flVertexID, const float3 vMorphTexCoord,
+ inout float3 vPosition, inout float3 vNormal, inout float3 vTangent, out float flWrinkle )
+{
+#if MORPHING
+
+#if !DECAL
+ float4 vPosDelta, vNormalDelta;
+ SampleMorphDelta2( morphSampler, vMorphTargetTextureDim, vMorphSubrect, flVertexID, vPosDelta, vNormalDelta );
+ vPosition += vPosDelta.xyz;
+ vNormal += vNormalDelta.xyz;
+ vTangent += vNormalDelta.xyz;
+ flWrinkle = vPosDelta.w;
+#else
+ float4 t = float4( vMorphTexCoord.x, vMorphTexCoord.y, 0.0f, 0.0f );
+ float4 vPosDelta = tex2Dlod( morphSampler, t );
+ t.x += 1.0f / vMorphTargetTextureDim.x;
+ float3 vNormalDelta = tex2Dlod( morphSampler, t );
+
+ vPosition += vPosDelta.xyz * vMorphTexCoord.z;
+ vNormal += vNormalDelta.xyz * vMorphTexCoord.z;
+ vTangent += vNormalDelta.xyz * vMorphTexCoord.z;
+ flWrinkle = vPosDelta.w * vMorphTexCoord.z;
+#endif // DECAL
+
+ return true;
+
+#else // MORPHING
+
+ flWrinkle = 0.0f;
+ return false;
+
+#endif
+}
+
+#endif // SHADER_MODEL_VS_3_0
+
+
+float RangeFog( const float3 projPos )
+{
+ return max( cFogMaxDensity, ( -projPos.z * cOOFogRange + cFogEndOverFogRange ) );
+}
+
+float WaterFog( const float3 worldPos, const float3 projPos )
+{
+ float4 tmp;
+
+ tmp.xy = cEyePosWaterZ.wz - worldPos.z;
+
+ // tmp.x is the distance from the water surface to the vert
+ // tmp.y is the distance from the eye position to the vert
+
+ // if $tmp.x < 0, then set it to 0
+ // This is the equivalent of moving the vert to the water surface if it's above the water surface
+
+ tmp.x = max( 0.0f, tmp.x );
+
+ // $tmp.w = $tmp.x / $tmp.y
+ tmp.w = tmp.x / tmp.y;
+
+ tmp.w *= projPos.z;
+
+ // $tmp.w is now the distance that we see through water.
+
+ return max( cFogMaxDensity, ( -tmp.w * cOOFogRange + cFogOne ) );
+}
+
+float CalcFog( const float3 worldPos, const float3 projPos, const int fogType )
+{
+#if defined( _X360 )
+ // 360 only does pixel fog
+ return 1.0f;
+#endif
+
+ if( fogType == FOGTYPE_RANGE )
+ {
+ return RangeFog( projPos );
+ }
+ else
+ {
+#if SHADERMODEL_VS_2_0 == 1
+ // We do this work in the pixel shader in dx9, so don't do any fog here.
+ return 1.0f;
+#else
+ return WaterFog( worldPos, projPos );
+#endif
+ }
+}
+
+float CalcFog( const float3 worldPos, const float3 projPos, const bool bWaterFog )
+{
+#if defined( _X360 )
+ // 360 only does pixel fog
+ return 1.0f;
+#endif
+
+ float flFog;
+ if( !bWaterFog )
+ {
+ flFog = RangeFog( projPos );
+ }
+ else
+ {
+#if SHADERMODEL_VS_2_0 == 1
+ // We do this work in the pixel shader in dx9, so don't do any fog here.
+ flFog = 1.0f;
+#else
+ flFog = WaterFog( worldPos, projPos );
+#endif
+ }
+
+ return flFog;
+}
+
+float4 DecompressBoneWeights( const float4 weights )
+{
+ float4 result = weights;
+
+ if ( COMPRESSED_VERTS )
+ {
+ // Decompress from SHORT2 to float. In our case, [-1, +32767] -> [0, +1]
+ // NOTE: we add 1 here so we can divide by 32768 - which is exact (divide by 32767 is not).
+ // This avoids cracking between meshes with different numbers of bone weights.
+ // We use SHORT2 instead of SHORT2N for a similar reason - the GPU's conversion
+ // from [-32768,+32767] to [-1,+1] is imprecise in the same way.
+ result += 1;
+ result /= 32768;
+ }
+
+ return result;
+}
+
+void SkinPosition( bool bSkinning, const float4 modelPos,
+ const float4 boneWeights, float4 fBoneIndices,
+ out float3 worldPos )
+{
+#if !defined( _X360 )
+ int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );
+#else
+ int3 boneIndices = fBoneIndices;
+#endif
+
+ // Needed for invariance issues caused by multipass rendering
+#if defined( _X360 )
+ [isolate]
+#endif
+ {
+ if ( !bSkinning )
+ {
+ worldPos = mul4x3( modelPos, cModel[0] );
+ }
+ else // skinning - always three bones
+ {
+ float4x3 mat1 = cModel[boneIndices[0]];
+ float4x3 mat2 = cModel[boneIndices[1]];
+ float4x3 mat3 = cModel[boneIndices[2]];
+
+ float3 weights = DecompressBoneWeights( boneWeights ).xyz;
+ weights[2] = 1 - (weights[0] + weights[1]);
+
+ float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2];
+ worldPos = mul4x3( modelPos, blendMatrix );
+ }
+ }
+}
+
+void SkinPositionAndNormal( bool bSkinning, const float4 modelPos, const float3 modelNormal,
+ const float4 boneWeights, float4 fBoneIndices,
+ out float3 worldPos, out float3 worldNormal )
+{
+ // Needed for invariance issues caused by multipass rendering
+#if defined( _X360 )
+ [isolate]
+#endif
+ {
+
+#if !defined( _X360 )
+ int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );
+#else
+ int3 boneIndices = fBoneIndices;
+#endif
+
+ if ( !bSkinning )
+ {
+ worldPos = mul4x3( modelPos, cModel[0] );
+ worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] );
+ }
+ else // skinning - always three bones
+ {
+ float4x3 mat1 = cModel[boneIndices[0]];
+ float4x3 mat2 = cModel[boneIndices[1]];
+ float4x3 mat3 = cModel[boneIndices[2]];
+
+ float3 weights = DecompressBoneWeights( boneWeights ).xyz;
+ weights[2] = 1 - (weights[0] + weights[1]);
+
+ float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2];
+ worldPos = mul4x3( modelPos, blendMatrix );
+ worldNormal = mul3x3( modelNormal, ( float3x3 )blendMatrix );
+ }
+
+ } // end [isolate]
+}
+
+// Is it worth keeping SkinPosition and SkinPositionAndNormal around since the optimizer
+// gets rid of anything that isn't used?
+void SkinPositionNormalAndTangentSpace(
+ bool bSkinning,
+ const float4 modelPos, const float3 modelNormal,
+ const float4 modelTangentS,
+ const float4 boneWeights, float4 fBoneIndices,
+ out float3 worldPos, out float3 worldNormal,
+ out float3 worldTangentS, out float3 worldTangentT )
+{
+#if !defined( _X360 )
+ int3 boneIndices = D3DCOLORtoUBYTE4( fBoneIndices );
+#else
+ int3 boneIndices = fBoneIndices;
+#endif
+
+ // Needed for invariance issues caused by multipass rendering
+#if defined( _X360 )
+ [isolate]
+#endif
+ {
+ if ( !bSkinning )
+ {
+ worldPos = mul4x3( modelPos, cModel[0] );
+ worldNormal = mul3x3( modelNormal, ( const float3x3 )cModel[0] );
+ worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )cModel[0] );
+ }
+ else // skinning - always three bones
+ {
+ float4x3 mat1 = cModel[boneIndices[0]];
+ float4x3 mat2 = cModel[boneIndices[1]];
+ float4x3 mat3 = cModel[boneIndices[2]];
+
+ float3 weights = DecompressBoneWeights( boneWeights ).xyz;
+ weights[2] = 1 - (weights[0] + weights[1]);
+
+ float4x3 blendMatrix = mat1 * weights[0] + mat2 * weights[1] + mat3 * weights[2];
+ worldPos = mul4x3( modelPos, blendMatrix );
+ worldNormal = mul3x3( modelNormal, ( const float3x3 )blendMatrix );
+ worldTangentS = mul3x3( ( float3 )modelTangentS, ( const float3x3 )blendMatrix );
+ }
+ worldTangentT = cross( worldNormal, worldTangentS ) * modelTangentS.w;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Lighting helper functions
+//-----------------------------------------------------------------------------
+
+float3 AmbientLight( const float3 worldNormal )
+{
+ float3 nSquared = worldNormal * worldNormal;
+ int3 isNegative = ( worldNormal < 0.0 );
+ float3 linearColor;
+ linearColor = nSquared.x * cAmbientCubeX[isNegative.x] +
+ nSquared.y * cAmbientCubeY[isNegative.y] +
+ nSquared.z * cAmbientCubeZ[isNegative.z];
+ return linearColor;
+}
+
+// The following "internal" routines are called "privately" by other routines in this file which
+// handle the particular flavor of vs20 control flow appropriate to the original caller
+float VertexAttenInternal( const float3 worldPos, int lightNum )
+{
+ float result = 0.0f;
+
+ // Get light direction
+ float3 lightDir = cLightInfo[lightNum].pos - worldPos;
+
+ // Get light distance squared.
+ float lightDistSquared = dot( lightDir, lightDir );
+
+ // Get 1/lightDistance
+ float ooLightDist = rsqrt( lightDistSquared );
+
+ // Normalize light direction
+ lightDir *= ooLightDist;
+
+ float3 vDist;
+# if defined( _X360 )
+ {
+ //X360 dynamic compile hits an internal compiler error using dst(), this is the breakdown of how dst() works from the 360 docs.
+ vDist.x = 1;
+ vDist.y = lightDistSquared * ooLightDist;
+ vDist.z = lightDistSquared;
+ //flDist.w = ooLightDist;
+ }
+# else
+ {
+ vDist = dst( lightDistSquared, ooLightDist );
+ }
+# endif
+
+ float flDistanceAtten = 1.0f / dot( cLightInfo[lightNum].atten.xyz, vDist );
+
+ // Spot attenuation
+ float flCosTheta = dot( cLightInfo[lightNum].dir.xyz, -lightDir );
+ float flSpotAtten = (flCosTheta - cLightInfo[lightNum].spotParams.z) * cLightInfo[lightNum].spotParams.w;
+ flSpotAtten = max( 0.0001f, flSpotAtten );
+ flSpotAtten = pow( flSpotAtten, cLightInfo[lightNum].spotParams.x );
+ flSpotAtten = saturate( flSpotAtten );
+
+ // Select between point and spot
+ float flAtten = lerp( flDistanceAtten, flDistanceAtten * flSpotAtten, cLightInfo[lightNum].dir.w );
+
+ // Select between above and directional (no attenuation)
+ result = lerp( flAtten, 1.0f, cLightInfo[lightNum].color.w );
+
+ return result;
+}
+
+float CosineTermInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert )
+{
+ // Calculate light direction assuming this is a point or spot
+ float3 lightDir = normalize( cLightInfo[lightNum].pos - worldPos );
+
+ // Select the above direction or the one in the structure, based upon light type
+ lightDir = lerp( lightDir, -cLightInfo[lightNum].dir, cLightInfo[lightNum].color.w );
+
+ // compute N dot L
+ float NDotL = dot( worldNormal, lightDir );
+
+ if ( !bHalfLambert )
+ {
+ NDotL = max( 0.0f, NDotL );
+ }
+ else // Half-Lambert
+ {
+ NDotL = NDotL * 0.5 + 0.5;
+ NDotL = NDotL * NDotL;
+ }
+ return NDotL;
+}
+
+// This routine uses booleans to do early-outs and is meant to be called by routines OUTSIDE of this file
+float GetVertexAttenForLight( const float3 worldPos, int lightNum, bool bUseStaticControlFlow )
+{
+ float result = 0.0f;
+
+ // Direct3D uses static control flow but OpenGL currently does not
+ if ( bUseStaticControlFlow )
+ {
+ if ( g_bLightEnabled[lightNum] )
+ {
+ result = VertexAttenInternal( worldPos, lightNum );
+ }
+ }
+ else // OpenGL non-static-control-flow path
+ {
+ result = VertexAttenInternal( worldPos, lightNum );
+ }
+
+ return result;
+}
+
+float3 DoLightInternal( const float3 worldPos, const float3 worldNormal, int lightNum, bool bHalfLambert )
+{
+ return cLightInfo[lightNum].color *
+ CosineTermInternal( worldPos, worldNormal, lightNum, bHalfLambert ) *
+ VertexAttenInternal( worldPos, lightNum );
+}
+
+float3 DoLighting( const float3 worldPos, const float3 worldNormal,
+ const float3 staticLightingColor, const bool bStaticLight,
+ const bool bDynamicLight, bool bHalfLambert )
+{
+ float3 linearColor = float3( 0.0f, 0.0f, 0.0f );
+
+ if( bStaticLight ) // Static light
+ {
+ float3 col = staticLightingColor * cOverbright;
+#if defined ( _X360 )
+ linearColor += col * col;
+#else
+ linearColor += GammaToLinear( col );
+#endif
+ }
+
+ if( bDynamicLight ) // Dynamic light
+ {
+ for (int i = 0; i < g_nLightCount; i++)
+ {
+ linearColor += DoLightInternal( worldPos, worldNormal, i, bHalfLambert );
+ }
+ }
+
+ if( bDynamicLight )
+ {
+ linearColor += AmbientLight( worldNormal ); //ambient light is already remapped
+ }
+
+ return linearColor;
+}
+
+float3 DoLightingUnrolled( const float3 worldPos, const float3 worldNormal,
+ const float3 staticLightingColor, const bool bStaticLight,
+ const bool bDynamicLight, bool bHalfLambert, const int nNumLights )
+{
+ float3 linearColor = float3( 0.0f, 0.0f, 0.0f );
+
+ if( bStaticLight ) // Static light
+ {
+ linearColor += GammaToLinear( staticLightingColor * cOverbright );
+ }
+
+ if( bDynamicLight ) // Ambient light
+ {
+ if ( nNumLights >= 1 )
+ linearColor += DoLightInternal( worldPos, worldNormal, 0, bHalfLambert );
+ if ( nNumLights >= 2 )
+ linearColor += DoLightInternal( worldPos, worldNormal, 1, bHalfLambert );
+ if ( nNumLights >= 3 )
+ linearColor += DoLightInternal( worldPos, worldNormal, 2, bHalfLambert );
+ if ( nNumLights >= 4 )
+ linearColor += DoLightInternal( worldPos, worldNormal, 3, bHalfLambert );
+ }
+
+ if( bDynamicLight )
+ {
+ linearColor += AmbientLight( worldNormal ); //ambient light is already remapped
+ }
+
+ return linearColor;
+}
+
+int4 FloatToInt( in float4 floats )
+{
+ return D3DCOLORtoUBYTE4( floats.zyxw / 255.001953125 );
+}
+
+float2 ComputeSphereMapTexCoords( in float3 reflectionVector )
+{
+ // transform reflection vector into view space
+ reflectionVector = mul( reflectionVector, ( float3x3 )cViewModel );
+
+ // generate <rx ry rz+1>
+ float3 tmp = float3( reflectionVector.x, reflectionVector.y, reflectionVector.z + 1.0f );
+
+ // find 1 / len
+ float ooLen = dot( tmp, tmp );
+ ooLen = 1.0f / sqrt( ooLen );
+
+ // tmp = tmp/|tmp| + 1
+ tmp.xy = ooLen * tmp.xy + 1.0f;
+
+ return tmp.xy * 0.5f;
+}
+
+
+#define DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE 1
+ // minxyz.minsoftness / maxxyz.maxsoftness
+float3 ApplyDeformation( float3 worldpos, int deftype, float4 defparms0, float4 defparms1,
+ float4 defparms2, float4 defparms3 )
+{
+ float3 ret = worldpos;
+ if ( deftype == DEFORMATION_CLAMP_TO_BOX_IN_WORLDSPACE )
+ {
+ ret=max( ret, defparms2.xyz );
+ ret=min( ret, defparms3.xyz );
+ }
+
+ return ret;
+}
+
+
+#endif //#ifndef COMMON_VS_FXC_H_
diff --git a/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h b/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h new file mode 100644 index 00000000..b448b048 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/cpp_shader_constant_register_map.h @@ -0,0 +1,45 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Provide convenient mapping for shader constants
+//
+// $NoKeywords: $
+//=============================================================================
+
+#define C_CODE_HACK
+#include "shader_constant_register_map.h"
+#undef C_CODE_HACK
+
+// For the C code, map the above file's defines back to integers...
+#define PSREG_CONSTANT_00 0
+#define PSREG_CONSTANT_01 1
+#define PSREG_CONSTANT_02 2
+#define PSREG_CONSTANT_03 3
+#define PSREG_CONSTANT_04 4
+#define PSREG_CONSTANT_05 5
+#define PSREG_CONSTANT_06 6
+#define PSREG_CONSTANT_07 7
+#define PSREG_CONSTANT_08 8
+#define PSREG_CONSTANT_09 9
+#define PSREG_CONSTANT_10 10
+#define PSREG_CONSTANT_11 11
+#define PSREG_CONSTANT_12 12
+#define PSREG_CONSTANT_13 13
+#define PSREG_CONSTANT_14 14
+#define PSREG_CONSTANT_15 15
+#define PSREG_CONSTANT_16 16
+#define PSREG_CONSTANT_17 17
+#define PSREG_CONSTANT_18 18
+#define PSREG_CONSTANT_19 19
+#define PSREG_CONSTANT_20 20
+#define PSREG_CONSTANT_21 21
+#define PSREG_CONSTANT_22 22
+#define PSREG_CONSTANT_23 23
+#define PSREG_CONSTANT_24 24
+#define PSREG_CONSTANT_25 25
+#define PSREG_CONSTANT_26 26
+#define PSREG_CONSTANT_27 27
+#define PSREG_CONSTANT_28 28
+#define PSREG_CONSTANT_29 29
+#define PSREG_CONSTANT_30 30
+#define PSREG_CONSTANT_31 31
+
diff --git a/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp b/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp new file mode 100644 index 00000000..9ee2659c --- /dev/null +++ b/mp/src/materialsystem/stdshaders/dx8fallbacks.cpp @@ -0,0 +1,11 @@ +#include "BaseVSShader.h"
+
+// This one isn't supported on dx8
+DEFINE_FALLBACK_SHADER( SDK_DepthWrite, Wireframe )
+
+DEFINE_FALLBACK_SHADER( SDK_EyeRefract, Eyes_dx8 )
+DEFINE_FALLBACK_SHADER( SDK_VolumeClouds, UnlitGeneric_DX8 )
+
+// FIXME: These aren't supported on dx8, but need to be.
+DEFINE_FALLBACK_SHADER( SDK_EyeGlint, EyeGlint )
+DEFINE_FALLBACK_SHADER( SDK_AfterShock, AfterShock )
diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9.cpp b/mp/src/materialsystem/stdshaders/example_model_dx9.cpp new file mode 100644 index 00000000..87e012e3 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/example_model_dx9.cpp @@ -0,0 +1,60 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
+//
+// Example shader that can be applied to models
+//
+//==================================================================================================
+
+#include "BaseVSShader.h"
+#include "convar.h"
+#include "example_model_dx9_helper.h"
+
+#ifdef GAME_SHADER_DLL
+DEFINE_FALLBACK_SHADER( Mod_Example_Model, Mod_Example_Model_DX9 )
+BEGIN_VS_SHADER( Mod_Example_Model_DX9, "Help for Example Model Shader" )
+#else
+DEFINE_FALLBACK_SHADER( Example_Model, Example_Model_DX9 )
+BEGIN_VS_SHADER( Example_Model_DX9, "Help for Example Model Shader" )
+#endif
+
+ BEGIN_SHADER_PARAMS
+ SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
+ END_SHADER_PARAMS
+
+ void SetupVars( ExampleModel_DX9_Vars_t& info )
+ {
+ info.m_nBaseTexture = BASETEXTURE;
+ info.m_nBaseTextureFrame = FRAME;
+ info.m_nBaseTextureTransform = BASETEXTURETRANSFORM;
+ info.m_nAlphaTestReference = ALPHATESTREFERENCE;
+ info.m_nFlashlightTexture = FLASHLIGHTTEXTURE;
+ info.m_nFlashlightTextureFrame = FLASHLIGHTTEXTUREFRAME;
+ }
+
+ SHADER_INIT_PARAMS()
+ {
+ ExampleModel_DX9_Vars_t info;
+ SetupVars( info );
+ InitParamsExampleModel_DX9( this, params, pMaterialName, info );
+ }
+
+ SHADER_FALLBACK
+ {
+ return 0;
+ }
+
+ SHADER_INIT
+ {
+ ExampleModel_DX9_Vars_t info;
+ SetupVars( info );
+ InitExampleModel_DX9( this, params, info );
+ }
+
+ SHADER_DRAW
+ {
+ ExampleModel_DX9_Vars_t info;
+ SetupVars( info );
+ DrawExampleModel_DX9( this, params, pShaderAPI, pShaderShadow, info, vertexCompression, pContextDataPtr );
+ }
+
+END_SHADER
+
diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp new file mode 100644 index 00000000..471b9f80 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.cpp @@ -0,0 +1,341 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+#include "BaseVSShader.h"
+#include "example_model_dx9_helper.h"
+#include "convar.h"
+#include "cpp_shader_constant_register_map.h"
+#include "example_model_vs20.inc"
+#include "example_model_ps20b.inc"
+#include "commandbuilder.h"
+
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+static ConVar mat_fullbright( "mat_fullbright", "0", FCVAR_CHEAT );
+static ConVar r_lightwarpidentity( "r_lightwarpidentity", "0", FCVAR_CHEAT );
+static ConVar r_rimlight( "r_rimlight", "1", FCVAR_CHEAT );
+
+// Textures may be bound to the following samplers:
+// SHADER_SAMPLER0 Base (Albedo) / Gloss in alpha
+// SHADER_SAMPLER4 Flashlight Shadow Depth Map
+// SHADER_SAMPLER5 Normalization cube map
+// SHADER_SAMPLER6 Flashlight Cookie
+
+
+//-----------------------------------------------------------------------------
+// Initialize shader parameters
+//-----------------------------------------------------------------------------
+void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, const char *pMaterialName, ExampleModel_DX9_Vars_t &info )
+{
+ // FLASHLIGHTFIXME: Do ShaderAPI::BindFlashlightTexture
+ Assert( info.m_nFlashlightTexture >= 0 );
+
+ if ( g_pHardwareConfig->SupportsBorderColor() )
+ {
+ params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight_border" );
+ }
+ else
+ {
+ params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" );
+ }
+
+ // This shader can be used with hw skinning
+ SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
+ SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
+}
+
+//-----------------------------------------------------------------------------
+// Initialize shader
+//-----------------------------------------------------------------------------
+void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, ExampleModel_DX9_Vars_t &info )
+{
+ Assert( info.m_nFlashlightTexture >= 0 );
+ pShader->LoadTexture( info.m_nFlashlightTexture, TEXTUREFLAGS_SRGB );
+
+ bool bIsBaseTextureTranslucent = false;
+ if ( params[info.m_nBaseTexture]->IsDefined() )
+ {
+ pShader->LoadTexture( info.m_nBaseTexture, TEXTUREFLAGS_SRGB );
+
+ if ( params[info.m_nBaseTexture]->GetTextureValue()->IsTranslucent() )
+ {
+ bIsBaseTextureTranslucent = true;
+ }
+ }
+}
+
+class CExampleModel_DX9_Context : public CBasePerMaterialContextData
+{
+public:
+ CCommandBufferBuilder< CFixedCommandStorageBuffer< 800 > > m_SemiStaticCmdsOut;
+ bool m_bFastPath;
+
+};
+
+//-----------------------------------------------------------------------------
+// Draws the shader
+//-----------------------------------------------------------------------------
+void DrawExampleModel_DX9_Internal( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
+ bool bHasFlashlight, ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
+ CBasePerMaterialContextData **pContextDataPtr )
+{
+ bool bHasBaseTexture = (info.m_nBaseTexture != -1) && params[info.m_nBaseTexture]->IsTexture();
+ bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0;
+
+ BlendType_t nBlendType= pShader->EvaluateBlendRequirements( info.m_nBaseTexture, true );
+ bool bFullyOpaque = ( nBlendType != BT_BLENDADD ) && ( nBlendType != BT_BLEND ) && !bIsAlphaTested && !bHasFlashlight;
+
+ CExampleModel_DX9_Context *pContextData = reinterpret_cast< CExampleModel_DX9_Context *> ( *pContextDataPtr );
+ if ( !pContextData )
+ {
+ pContextData = new CExampleModel_DX9_Context;
+ *pContextDataPtr = pContextData;
+ }
+
+ if( pShader->IsSnapshotting() )
+ {
+ pShaderShadow->EnableAlphaTest( bIsAlphaTested );
+
+ if( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f )
+ {
+ pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() );
+ }
+
+ int nShadowFilterMode = 0;
+ if( bHasFlashlight )
+ {
+ if (params[info.m_nBaseTexture]->IsTexture())
+ {
+ pShader->SetAdditiveBlendingShadowState( info.m_nBaseTexture, true );
+ }
+
+ if( bIsAlphaTested )
+ {
+ // disable alpha test and use the zfunc zequals since alpha isn't guaranteed to
+ // be the same on both the regular pass and the flashlight pass.
+ pShaderShadow->EnableAlphaTest( false );
+ pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL );
+ }
+ pShaderShadow->EnableBlending( true );
+ pShaderShadow->EnableDepthWrites( false );
+
+ // Be sure not to write to dest alpha
+ pShaderShadow->EnableAlphaWrites( false );
+
+ nShadowFilterMode = g_pHardwareConfig->GetShadowFilterMode(); // Based upon vendor and device dependent formats
+ }
+ else // not flashlight pass
+ {
+ if (params[info.m_nBaseTexture]->IsTexture())
+ {
+ pShader->SetDefaultBlendingShadowState( info.m_nBaseTexture, true );
+ }
+ }
+
+ unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL;
+ int userDataSize = 0;
+
+ // Always enable...will bind white if nothing specified...
+ pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); // Base (albedo) map
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true );
+
+ if( bHasFlashlight )
+ {
+ pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); // Shadow depth map
+ pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER4 );
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, false );
+ pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Noise map
+ pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); // Flashlight cookie
+ pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, true );
+ userDataSize = 4; // tangent S
+ }
+
+ // Always enable, since flat normal will be bound
+ pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); // Normal map
+ userDataSize = 4; // tangent S
+ pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); // Normalizing cube map
+ pShaderShadow->EnableSRGBWrite( true );
+
+ // texcoord0 : base texcoord, texcoord2 : decal hw morph delta
+ int pTexCoordDim[3] = { 2, 0, 3 };
+ int nTexCoordCount = 1;
+
+ // This shader supports compressed vertices, so OR in that flag:
+ flags |= VERTEX_FORMAT_COMPRESSED;
+
+ pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, pTexCoordDim, userDataSize );
+
+ DECLARE_STATIC_VERTEX_SHADER( example_model_vs20 );
+ SET_STATIC_VERTEX_SHADER( example_model_vs20 );
+
+ // Assume we're only going to get in here if we support 2b
+ DECLARE_STATIC_PIXEL_SHADER( example_model_ps20b );
+ SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHT, bHasFlashlight );
+ SET_STATIC_PIXEL_SHADER_COMBO( FLASHLIGHTDEPTHFILTERMODE, nShadowFilterMode );
+ SET_STATIC_PIXEL_SHADER_COMBO( CONVERT_TO_SRGB, 0 );
+ SET_STATIC_PIXEL_SHADER( example_model_ps20b );
+
+ if( bHasFlashlight )
+ {
+ pShader->FogToBlack();
+ }
+ else
+ {
+ pShader->DefaultFog();
+ }
+
+ // HACK HACK HACK - enable alpha writes all the time so that we have them for underwater stuff
+ pShaderShadow->EnableAlphaWrites( bFullyOpaque );
+ }
+ else // not snapshotting -- begin dynamic state
+ {
+ bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
+
+ if( bHasBaseTexture )
+ {
+ pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame );
+ }
+ else
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE );
+ }
+
+ LightState_t lightState = { 0, false, false };
+ bool bFlashlightShadows = false;
+ if( bHasFlashlight )
+ {
+ Assert( info.m_nFlashlightTexture >= 0 && info.m_nFlashlightTextureFrame >= 0 );
+ pShader->BindTexture( SHADER_SAMPLER6, info.m_nFlashlightTexture, info.m_nFlashlightTextureFrame );
+ VMatrix worldToTexture;
+ ITexture *pFlashlightDepthTexture;
+ FlashlightState_t state = pShaderAPI->GetFlashlightStateEx( worldToTexture, &pFlashlightDepthTexture );
+ bFlashlightShadows = state.m_bEnableShadows && ( pFlashlightDepthTexture != NULL );
+
+ SetFlashLightColorFromState( state, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
+
+ if( pFlashlightDepthTexture && g_pConfig->ShadowDepthTexture() && state.m_bEnableShadows )
+ {
+ pShader->BindTexture( SHADER_SAMPLER4, pFlashlightDepthTexture, 0 );
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SHADOW_NOISE_2D );
+ }
+ }
+ else // no flashlight
+ {
+ pShaderAPI->GetDX9LightState( &lightState );
+ }
+
+ MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode();
+ int fogIndex = ( fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ) ? 1 : 0;
+ int numBones = pShaderAPI->GetCurrentNumBones();
+
+ bool bWriteDepthToAlpha = false;
+ bool bWriteWaterFogToAlpha = false;
+ if( bFullyOpaque )
+ {
+ bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha();
+ bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
+ AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
+ }
+
+ DECLARE_DYNAMIC_VERTEX_SHADER( example_model_vs20 );
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, fogIndex );
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, numBones > 0 );
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, pShaderAPI->GetIntRenderingParameter(INT_RENDERPARM_ENABLE_FIXED_LIGHTING)!=0);
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression );
+ SET_DYNAMIC_VERTEX_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
+ SET_DYNAMIC_VERTEX_SHADER( example_model_vs20 );
+
+ DECLARE_DYNAMIC_PIXEL_SHADER( example_model_ps20b );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( NUM_LIGHTS, lightState.m_nNumLights );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() );
+ SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows );
+ SET_DYNAMIC_PIXEL_SHADER( example_model_ps20b );
+
+ pShader->SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
+ pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 );
+ pShader->SetAmbientCubeDynamicStateVertexShader();
+
+ if( !bHasFlashlight )
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALIZATION_CUBEMAP_SIGNED );
+ }
+
+ pShaderAPI->SetPixelShaderStateAmbientLightCube( PSREG_AMBIENT_CUBE, !lightState.m_bAmbientLight ); // Force to black if not bAmbientLight
+ pShaderAPI->CommitPixelShaderLighting( PSREG_LIGHT_INFO_ARRAY );
+
+ // handle mat_fullbright 2 (diffuse lighting only)
+ if( bLightingOnly )
+ {
+ pShaderAPI->BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY );
+ }
+
+ pShaderAPI->SetPixelShaderFogParams( PSREG_FOG_PARAMS );
+
+ if( bHasFlashlight )
+ {
+ VMatrix worldToTexture;
+ float atten[4], pos[4], tweaks[4];
+
+ const FlashlightState_t &flashlightState = pShaderAPI->GetFlashlightState( worldToTexture );
+ SetFlashLightColorFromState( flashlightState, pShaderAPI, PSREG_FLASHLIGHT_COLOR );
+
+ pShader->BindTexture( SHADER_SAMPLER6, flashlightState.m_pSpotlightTexture, flashlightState.m_nSpotlightTextureFrame );
+
+ atten[0] = flashlightState.m_fConstantAtten; // Set the flashlight attenuation factors
+ atten[1] = flashlightState.m_fLinearAtten;
+ atten[2] = flashlightState.m_fQuadraticAtten;
+ atten[3] = flashlightState.m_FarZ;
+ pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_ATTENUATION, atten, 1 );
+
+ pos[0] = flashlightState.m_vecLightOrigin[0]; // Set the flashlight origin
+ pos[1] = flashlightState.m_vecLightOrigin[1];
+ pos[2] = flashlightState.m_vecLightOrigin[2];
+ pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_POSITION_RIM_BOOST, pos, 1 );
+
+ pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE, worldToTexture.Base(), 4 );
+
+ // Tweaks associated with a given flashlight
+ tweaks[0] = ShadowFilterFromState( flashlightState );
+ tweaks[1] = ShadowAttenFromState( flashlightState );
+ pShader->HashShadow2DJitter( flashlightState.m_flShadowJitterSeed, &tweaks[2], &tweaks[3] );
+ pShaderAPI->SetPixelShaderConstant( PSREG_ENVMAP_TINT__SHADOW_TWEAKS, tweaks, 1 );
+
+ // Dimensions of screen, used for screen-space noise map sampling
+ float vScreenScale[4] = {1280.0f / 32.0f, 720.0f / 32.0f, 0, 0};
+ int nWidth, nHeight;
+ pShaderAPI->GetBackBufferDimensions( nWidth, nHeight );
+ vScreenScale[0] = (float) nWidth / 32.0f;
+ vScreenScale[1] = (float) nHeight / 32.0f;
+ pShaderAPI->SetPixelShaderConstant( PSREG_FLASHLIGHT_SCREEN_SCALE, vScreenScale, 1 );
+ }
+ }
+ pShader->Draw();
+}
+
+
+//-----------------------------------------------------------------------------
+// Draws the shader
+//-----------------------------------------------------------------------------
+void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
+ ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData **pContextDataPtr )
+
+{
+ bool bHasFlashlight = pShader->UsingFlashlight( params );
+ if ( bHasFlashlight )
+ {
+ DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, false, info, vertexCompression, pContextDataPtr++ );
+ if ( pShaderShadow )
+ {
+ pShader->SetInitialShadowState( );
+ }
+ }
+ DrawExampleModel_DX9_Internal( pShader, params, pShaderAPI, pShaderShadow, bHasFlashlight, info, vertexCompression, pContextDataPtr );
+}
diff --git a/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h new file mode 100644 index 00000000..3b82e71f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/example_model_dx9_helper.h @@ -0,0 +1,46 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
+//
+// Example shader that can be applied to models
+//
+//==================================================================================================
+
+#ifndef EXAMPLE_MODEL_DX9_HELPER_H
+#define EXAMPLE_MODEL_DX9_HELPER_H
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class CBaseVSShader;
+class IMaterialVar;
+class IShaderDynamicAPI;
+class IShaderShadow;
+
+//-----------------------------------------------------------------------------
+// Init params/ init/ draw methods
+//-----------------------------------------------------------------------------
+struct ExampleModel_DX9_Vars_t
+{
+ ExampleModel_DX9_Vars_t() { memset( this, 0xFF, sizeof(*this) ); }
+
+ int m_nBaseTexture;
+ int m_nBaseTextureFrame;
+ int m_nBaseTextureTransform;
+ int m_nAlphaTestReference;
+ int m_nFlashlightTexture;
+ int m_nFlashlightTextureFrame;
+};
+
+void InitParamsExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params,
+ const char *pMaterialName, ExampleModel_DX9_Vars_t &info );
+
+void InitExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params,
+ ExampleModel_DX9_Vars_t &info );
+
+void DrawExampleModel_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI,
+ IShaderShadow* pShaderShadow,
+ ExampleModel_DX9_Vars_t &info, VertexCompressionType_t vertexCompression,
+ CBasePerMaterialContextData **pContextDataPtr );
+
+#endif // EXAMPLE_MODEL_DX9_HELPER_H
diff --git a/mp/src/materialsystem/stdshaders/example_model_ps20b.fxc b/mp/src/materialsystem/stdshaders/example_model_ps20b.fxc new file mode 100644 index 00000000..a7b35e44 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/example_model_ps20b.fxc @@ -0,0 +1,92 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
+//
+// Example pixel shader that can be applied to models
+//
+//==================================================================================================
+
+// STATIC: "CONVERT_TO_SRGB" "0..0"
+// STATIC: "FLASHLIGHT" "0..1"
+// STATIC: "FLASHLIGHTDEPTHFILTERMODE" "0..2" [ps20b]
+
+// DYNAMIC: "WRITEWATERFOGTODESTALPHA" "0..1"
+// DYNAMIC: "PIXELFOGTYPE" "0..1"
+// DYNAMIC: "NUM_LIGHTS" "0..4"
+// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA" "0..1" [ps20b]
+// DYNAMIC: "FLASHLIGHTSHADOWS" "0..1" [ps20b]
+
+// SKIP: ($PIXELFOGTYPE == 0) && ($WRITEWATERFOGTODESTALPHA != 0)
+
+// We don't care about flashlight depth unless the flashlight is on
+// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTSHADOWS == 1 )
+
+// Flashlight shadow filter mode is irrelevant if there is no flashlight
+// SKIP: ( $FLASHLIGHT == 0 ) && ( $FLASHLIGHTDEPTHFILTERMODE != 0 ) [ps20b]
+
+#include "common_flashlight_fxc.h"
+#include "shader_constant_register_map.h"
+
+const float4 g_DiffuseModulation : register( PSREG_DIFFUSE_MODULATION );
+const float4 g_ShadowTweaks : register( PSREG_ENVMAP_TINT__SHADOW_TWEAKS );
+const float3 cAmbientCube[6] : register( PSREG_AMBIENT_CUBE );
+const float4 g_EyePos : register( PSREG_EYEPOS_SPEC_EXPONENT );
+const float4 g_FogParams : register( PSREG_FOG_PARAMS );
+const float4 g_FlashlightAttenuationFactors : register( PSREG_FLASHLIGHT_ATTENUATION ); // On non-flashlight pass
+const float4 g_FlashlightPos_RimBoost : register( PSREG_FLASHLIGHT_POSITION_RIM_BOOST );
+const float4x4 g_FlashlightWorldToTexture : register( PSREG_FLASHLIGHT_TO_WORLD_TEXTURE );
+PixelShaderLightInfo cLightInfo[3] : register( PSREG_LIGHT_INFO_ARRAY ); // 2 registers each - 6 registers total (4th light spread across w's)
+
+#define g_FlashlightPos g_FlashlightPos_RimBoost.xyz
+
+sampler BaseTextureSampler : register( s0 ); // Base map, selfillum in alpha
+sampler ShadowDepthSampler : register( s4 ); // Flashlight shadow depth map sampler
+sampler NormalizeRandRotSampler : register( s5 ); // Normalization / RandomRotation samplers
+sampler FlashlightSampler : register( s6 ); // Flashlight cookie
+
+struct PS_INPUT
+{
+ float2 baseTexCoord : TEXCOORD0;
+ float4 lightAtten : TEXCOORD1;
+ float3 worldNormal : TEXCOORD2;
+ float3 worldPos : TEXCOORD3;
+ float3 projPos : TEXCOORD4;
+};
+
+float4 main( PS_INPUT i ) : COLOR
+{
+ float4 baseColor = tex2D( BaseTextureSampler, i.baseTexCoord );
+
+ float3 diffuseLighting;
+ if ( FLASHLIGHT != 0 )
+ {
+ float4 flashlightSpacePosition = mul( float4( i.worldPos, 1.0f ), g_FlashlightWorldToTexture );
+
+ diffuseLighting = DoFlashlight( g_FlashlightPos, i.worldPos, flashlightSpacePosition,
+ i.worldNormal, g_FlashlightAttenuationFactors.xyz,
+ g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler,
+ NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, i.projPos, false, g_ShadowTweaks );
+ }
+ else // non-flashlight path
+ {
+ // Summation of diffuse illumination from all local lights
+ diffuseLighting = PixelShaderDoLighting( i.worldPos, i.worldNormal,
+ float3( 0.0f, 0.0f, 0.0f ), false, true, i.lightAtten,
+ cAmbientCube, NormalizeRandRotSampler, NUM_LIGHTS, cLightInfo, true,
+
+ // These are dummy parameters:
+ false, 1.0f,
+ false, BaseTextureSampler );
+ }
+
+ float3 result = baseColor.rgb * g_DiffuseModulation.rgb * diffuseLighting;
+ float alpha = g_DiffuseModulation.a * baseColor.a;
+
+ float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos.z, i.projPos.z );
+
+#if WRITEWATERFOGTODESTALPHA && ( PIXELFOGTYPE == PIXEL_FOG_TYPE_HEIGHT )
+ alpha = fogFactor;
+#endif
+
+ bool bWriteDepthToAlpha = ( WRITE_DEPTH_TO_DESTALPHA != 0 ) && ( WRITEWATERFOGTODESTALPHA == 0 );
+
+ return FinalOutput( float4( result, alpha ), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, bWriteDepthToAlpha, i.projPos.z );
+}
diff --git a/mp/src/materialsystem/stdshaders/example_model_vs20.fxc b/mp/src/materialsystem/stdshaders/example_model_vs20.fxc new file mode 100644 index 00000000..877c84e2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/example_model_vs20.fxc @@ -0,0 +1,91 @@ +//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
+//
+// Example vertex shader that can be applied to models
+//
+//==================================================================================================
+
+// DYNAMIC: "COMPRESSED_VERTS" "0..1"
+// DYNAMIC: "DOWATERFOG" "0..1"
+// DYNAMIC: "SKINNING" "0..1"
+// DYNAMIC: "LIGHTING_PREVIEW" "0..1"
+// DYNAMIC: "NUM_LIGHTS" "0..4"
+
+#include "common_vs_fxc.h"
+
+static const bool g_bSkinning = SKINNING ? true : false;
+static const int g_FogType = DOWATERFOG;
+
+const float4 cBaseTexCoordTransform[2] : register( SHADER_SPECIFIC_CONST_0 );
+
+//-----------------------------------------------------------------------------
+// Input vertex format
+//-----------------------------------------------------------------------------
+struct VS_INPUT
+{
+ // This is all of the stuff that we ever use.
+ float4 vPos : POSITION;
+ float4 vBoneWeights : BLENDWEIGHT;
+ float4 vBoneIndices : BLENDINDICES;
+ float4 vNormal : NORMAL;
+ float2 vTexCoord0 : TEXCOORD0;
+};
+
+struct VS_OUTPUT
+{
+ // Stuff that isn't seen by the pixel shader
+ float4 projPosSetup : POSITION;
+ float fog : FOG;
+ // Stuff that is seen by the pixel shader
+ float2 baseTexCoord : TEXCOORD0;
+ float4 lightAtten : TEXCOORD1;
+ float3 worldNormal : TEXCOORD2;
+ float3 worldPos : TEXCOORD3;
+ float3 projPos : TEXCOORD4;
+};
+
+//-----------------------------------------------------------------------------
+// Main shader entry point
+//-----------------------------------------------------------------------------
+VS_OUTPUT main( const VS_INPUT v )
+{
+ VS_OUTPUT o = ( VS_OUTPUT )0;
+
+ float3 vNormal;
+ DecompressVertex_Normal( v.vNormal, vNormal );
+
+ float3 worldNormal, worldPos;
+ SkinPositionAndNormal( g_bSkinning, v.vPos, vNormal, v.vBoneWeights, v.vBoneIndices, worldPos, worldNormal );
+
+ // Transform into projection space
+ float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj );
+ o.projPosSetup = vProjPos;
+ vProjPos.z = dot( float4( worldPos, 1 ), cViewProjZ );
+
+ o.projPos = vProjPos.xyz;
+ o.fog = CalcFog( worldPos, vProjPos.xyz, g_FogType );
+
+ // Needed for water fog alpha and diffuse lighting
+ o.worldPos = worldPos;
+ o.worldNormal = normalize( worldNormal );
+
+ // Scalar attenuations for four lights
+ o.lightAtten.xyz = float4(0,0,0,0);
+ #if ( NUM_LIGHTS > 0 )
+ o.lightAtten.x = GetVertexAttenForLight( worldPos, 0, false );
+ #endif
+ #if ( NUM_LIGHTS > 1 )
+ o.lightAtten.y = GetVertexAttenForLight( worldPos, 1, false );
+ #endif
+ #if ( NUM_LIGHTS > 2 )
+ o.lightAtten.z = GetVertexAttenForLight( worldPos, 2, false );
+ #endif
+ #if ( NUM_LIGHTS > 3 )
+ o.lightAtten.w = GetVertexAttenForLight( worldPos, 3, false );
+ #endif
+
+ // Base texture coordinate transform
+ o.baseTexCoord.x = dot( v.vTexCoord0, cBaseTexCoordTransform[0] );
+ o.baseTexCoord.y = dot( v.vTexCoord0, cBaseTexCoordTransform[1] );
+
+ return o;
+}
diff --git a/mp/src/materialsystem/stdshaders/fxctmp9/example_model_ps20b.inc b/mp/src/materialsystem/stdshaders/fxctmp9/example_model_ps20b.inc new file mode 100644 index 00000000..018f7b63 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/fxctmp9/example_model_ps20b.inc @@ -0,0 +1,237 @@ +#include "shaderlib/cshader.h"
+class example_model_ps20b_Static_Index
+{
+private:
+ int m_nCONVERT_TO_SRGB;
+#ifdef _DEBUG
+ bool m_bCONVERT_TO_SRGB;
+#endif
+public:
+ void SetCONVERT_TO_SRGB( int i )
+ {
+ Assert( i >= 0 && i <= 0 );
+ m_nCONVERT_TO_SRGB = i;
+#ifdef _DEBUG
+ m_bCONVERT_TO_SRGB = true;
+#endif
+ }
+ void SetCONVERT_TO_SRGB( bool i )
+ {
+ m_nCONVERT_TO_SRGB = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bCONVERT_TO_SRGB = true;
+#endif
+ }
+private:
+ int m_nFLASHLIGHT;
+#ifdef _DEBUG
+ bool m_bFLASHLIGHT;
+#endif
+public:
+ void SetFLASHLIGHT( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nFLASHLIGHT = i;
+#ifdef _DEBUG
+ m_bFLASHLIGHT = true;
+#endif
+ }
+ void SetFLASHLIGHT( bool i )
+ {
+ m_nFLASHLIGHT = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHT = true;
+#endif
+ }
+private:
+ int m_nFLASHLIGHTDEPTHFILTERMODE;
+#ifdef _DEBUG
+ bool m_bFLASHLIGHTDEPTHFILTERMODE;
+#endif
+public:
+ void SetFLASHLIGHTDEPTHFILTERMODE( int i )
+ {
+ Assert( i >= 0 && i <= 2 );
+ m_nFLASHLIGHTDEPTHFILTERMODE = i;
+#ifdef _DEBUG
+ m_bFLASHLIGHTDEPTHFILTERMODE = true;
+#endif
+ }
+ void SetFLASHLIGHTDEPTHFILTERMODE( bool i )
+ {
+ m_nFLASHLIGHTDEPTHFILTERMODE = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHTDEPTHFILTERMODE = true;
+#endif
+ }
+public:
+ example_model_ps20b_Static_Index( )
+ {
+#ifdef _DEBUG
+ m_bCONVERT_TO_SRGB = false;
+#endif // _DEBUG
+ m_nCONVERT_TO_SRGB = 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHT = false;
+#endif // _DEBUG
+ m_nFLASHLIGHT = 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHTDEPTHFILTERMODE = false;
+#endif // _DEBUG
+ m_nFLASHLIGHTDEPTHFILTERMODE = 0;
+ }
+ int GetIndex()
+ {
+ // Asserts to make sure that we aren't using any skipped combinations.
+ // Asserts to make sure that we are setting all of the combination vars.
+#ifdef _DEBUG
+ bool bAllStaticVarsDefined = m_bCONVERT_TO_SRGB && m_bFLASHLIGHT && m_bFLASHLIGHTDEPTHFILTERMODE;
+ Assert( bAllStaticVarsDefined );
+#endif // _DEBUG
+ return ( 80 * m_nCONVERT_TO_SRGB ) + ( 80 * m_nFLASHLIGHT ) + ( 160 * m_nFLASHLIGHTDEPTHFILTERMODE ) + 0;
+ }
+};
+#define shaderStaticTest_example_model_ps20b psh_forgot_to_set_static_CONVERT_TO_SRGB + psh_forgot_to_set_static_FLASHLIGHT + psh_forgot_to_set_static_FLASHLIGHTDEPTHFILTERMODE + 0
+class example_model_ps20b_Dynamic_Index
+{
+private:
+ int m_nWRITEWATERFOGTODESTALPHA;
+#ifdef _DEBUG
+ bool m_bWRITEWATERFOGTODESTALPHA;
+#endif
+public:
+ void SetWRITEWATERFOGTODESTALPHA( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nWRITEWATERFOGTODESTALPHA = i;
+#ifdef _DEBUG
+ m_bWRITEWATERFOGTODESTALPHA = true;
+#endif
+ }
+ void SetWRITEWATERFOGTODESTALPHA( bool i )
+ {
+ m_nWRITEWATERFOGTODESTALPHA = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bWRITEWATERFOGTODESTALPHA = true;
+#endif
+ }
+private:
+ int m_nPIXELFOGTYPE;
+#ifdef _DEBUG
+ bool m_bPIXELFOGTYPE;
+#endif
+public:
+ void SetPIXELFOGTYPE( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nPIXELFOGTYPE = i;
+#ifdef _DEBUG
+ m_bPIXELFOGTYPE = true;
+#endif
+ }
+ void SetPIXELFOGTYPE( bool i )
+ {
+ m_nPIXELFOGTYPE = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bPIXELFOGTYPE = true;
+#endif
+ }
+private:
+ int m_nNUM_LIGHTS;
+#ifdef _DEBUG
+ bool m_bNUM_LIGHTS;
+#endif
+public:
+ void SetNUM_LIGHTS( int i )
+ {
+ Assert( i >= 0 && i <= 4 );
+ m_nNUM_LIGHTS = i;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = true;
+#endif
+ }
+ void SetNUM_LIGHTS( bool i )
+ {
+ m_nNUM_LIGHTS = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = true;
+#endif
+ }
+private:
+ int m_nWRITE_DEPTH_TO_DESTALPHA;
+#ifdef _DEBUG
+ bool m_bWRITE_DEPTH_TO_DESTALPHA;
+#endif
+public:
+ void SetWRITE_DEPTH_TO_DESTALPHA( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nWRITE_DEPTH_TO_DESTALPHA = i;
+#ifdef _DEBUG
+ m_bWRITE_DEPTH_TO_DESTALPHA = true;
+#endif
+ }
+ void SetWRITE_DEPTH_TO_DESTALPHA( bool i )
+ {
+ m_nWRITE_DEPTH_TO_DESTALPHA = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bWRITE_DEPTH_TO_DESTALPHA = true;
+#endif
+ }
+private:
+ int m_nFLASHLIGHTSHADOWS;
+#ifdef _DEBUG
+ bool m_bFLASHLIGHTSHADOWS;
+#endif
+public:
+ void SetFLASHLIGHTSHADOWS( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nFLASHLIGHTSHADOWS = i;
+#ifdef _DEBUG
+ m_bFLASHLIGHTSHADOWS = true;
+#endif
+ }
+ void SetFLASHLIGHTSHADOWS( bool i )
+ {
+ m_nFLASHLIGHTSHADOWS = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHTSHADOWS = true;
+#endif
+ }
+public:
+ example_model_ps20b_Dynamic_Index()
+ {
+#ifdef _DEBUG
+ m_bWRITEWATERFOGTODESTALPHA = false;
+#endif // _DEBUG
+ m_nWRITEWATERFOGTODESTALPHA = 0;
+#ifdef _DEBUG
+ m_bPIXELFOGTYPE = false;
+#endif // _DEBUG
+ m_nPIXELFOGTYPE = 0;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = false;
+#endif // _DEBUG
+ m_nNUM_LIGHTS = 0;
+#ifdef _DEBUG
+ m_bWRITE_DEPTH_TO_DESTALPHA = false;
+#endif // _DEBUG
+ m_nWRITE_DEPTH_TO_DESTALPHA = 0;
+#ifdef _DEBUG
+ m_bFLASHLIGHTSHADOWS = false;
+#endif // _DEBUG
+ m_nFLASHLIGHTSHADOWS = 0;
+ }
+ int GetIndex()
+ {
+ // Asserts to make sure that we aren't using any skipped combinations.
+ // Asserts to make sure that we are setting all of the combination vars.
+#ifdef _DEBUG
+ bool bAllDynamicVarsDefined = m_bWRITEWATERFOGTODESTALPHA && m_bPIXELFOGTYPE && m_bNUM_LIGHTS && m_bWRITE_DEPTH_TO_DESTALPHA && m_bFLASHLIGHTSHADOWS;
+ Assert( bAllDynamicVarsDefined );
+#endif // _DEBUG
+ return ( 1 * m_nWRITEWATERFOGTODESTALPHA ) + ( 2 * m_nPIXELFOGTYPE ) + ( 4 * m_nNUM_LIGHTS ) + ( 20 * m_nWRITE_DEPTH_TO_DESTALPHA ) + ( 40 * m_nFLASHLIGHTSHADOWS ) + 0;
+ }
+};
+#define shaderDynamicTest_example_model_ps20b psh_forgot_to_set_dynamic_WRITEWATERFOGTODESTALPHA + psh_forgot_to_set_dynamic_PIXELFOGTYPE + psh_forgot_to_set_dynamic_NUM_LIGHTS + psh_forgot_to_set_dynamic_WRITE_DEPTH_TO_DESTALPHA + psh_forgot_to_set_dynamic_FLASHLIGHTSHADOWS + 0
diff --git a/mp/src/materialsystem/stdshaders/fxctmp9/example_model_vs20.inc b/mp/src/materialsystem/stdshaders/fxctmp9/example_model_vs20.inc new file mode 100644 index 00000000..a8dbd23f --- /dev/null +++ b/mp/src/materialsystem/stdshaders/fxctmp9/example_model_vs20.inc @@ -0,0 +1,160 @@ +#include "shaderlib/cshader.h"
+class example_model_vs20_Static_Index
+{
+public:
+ example_model_vs20_Static_Index( )
+ {
+ }
+ int GetIndex()
+ {
+ // Asserts to make sure that we aren't using any skipped combinations.
+ // Asserts to make sure that we are setting all of the combination vars.
+#ifdef _DEBUG
+#endif // _DEBUG
+ return 0;
+ }
+};
+#define shaderStaticTest_example_model_vs20 0
+class example_model_vs20_Dynamic_Index
+{
+private:
+ int m_nCOMPRESSED_VERTS;
+#ifdef _DEBUG
+ bool m_bCOMPRESSED_VERTS;
+#endif
+public:
+ void SetCOMPRESSED_VERTS( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nCOMPRESSED_VERTS = i;
+#ifdef _DEBUG
+ m_bCOMPRESSED_VERTS = true;
+#endif
+ }
+ void SetCOMPRESSED_VERTS( bool i )
+ {
+ m_nCOMPRESSED_VERTS = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bCOMPRESSED_VERTS = true;
+#endif
+ }
+private:
+ int m_nDOWATERFOG;
+#ifdef _DEBUG
+ bool m_bDOWATERFOG;
+#endif
+public:
+ void SetDOWATERFOG( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nDOWATERFOG = i;
+#ifdef _DEBUG
+ m_bDOWATERFOG = true;
+#endif
+ }
+ void SetDOWATERFOG( bool i )
+ {
+ m_nDOWATERFOG = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bDOWATERFOG = true;
+#endif
+ }
+private:
+ int m_nSKINNING;
+#ifdef _DEBUG
+ bool m_bSKINNING;
+#endif
+public:
+ void SetSKINNING( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nSKINNING = i;
+#ifdef _DEBUG
+ m_bSKINNING = true;
+#endif
+ }
+ void SetSKINNING( bool i )
+ {
+ m_nSKINNING = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bSKINNING = true;
+#endif
+ }
+private:
+ int m_nLIGHTING_PREVIEW;
+#ifdef _DEBUG
+ bool m_bLIGHTING_PREVIEW;
+#endif
+public:
+ void SetLIGHTING_PREVIEW( int i )
+ {
+ Assert( i >= 0 && i <= 1 );
+ m_nLIGHTING_PREVIEW = i;
+#ifdef _DEBUG
+ m_bLIGHTING_PREVIEW = true;
+#endif
+ }
+ void SetLIGHTING_PREVIEW( bool i )
+ {
+ m_nLIGHTING_PREVIEW = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bLIGHTING_PREVIEW = true;
+#endif
+ }
+private:
+ int m_nNUM_LIGHTS;
+#ifdef _DEBUG
+ bool m_bNUM_LIGHTS;
+#endif
+public:
+ void SetNUM_LIGHTS( int i )
+ {
+ Assert( i >= 0 && i <= 4 );
+ m_nNUM_LIGHTS = i;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = true;
+#endif
+ }
+ void SetNUM_LIGHTS( bool i )
+ {
+ m_nNUM_LIGHTS = i ? 1 : 0;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = true;
+#endif
+ }
+public:
+ example_model_vs20_Dynamic_Index()
+ {
+#ifdef _DEBUG
+ m_bCOMPRESSED_VERTS = false;
+#endif // _DEBUG
+ m_nCOMPRESSED_VERTS = 0;
+#ifdef _DEBUG
+ m_bDOWATERFOG = false;
+#endif // _DEBUG
+ m_nDOWATERFOG = 0;
+#ifdef _DEBUG
+ m_bSKINNING = false;
+#endif // _DEBUG
+ m_nSKINNING = 0;
+#ifdef _DEBUG
+ m_bLIGHTING_PREVIEW = false;
+#endif // _DEBUG
+ m_nLIGHTING_PREVIEW = 0;
+#ifdef _DEBUG
+ m_bNUM_LIGHTS = false;
+#endif // _DEBUG
+ m_nNUM_LIGHTS = 0;
+ }
+ int GetIndex()
+ {
+ // Asserts to make sure that we aren't using any skipped combinations.
+ // Asserts to make sure that we are setting all of the combination vars.
+#ifdef _DEBUG
+ bool bAllDynamicVarsDefined = m_bCOMPRESSED_VERTS && m_bDOWATERFOG && m_bSKINNING && m_bLIGHTING_PREVIEW && m_bNUM_LIGHTS;
+ Assert( bAllDynamicVarsDefined );
+#endif // _DEBUG
+ return ( 1 * m_nCOMPRESSED_VERTS ) + ( 2 * m_nDOWATERFOG ) + ( 4 * m_nSKINNING ) + ( 8 * m_nLIGHTING_PREVIEW ) + ( 16 * m_nNUM_LIGHTS ) + 0;
+ }
+};
+#define shaderDynamicTest_example_model_vs20 vsh_forgot_to_set_dynamic_COMPRESSED_VERTS + vsh_forgot_to_set_dynamic_DOWATERFOG + vsh_forgot_to_set_dynamic_SKINNING + vsh_forgot_to_set_dynamic_LIGHTING_PREVIEW + vsh_forgot_to_set_dynamic_NUM_LIGHTS + 0
diff --git a/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc b/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc new file mode 100644 index 00000000..2fb7fc9e --- /dev/null +++ b/mp/src/materialsystem/stdshaders/game_shader_dx9_base.vpc @@ -0,0 +1,101 @@ +//-----------------------------------------------------------------------------
+// game_shader_dx9.vpc
+//
+// Project Script for mods to use an an example of how to override shaders
+//-----------------------------------------------------------------------------
+
+$Macro OUTBINDIR "$SRCDIR\..\game\$GAMENAME\bin"
+
+$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
+
+$Configuration "Debug"
+{
+ $General
+ {
+ $OutputDirectory "Debug_dx9_$GAMENAME" [$WIN32]
+ $IntermediateDirectory "Debug_dx9_$GAMENAME" [$WIN32]
+ }
+}
+
+$Configuration "Release"
+{
+ $General
+ {
+ $OutputDirectory "Release_dx9_$GAMENAME" [$WIN32]
+ $IntermediateDirectory "Release_dx9_$GAMENAME" [$WIN32]
+ }
+}
+
+// Common Configuration
+$Configuration
+{
+ $Compiler
+ {
+ $AdditionalIncludeDirectories "$BASE;fxctmp9;vshtmp9;" [$WIN32||$POSIX]
+// $AdditionalIncludeDirectories "$BASE;..\..\dx9sdk\include" [$WIN32]
+ $AdditionalIncludeDirectories "$BASE;fxctmp9_360;vshtmp9_360" [$X360]
+ $PreprocessorDefinitions "$BASE;STDSHADER_DX9_DLL_EXPORT;FAST_MATERIALVAR_ACCESS;GAME_SHADER_DLL"
+ $PreprocessorDefinitions "$BASE;USE_ACTUAL_DX" [($WIN32||$X360) && !$GL]
+ }
+
+ $Linker
+ {
+ $AdditionalDependencies "$BASE version.lib winmm.lib" [$WIN32]
+ $SystemLibraries "iconv" [$OSXALL]
+ }
+}
+
+$Project
+{
+ $Folder "Source Files"
+ {
+ $File "BaseVSShader.cpp"
+
+ $File "example_model_dx9.cpp"
+ $File "example_model_dx9_helper.cpp"
+ }
+
+ $Folder "Header Files"
+ {
+ $File "BaseVSShader.h"
+ $File "common_fxc.h"
+ $File "common_hlsl_cpp_consts.h"
+ $File "common_ps_fxc.h"
+ $File "common_vertexlitgeneric_dx9.h"
+ $File "common_vs_fxc.h"
+ $File "shader_constant_register_map.h"
+
+ $File "example_model_dx9_helper.h"
+ }
+
+ $Folder "Link Libraries" [$WIN32]
+ {
+// $File "$SRCDIR\dx9sdk\lib\d3dx9.lib"
+ $DynamicFile "$SRCDIR\lib\public\mathlib.lib"
+ $DynamicFile "$SRCDIR\lib\public\shaderlib.lib"
+ }
+
+ $Folder "Link Libraries" [$X360]
+ {
+ $DynamicFile "$SRCDIR\lib\public\mathlib_360.lib"
+ $DynamicFile "$SRCDIR\lib\public\shaderlib_360.lib"
+ }
+
+ $Folder "Link Libraries" [$POSIX&&!$LINUX]
+ {
+ $DynamicFile "$SRCDIR\lib\$PLATFORM\mathlib$_STATICLIB_EXT"
+ $DynamicFile "$SRCDIR\lib\$PLATFORM\shaderlib$_STATICLIB_EXT"
+ }
+
+ $Folder "Link Libraries" [$LINUX]
+ {
+ $Lib mathlib
+ $Lib shaderlib
+ }
+
+ $File "buildsdkshaders.bat"
+ $File "buildshaders.bat"
+
+ $Shaders "stdshader_dx9_20b.txt"
+ $Shaders "stdshader_dx9_30.txt"
+}
diff --git a/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc b/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc new file mode 100644 index 00000000..7f5339b7 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/game_shader_dx9_hl2mp.vpc @@ -0,0 +1,13 @@ +//-----------------------------------------------------------------------------
+// game_shader_dx9.vpc
+//
+// Project Script for mods to use an an example of how to override shaders
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\.."
+$Macro GAMENAME "mod_hl2mp"
+$Include "$SRCDIR\materialsystem\stdshaders\game_shader_dx9_base.vpc"
+
+$Project "Shaders (HL2MP)"
+{
+}
\ No newline at end of file diff --git a/mp/src/materialsystem/stdshaders/genwaterloop.pl b/mp/src/materialsystem/stdshaders/genwaterloop.pl new file mode 100644 index 00000000..0a4701ce --- /dev/null +++ b/mp/src/materialsystem/stdshaders/genwaterloop.pl @@ -0,0 +1,9 @@ +for($ix=-2;$ix<=2;$ix++)
+{
+ for($iy=-2;$iy<=2;$iy++)
+ {
+ print "vRefractColor += tex2D( RefractSampler, vRefractTexCoord + $ix * ddx1 + $iy * ddy1 );\n";
+ $sumweights+=1;
+ }
+}
+print "float sumweights = $sumweights;\n";
diff --git a/mp/src/materialsystem/stdshaders/macros.vsh b/mp/src/materialsystem/stdshaders/macros.vsh new file mode 100644 index 00000000..9b19f777 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/macros.vsh @@ -0,0 +1,1393 @@ +;------------------------------------
+; RULES FOR AUTHORING VERTEX SHADERS:
+;------------------------------------
+; - never use "def" . . .set constants in code instead. . our constant shadowing will break otherwise.
+; (same goes for pixel shaders)
+; - use cN notation instead of c[N] notation. .makes grepping for registers easier.
+; The only exception is c[a0.x+blah] where you have no choice.
+$g_NumRegisters = 12;
+
+; NOTE: These must match the same values in vsh_prep.pl!
+$vPos = "v0";
+$vBoneWeights = "v1";
+$vBoneIndices = "v2";
+$vNormal = "v3";
+$vColor = "v5";
+$vSpecular = "v6";
+$vTexCoord0 = "v7";
+$vTexCoord1 = "v8";
+$vTexCoord2 = "v9";
+$vTexCoord3 = "v10";
+$vTangentS = "v11";
+$vTangentT = "v12";
+$vUserData = "v14";
+
+if( $g_dx9 )
+{
+ if( $g_usesPos )
+ {
+ dcl_position $vPos;
+ }
+
+ if( $g_usesBoneWeights )
+ {
+ dcl_blendweight $vBoneWeights;
+ }
+ if( $g_usesBoneIndices )
+ {
+ dcl_blendindices $vBoneIndices;
+ }
+ if( $g_usesNormal )
+ {
+ dcl_normal $vNormal;
+ }
+ if( $g_usesColor )
+ {
+ dcl_color0 $vColor;
+ }
+ if( $g_usesSpecular )
+ {
+ dcl_color1 $vSpecular;
+ }
+ if( $g_usesTexCoord0 )
+ {
+ dcl_texcoord0 $vTexCoord0;
+ }
+ if( $g_usesTexCoord1 )
+ {
+ dcl_texcoord1 $vTexCoord1;
+ }
+ if( $g_usesTexCoord2 )
+ {
+ dcl_texcoord2 $vTexCoord2;
+ }
+ if( $g_usesTexCoord3 )
+ {
+ dcl_texcoord3 $vTexCoord3;
+ }
+ if( $g_usesTangentS )
+ {
+ dcl_tangent $vTangentS;
+ }
+ if( $g_usesTangentT )
+ {
+ dcl_binormal0 $vTangentT;
+ }
+ if( $g_usesUserData )
+ {
+ dcl_tangent $vUserData;
+ }
+}
+
+# NOTE: These should match g_LightCombinations in vertexshaderdx8.cpp!
+# NOTE: Leave this on single lines or shit might blow up.
+@g_staticLightTypeArray = ( "none", "static", "none", "none", "none", "none", "none", "none", "none", "none", "none", "none", "static", "static", "static", "static", "static", "static", "static", "static", "static", "static" );
+@g_ambientLightTypeArray = ( "none", "none", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient", "ambient" );
+@g_localLightType1Array = ( "none", "none", "none", "spot", "point", "directional", "spot", "spot", "spot", "point", "point", "directional", "none", "spot", "point", "directional", "spot", "spot", "spot", "point", "point", "directional" );
+@g_localLightType2Array = ( "none", "none", "none", "none", "none", "none", "spot", "point", "directional", "point", "directional", "directional", "none", "none", "none", "none", "spot", "point", "directional", "point", "directional", "directional" );
+
+$cConstants0 = "c0";
+$cZero = "c0.x";
+$cOne = "c0.y";
+$cTwo = "c0.z";
+$cHalf = "c0.w";
+
+$cConstants1 = "c1";
+$cOOGamma = "c1.x"; # 1/2.2
+$cOtherOverbrightFactor = "c1.y"; # overbright
+$cOneThird = "c1.z"; # 1/3
+$cOverbrightFactor = "c1.w"; # 1/overbright
+
+$cEyePos = "c2";
+$cWaterZ = "c2.w";
+$cEyePosWaterZ = "c2";
+
+$cLightIndex = "c3";
+$cLight0Offset = "c3.x"; # 27
+$cLight1Offset = "c3.y"; # 32
+$cColorToIntScale = "c3.z"; # matrix array offset = 3.0f * 255.0f + 0.01 (epsilon ensures floor yields desired result)
+$cModel0Index = "c3.w"; # base for start of skinning matrices
+
+; NOTE: These must match the same values in vsh_prep.pl!
+$cModelViewProj0 = "c4";
+$cModelViewProj1 = "c5";
+$cModelViewProj2 = "c6";
+$cModelViewProj3 = "c7";
+
+$cViewProj0 = "c8";
+$cViewProj1 = "c9";
+$cViewProj2 = "c10";
+$cViewProj3 = "c11";
+
+; currently unused
+; c12, c13
+
+$SHADER_SPECIFIC_CONST_10 = "c14";
+$SHADER_SPECIFIC_CONST_11 = "c15";
+
+$cFogParams = "c16";
+$cFogEndOverFogRange = "c16.x";
+$cFogOne = "c16.y";
+$cFogMaxDensity = "c16.z";
+$cOOFogRange = "c16.w"; # (1/(fogEnd-fogStart))
+
+$cViewModel0 = "c17";
+$cViewModel1 = "c18";
+$cViewModel2 = "c19";
+$cViewModel3 = "c20";
+
+$cAmbientColorPosX = "c21";
+$cAmbientColorNegX = "c22";
+$cAmbientColorPosY = "c23";
+$cAmbientColorNegY = "c24";
+$cAmbientColorPosZ = "c25";
+$cAmbientColorNegZ = "c26";
+
+$cAmbientColorPosXOffset = "21";
+$cAmbientColorPosYOffset = "23";
+$cAmbientColorPosZOffset = "25";
+
+$cLight0DiffColor = "c27";
+$cLight0Dir = "c28";
+$cLight0Pos = "c29";
+$cLight0SpotParams = "c30"; # [ exponent, stopdot, stopdot2, 1 / (stopdot - stopdot2)
+$cLight0Atten = "c31"; # [ constant, linear, quadratic, 0.0f ]
+
+$cLight1DiffColor = "c32";
+$cLight1Dir = "c33";
+$cLight1Pos = "c34";
+$cLight1SpotParams = "c35"; # [ exponent, stopdot, stopdot2, 1 / (stopdot - stopdot2)
+$cLight1Atten = "c36"; # [ constant, linear, quadratic, 0.0f ]
+
+$cModulationColor = "c37";
+
+$SHADER_SPECIFIC_CONST_0 = "c38";
+$SHADER_SPECIFIC_CONST_1 = "c39";
+$SHADER_SPECIFIC_CONST_2 = "c40";
+$SHADER_SPECIFIC_CONST_3 = "c41";
+$SHADER_SPECIFIC_CONST_4 = "c42";
+$SHADER_SPECIFIC_CONST_5 = "c43";
+$SHADER_SPECIFIC_CONST_6 = "c44";
+$SHADER_SPECIFIC_CONST_7 = "c45";
+$SHADER_SPECIFIC_CONST_8 = "c46";
+$SHADER_SPECIFIC_CONST_9 = "c47";
+; $SHADER_SPECIFIC_CONST_10 is c14
+; $SHADER_SPECIFIC_CONST_11 is c15
+
+; There are 16 model matrices for skinning
+; NOTE: These must match the same values in vsh_prep.pl!
+$cModel0 = "c48";
+$cModel1 = "c49";
+$cModel2 = "c50";
+
+sub OutputUsedRegisters
+{
+ local( $i );
+ ; USED REGISTERS
+ for( $i = 0; $i < $g_NumRegisters; $i++ )
+ {
+ if( $g_allocated[$i] )
+ {
+ ; $g_allocatedname[$i] = r$i
+ }
+ }
+ ;
+}
+
+sub AllocateRegister
+{
+ local( *reg ) = shift;
+ local( $regname ) = shift;
+ local( $i );
+ for( $i = 0; $i < $g_NumRegisters; $i++ )
+ {
+ if( !$g_allocated[$i] )
+ {
+ $g_allocated[$i] = 1;
+ $g_allocatedname[$i] = $regname;
+ ; AllocateRegister $regname = r$i
+ $reg = "r$i";
+ &OutputUsedRegisters();
+ return;
+ }
+ }
+ ; Out of registers allocating $regname!
+ $reg = "rERROR_OUT_OF_REGISTERS";
+ &OutputUsedRegisters();
+}
+
+; pass in a reference to a var that contains a register. . ie \$var where var will constain "r1", etc
+sub FreeRegister
+{
+ local( *reg ) = shift;
+ local( $regname ) = shift;
+ ; FreeRegister $regname = $reg
+ if( $reg =~ m/rERROR_DEALLOCATED/ )
+ {
+ ; $regname already deallocated
+ ; $reg = "rALREADY_DEALLOCATED";
+ &OutputUsedRegisters();
+ return;
+ }
+; if( $regname ne g_allocatedname[$reg] )
+; {
+; ; Error freeing $reg
+; mov compileerror, freed unallocated register $regname
+; }
+
+ if( ( $reg =~ m/r(.*)/ ) )
+ {
+ $g_allocated[$1] = 0;
+ }
+ $reg = "rERROR_DEALLOCATED";
+ &OutputUsedRegisters();
+}
+
+sub CheckUnfreedRegisters()
+{
+ local( $i );
+ for( $i = 0; $i < $g_NumRegisters; $i++ )
+ {
+ if( $g_allocated[$i] )
+ {
+ print "ERROR: r$i allocated to $g_allocatedname[$i] at end of program\n";
+ $g_allocated[$i] = 0;
+ }
+ }
+}
+
+sub Normalize
+{
+ local( $r ) = shift;
+ dp3 $r.w, $r, $r
+ rsq $r.w, $r.w
+ mul $r, $r, $r.w
+}
+
+sub Cross
+{
+ local( $result ) = shift;
+ local( $a ) = shift;
+ local( $b ) = shift;
+
+ mul $result.xyz, $a.yzx, $b.zxy
+ mad $result.xyz, -$b.yzx, $a.zxy, $result
+}
+
+sub RangeFog
+{
+ local( $projPos ) = shift;
+
+ ;------------------------------
+ ; Regular range fog
+ ;------------------------------
+
+ ; oFog.x = 1.0f = no fog
+ ; oFog.x = 0.0f = full fog
+ ; compute fog factor f = (fog_end - dist)*(1/(fog_end-fog_start))
+ ; this is == to: (fog_end/(fog_end-fog_start) - dist/(fog_end-fog_start)
+ ; which can be expressed with a single mad instruction!
+
+ ; Compute |projPos|
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+ dp3 $tmp.x, $projPos.xyw, $projPos.xyw
+ rsq $tmp.x, $tmp.x
+ rcp $tmp.x, $tmp.x
+
+ if( $g_dx9 )
+ {
+ mad $tmp, -$tmp.x, $cOOFogRange, $cFogEndOverFogRange
+ min $tmp, $tmp, $cOne
+ max oFog, $tmp.x, $cFogMaxDensity
+ }
+ else
+ {
+ mad $tmp, -$tmp.x, $cOOFogRange, $cFogEndOverFogRange
+ min $tmp, $tmp, $cOne
+ max oFog.x, $tmp.x, $cFogMaxDensity
+ }
+ &FreeRegister( \$tmp );
+}
+
+sub DepthFog
+{
+ local( $projPos ) = shift;
+ local( $dest ) = shift;
+
+ if ( $dest eq "" )
+ {
+ $dest = "oFog";
+ }
+
+ ;------------------------------
+ ; Regular range fog
+ ;------------------------------
+
+ ; oFog.x = 1.0f = no fog
+ ; oFog.x = 0.0f = full fog
+ ; compute fog factor f = (fog_end - dist)*(1/(fog_end-fog_start))
+ ; this is == to: (fog_end/(fog_end-fog_start) - dist/(fog_end-fog_start)
+ ; which can be expressed with a single mad instruction!
+
+ ; Compute |projPos|
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+
+ if( $g_dx9 )
+ {
+ mad $tmp, -$projPos.w, $cOOFogRange, $cFogEndOverFogRange
+ min $tmp, $tmp, $cOne
+ max $dest, $tmp.x, $cFogMaxDensity
+ }
+ else
+ {
+ mad $tmp, -$projPos.w, $cOOFogRange, $cFogEndOverFogRange
+ min $tmp, $tmp, $cOne
+ max $dest.x, $tmp.x, $cFogMaxDensity
+ }
+
+ &FreeRegister( \$tmp );
+}
+
+sub WaterRangeFog
+{
+ ; oFog.x = 1.0f = no fog
+ ; oFog.x = 0.0f = full fog
+
+ ; only $worldPos.z is used out of worldPos
+ local( $worldPos ) = shift;
+ local( $projPos ) = shift;
+
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+
+ ; This is simple similar triangles. Imagine a line passing from the point directly vertically
+ ; and another line passing from the point to the eye position.
+ ; Let d = total distance from point to the eye
+ ; Let h = vertical distance from the point to the eye
+ ; Let hw = vertical distance from the point to the water surface
+ ; Let dw = distance from the point to a point on the water surface that lies along the ray from point to eye
+ ; Therefore d/h = dw/hw by similar triangles, or dw = d * hw / h.
+ ; d = |projPos|, h = eyepos.z - worldPos.z, hw = waterheight.z - worldPos.z, dw = what we solve for
+
+ ; Now, tmp.x = hw, and tmp.y = h
+ add $tmp.xy, $cEyePosWaterZ.wz, -$worldPos.z
+
+ ; if $tmp.x < 0, then set it to 0
+ ; This is the equivalent of moving the vert to the water surface if it's above the water surface
+ max $tmp.x, $tmp.x, $cZero
+
+ ; Compute 1 / |projPos| = 1/d
+ dp3 $tmp.z, $projPos.xyw, $projPos.xyw
+ rsq $tmp.z, $tmp.z
+
+ ; Now we have h/d
+ mul $tmp.z, $tmp.z, $tmp.y
+
+ ; Now we have d/h
+ rcp $tmp.w, $tmp.z
+
+ ; We finally have d * hw / h
+ ; $tmp.w is now the distance that we see through water.
+ mul $tmp.w, $tmp.x, $tmp.w
+
+ if( $g_dx9 )
+ {
+ mad $tmp, -$tmp.w, $cOOFogRange, $cFogOne
+ min $tmp, $tmp, $cOne
+ max oFog, $tmp.x, $cFogMaxDensity
+ }
+ else
+ {
+ mad $tmp, -$tmp.w, $cOOFogRange, $cFogOne
+ min $tmp, $tmp, $cOne
+ max oFog.x, $tmp.x, $cFogMaxDensity
+ }
+
+ &FreeRegister( \$tmp );
+}
+
+sub WaterDepthFog
+{
+ ; oFog.x = 1.0f = no fog
+ ; oFog.x = 0.0f = full fog
+
+ ; only $worldPos.z is used out of worldPos
+ local( $worldPos ) = shift;
+ local( $projPos ) = shift;
+ local( $dest ) = shift;
+
+ if ( $dest eq "" )
+ {
+ $dest = "oFog";
+ }
+
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+
+ ; This is simple similar triangles. Imagine a line passing from the point directly vertically
+ ; and another line passing from the point to the eye position.
+ ; Let d = total distance from point to the eye
+ ; Let h = vertical distance from the point to the eye
+ ; Let hw = vertical distance from the point to the water surface
+ ; Let dw = distance from the point to a point on the water surface that lies along the ray from point to eye
+ ; Therefore d/h = dw/hw by similar triangles, or dw = d * hw / h.
+ ; d = projPos.w, h = eyepos.z - worldPos.z, hw = waterheight.z - worldPos.z, dw = what we solve for
+
+ ; Now, tmp.x = hw, and tmp.y = h
+ add $tmp.xy, $cEyePosWaterZ.wz, -$worldPos.z
+
+ ; if $tmp.x < 0, then set it to 0
+ ; This is the equivalent of moving the vert to the water surface if it's above the water surface
+ max $tmp.x, $tmp.x, $cZero
+
+ ; Now we have 1/h
+ rcp $tmp.z, $tmp.y
+
+ ; Now we have d/h
+ mul $tmp.w, $projPos.w, $tmp.z
+
+ ; We finally have d * hw / h
+ ; $tmp.w is now the distance that we see through water.
+ mul $tmp.w, $tmp.x, $tmp.w
+
+ if( $g_dx9 )
+ {
+ mad $tmp, -$tmp.w, $cOOFogRange, $cFogOne
+ min $tmp, $tmp, $cOne
+ max $dest, $tmp.x, $cZero
+ }
+ else
+ {
+ mad $tmp, -$tmp.w, $cOOFogRange, $cFogOne
+ min $tmp, $tmp, $cOne
+ max $dest.x, $tmp.x, $cZero
+ }
+
+ &FreeRegister( \$tmp );
+}
+
+
+;------------------------------------------------------------------------------
+; Main fogging routine
+;------------------------------------------------------------------------------
+sub CalcFog
+{
+ if( !defined $DOWATERFOG )
+ {
+ die "CalcFog called without using \$DOWATERFOG\n";
+ }
+ my $fogType;
+ if( $DOWATERFOG == 0 )
+ {
+ $fogType = "rangefog";
+ }
+ else
+ {
+ $fogType = "heightfog";
+ }
+
+# print "\$fogType = $fogType\n";
+
+ ; CalcFog
+ local( $worldPos ) = shift;
+ local( $projPos ) = shift;
+ local( $dest ) = shift;
+
+ if ( $dest eq "" )
+ {
+ $dest = "oFog";
+ }
+
+ if( $fogType eq "rangefog" )
+ {
+ &DepthFog( $projPos, $dest );
+ }
+ elsif( $fogType eq "heightfog" )
+ {
+ &WaterDepthFog( $worldPos, $projPos, $dest );
+ }
+ else
+ {
+ die;
+ }
+}
+
+sub CalcRangeFog
+{
+ ; CalcFog
+ local( $worldPos ) = shift;
+ local( $projPos ) = shift;
+
+ if( $DOWATERFOG == 0 )
+ {
+ &RangeFog( $projPos );
+ }
+ elsif( $DOWATERFOG == 1 )
+ {
+ &WaterRangeFog( $worldPos, $projPos );
+ }
+ else
+ {
+ die;
+ }
+}
+
+sub GammaToLinear
+{
+ local( $gamma ) = shift;
+ local( $linear ) = shift;
+
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+
+ ; Is rcp more expensive than just storing 2.2 somewhere and doing a mov?
+ rcp $gamma.w, $cOOGamma ; $gamma.w = 2.2
+ lit $linear.z, $gamma.zzzw ; r0.z = linear blue
+ lit $tmp.z, $gamma.yyyw ; r2.z = linear green
+ mov $linear.y, $tmp.z ; r0.y = linear green
+ lit $tmp.z, $gamma.xxxw ; r2.z = linear red
+ mov $linear.x, $tmp.z ; r0.x = linear red
+
+ &FreeRegister( \$tmp );
+}
+
+sub LinearToGamma
+{
+ local( $linear ) = shift;
+ local( $gamma ) = shift;
+
+ local( $tmp );
+ &AllocateRegister( \$tmp );
+
+ mov $linear.w, $cOOGamma ; $linear.w = 1.0/2.2
+ lit $gamma.z, $linear.zzzw ; r0.z = gamma blue
+ lit $tmp.z, $linear.yyyw ; r2.z = gamma green
+ mov $gamma.y, $tmp.z ; r0.y = gamma green
+ lit $tmp.z, $linear.xxxw ; r2.z = gamma red
+ mov $gamma.x, $tmp.z ; r0.x = gamma red
+
+ &FreeRegister( \$tmp );
+}
+
+sub ComputeReflectionVector
+{
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $reflectionVector ) = shift;
+
+ local( $vertToEye ); &AllocateRegister( \$vertToEye );
+ local( $tmp ); &AllocateRegister( \$tmp );
+
+ ; compute reflection vector r = 2 * (n dot v) n - v
+ sub $vertToEye.xyz, $cEyePos.xyz, $worldPos ; $tmp1 = v = c - p
+ dp3 $tmp, $worldNormal, $vertToEye ; $tmp = n dot v
+ mul $tmp.xyz, $tmp.xyz, $worldNormal ; $tmp = (n dot v ) n
+ mad $reflectionVector.xyz, $tmp, $cTwo, -$vertToEye
+
+ &FreeRegister( \$vertToEye );
+ &FreeRegister( \$tmp );
+}
+
+sub ComputeSphereMapTexCoords
+{
+ local( $reflectionVector ) = shift;
+ local( $sphereMapTexCoords ) = shift;
+
+ local( $tmp ); &AllocateRegister( \$tmp );
+
+ ; transform reflection vector into view space
+ dp3 $tmp.x, $reflectionVector, $cViewModel0
+ dp3 $tmp.y, $reflectionVector, $cViewModel1
+ dp3 $tmp.z, $reflectionVector, $cViewModel2
+
+ ; generate <rx ry rz+1>
+ add $tmp.z, $tmp.z, $cOne
+
+ ; find 1 / the length of r2
+ dp3 $tmp.w, $tmp, $tmp
+ rsq $tmp.w, $tmp.w
+
+ ; r1 = r2/|r2| + 1
+ mad $tmp.xy, $tmp.w, $tmp, $cOne
+ mul $sphereMapTexCoords.xy, $tmp.xy, $cHalf
+
+ &FreeRegister( \$tmp );
+}
+
+sub SkinPosition
+{
+# print "\$SKINNING = $SKINNING\n";
+ local( $worldPos ) = shift;
+
+ if( !defined $SKINNING )
+ {
+ die "using \$SKINNING without defining.\n";
+ }
+
+ if( $SKINNING == 0 )
+ {
+ ;
+ ; 0 bone skinning (4 instructions)
+ ;
+ ; Transform position into world space
+ ; position
+ dp4 $worldPos.x, $vPos, $cModel0
+ dp4 $worldPos.y, $vPos, $cModel1
+ dp4 $worldPos.z, $vPos, $cModel2
+ mov $worldPos.w, $cOne
+ }
+ else
+ {
+ ;
+ ; 3 bone skinning (19 instructions)
+ ;
+ local( $boneIndices );
+ local( $blendedMatrix0 );
+ local( $blendedMatrix1 );
+ local( $blendedMatrix2 );
+ local( $localPos );
+ &AllocateRegister( \$boneIndices );
+ &AllocateRegister( \$blendedMatrix0 );
+ &AllocateRegister( \$blendedMatrix1 );
+ &AllocateRegister( \$blendedMatrix2 );
+
+ ; Transform position into world space using all bones
+ ; denormalize d3dcolor to matrix index
+ mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index
+ if ( $g_x360 )
+ {
+ mov $boneIndices, $boneIndices.zyxw
+ }
+
+ ; r11 = boneindices at this point
+ ; first matrix
+ mov a0.x, $boneIndices.z
+ mul $blendedMatrix0, $vBoneWeights.x, c[a0.x]
+ mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1]
+ mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2]
+ ; second matrix
+ mov a0.x, $boneIndices.y
+ mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2
+
+ ; Calculate third weight
+ ; compute 1-(weight1+weight2) to calculate weight2
+ ; Use $boneIndices.w as a temp since we aren't using it for anything.
+ add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y
+ sub $boneIndices.w, $cOne, $boneIndices.w
+
+ ; third matrix
+ mov a0.x, $boneIndices.x
+ mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2
+
+ dp4 $worldPos.x, $vPos, $blendedMatrix0
+ dp4 $worldPos.y, $vPos, $blendedMatrix1
+ dp4 $worldPos.z, $vPos, $blendedMatrix2
+ mov $worldPos.w, $cOne
+
+ &FreeRegister( \$boneIndices );
+ &FreeRegister( \$blendedMatrix0 );
+ &FreeRegister( \$blendedMatrix1 );
+ &FreeRegister( \$blendedMatrix2 );
+ }
+}
+
+
+sub SkinPositionAndNormal
+{
+# print "\$SKINNING = $SKINNING\n";
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+
+ if( !defined $SKINNING )
+ {
+ die "using \$SKINNING without defining.\n";
+ }
+
+ if( $SKINNING == 0 )
+ {
+ ;
+ ; 0 bone skinning (13 instructions)
+ ;
+ ; Transform position + normal + tangentS + tangentT into world space
+ ; position
+ dp4 $worldPos.x, $vPos, $cModel0
+ dp4 $worldPos.y, $vPos, $cModel1
+ dp4 $worldPos.z, $vPos, $cModel2
+ mov $worldPos.w, $cOne
+ ; normal
+ dp3 $worldNormal.x, $vNormal, $cModel0
+ dp3 $worldNormal.y, $vNormal, $cModel1
+ dp3 $worldNormal.z, $vNormal, $cModel2
+ }
+ else
+ {
+ local( $boneIndices );
+ local( $blendedMatrix0 );
+ local( $blendedMatrix1 );
+ local( $blendedMatrix2 );
+ local( $localPos );
+ local( $localNormal );
+ local( $normalLength );
+ local( $ooNormalLength );
+ &AllocateRegister( \$boneIndices );
+ &AllocateRegister( \$blendedMatrix0 );
+ &AllocateRegister( \$blendedMatrix1 );
+ &AllocateRegister( \$blendedMatrix2 );
+
+ ; Transform position into world space using all bones
+ ; denormalize d3dcolor to matrix index
+ mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index
+ if ( $g_x360 )
+ {
+ mov $boneIndices, $boneIndices.zyxw
+ }
+
+ ; r11 = boneindices at this point
+ ; first matrix
+ mov a0.x, $boneIndices.z
+ mul $blendedMatrix0, $vBoneWeights.x, c[a0.x]
+ mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1]
+ mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2]
+ ; second matrix
+ mov a0.x, $boneIndices.y
+ mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2
+
+ ; Calculate third weight
+ ; compute 1-(weight1+weight2) to calculate weight2
+ ; Use $boneIndices.w as a temp since we aren't using it for anything.
+ add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y
+ sub $boneIndices.w, $cOne, $boneIndices.w
+
+ ; third matrix
+ mov a0.x, $boneIndices.x
+ mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2
+
+ dp4 $worldPos.x, $vPos, $blendedMatrix0
+ dp4 $worldPos.y, $vPos, $blendedMatrix1
+ dp4 $worldPos.z, $vPos, $blendedMatrix2
+ mov $worldPos.w, $cOne
+
+ ; normal
+ dp3 $worldNormal.x, $vNormal, $blendedMatrix0
+ dp3 $worldNormal.y, $vNormal, $blendedMatrix1
+ dp3 $worldNormal.z, $vNormal, $blendedMatrix2
+
+ &FreeRegister( \$boneIndices );
+ &FreeRegister( \$blendedMatrix0 );
+ &FreeRegister( \$blendedMatrix1 );
+ &FreeRegister( \$blendedMatrix2 );
+ }
+}
+
+sub SkinPositionNormalAndTangentSpace
+{
+# print "\$SKINNING = $SKINNING\n";
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $worldTangentS ) = shift;
+ local( $worldTangentT ) = shift;
+ local( $userData );
+ local( $localPos );
+ local( $localNormal );
+ local( $normalLength );
+ local( $ooNormalLength );
+
+ if( !defined $SKINNING )
+ {
+ die "using \$SKINNING without defining.\n";
+ }
+
+# X360TBD: needed for compressed vertex format
+# if ( $g_x360 )
+# {
+# &AllocateRegister( \$userData );
+# ; remap compressed range [0..1] to [-1..1]
+# mad $userData, $vUserData, $cTwo, -$cOne
+# }
+
+ if( $SKINNING == 0 )
+ {
+ ;
+ ; 0 bone skinning (13 instructions)
+ ;
+ ; Transform position + normal + tangentS + tangentT into world space
+ dp4 $worldPos.x, $vPos, $cModel0
+ dp4 $worldPos.y, $vPos, $cModel1
+ dp4 $worldPos.z, $vPos, $cModel2
+ mov $worldPos.w, $cOne
+
+ ; normal
+ dp3 $worldNormal.x, $vNormal, $cModel0
+ dp3 $worldNormal.y, $vNormal, $cModel1
+ dp3 $worldNormal.z, $vNormal, $cModel2
+
+# X360TBD: needed for compressed vertex format
+# if ( $g_x360 )
+# {
+# ; tangents
+# dp3 $worldTangentS.x, $userData, $cModel0
+# dp3 $worldTangentS.y, $userData, $cModel1
+# dp3 $worldTangentS.z, $userData, $cModel2
+#
+# ; calculate tangent t via cross( N, S ) * S[3]
+# &Cross( $worldTangentT, $worldNormal, $worldTangentS );
+# mul $worldTangentT.xyz, $userData.w, $worldTangentT.xyz
+# }
+# else
+ {
+ ; tangents
+ dp3 $worldTangentS.x, $vUserData, $cModel0
+ dp3 $worldTangentS.y, $vUserData, $cModel1
+ dp3 $worldTangentS.z, $vUserData, $cModel2
+
+ ; calculate tangent t via cross( N, S ) * S[3]
+ &Cross( $worldTangentT, $worldNormal, $worldTangentS );
+ mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz
+ }
+ }
+ else
+ {
+ local( $boneIndices );
+ local( $blendedMatrix0 );
+ local( $blendedMatrix1 );
+ local( $blendedMatrix2 );
+ &AllocateRegister( \$boneIndices );
+ &AllocateRegister( \$blendedMatrix0 );
+ &AllocateRegister( \$blendedMatrix1 );
+ &AllocateRegister( \$blendedMatrix2 );
+
+ ; Transform position into world space using all bones
+ ; denormalize d3dcolor to matrix index
+ mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index
+ if ( $g_x360 )
+ {
+ mov $boneIndices, $boneIndices.zyxw
+ }
+
+ ; r11 = boneindices at this point
+ ; first matrix
+ mov a0.x, $boneIndices.z
+ mul $blendedMatrix0, $vBoneWeights.x, c[a0.x]
+ mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1]
+ mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2]
+ ; second matrix
+ mov a0.x, $boneIndices.y
+ mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2
+
+ ; Calculate third weight
+ ; compute 1-(weight1+weight2) to calculate weight2
+ ; Use $boneIndices.w as a temp since we aren't using it for anything.
+ add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y
+ sub $boneIndices.w, $cOne, $boneIndices.w
+
+ ; third matrix
+ mov a0.x, $boneIndices.x
+ mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0
+ mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1
+ mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2
+
+ ; position
+ dp4 $worldPos.x, $vPos, $blendedMatrix0
+ dp4 $worldPos.y, $vPos, $blendedMatrix1
+ dp4 $worldPos.z, $vPos, $blendedMatrix2
+ mov $worldPos.w, $cOne
+
+ ; normal
+ dp3 $worldNormal.x, $vNormal, $blendedMatrix0
+ dp3 $worldNormal.y, $vNormal, $blendedMatrix1
+ dp3 $worldNormal.z, $vNormal, $blendedMatrix2
+
+# X360TBD: needed for compressed vertex format
+# if ( $g_x360 )
+# {
+# ; tangents
+# dp3 $worldTangentS.x, $userData, $blendedMatrix0
+# dp3 $worldTangentS.y, $userData, $blendedMatrix1
+# dp3 $worldTangentS.z, $userData, $blendedMatrix2
+#
+# ; calculate tangent t via cross( N, S ) * S[3]
+# &Cross( $worldTangentT, $worldNormal, $worldTangentS );
+# mul $worldTangentT.xyz, $userData.w, $worldTangentT.xyz
+# }
+# else
+ {
+ ; tangents
+ dp3 $worldTangentS.x, $vUserData, $blendedMatrix0
+ dp3 $worldTangentS.y, $vUserData, $blendedMatrix1
+ dp3 $worldTangentS.z, $vUserData, $blendedMatrix2
+
+ ; calculate tangent t via cross( N, S ) * S[3]
+ &Cross( $worldTangentT, $worldNormal, $worldTangentS );
+ mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz
+ }
+
+ &FreeRegister( \$boneIndices );
+ &FreeRegister( \$blendedMatrix0 );
+ &FreeRegister( \$blendedMatrix1 );
+ &FreeRegister( \$blendedMatrix2 );
+ }
+
+# X360TBD: needed for compressed vertex format
+# if ( $g_x360 )
+# {
+# &FreeRegister( \$userData );
+# }
+}
+
+sub ColorClamp
+{
+ ; ColorClamp; stomps $color.w
+ local( $color ) = shift;
+ local( $dst ) = shift;
+
+ ; Get the max of RGB and stick it in W
+ max $color.w, $color.x, $color.y
+ max $color.w, $color.w, $color.z
+
+ ; get the greater of one and the max color.
+ max $color.w, $color.w, $cOne
+
+ rcp $color.w, $color.w
+ mul $dst.xyz, $color.w, $color.xyz
+}
+
+sub AmbientLight
+{
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+ local( $add ) = shift;
+
+ ; Ambient lighting
+ &AllocateRegister( \$nSquared );
+ &AllocateRegister( \$isNegative );
+
+ mul $nSquared.xyz, $worldNormal.xyz, $worldNormal.xyz ; compute n times n
+ slt $isNegative.xyz, $worldNormal.xyz, $cZero ; Figure out whether each component is >0
+ mov a0.x, $isNegative.x
+ if( $add )
+ {
+ mad $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset], $linearColor ; $linearColor = normal[0]*normal[0] * box color of appropriate x side
+ }
+ else
+ {
+ mul $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset] ; $linearColor = normal[0]*normal[0] * box color of appropriate x side
+ }
+ mov a0.x, $isNegative.y
+ mad $linearColor.xyz, $nSquared.y, c[a0.x + $cAmbientColorPosYOffset], $linearColor
+ mov a0.x, $isNegative.z
+ mad $linearColor.xyz, $nSquared.z, c[a0.x + $cAmbientColorPosZOffset], $linearColor
+
+ &FreeRegister( \$isNegative );
+ &FreeRegister( \$nSquared );
+}
+
+sub DirectionalLight
+{
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+ local( $add ) = shift;
+
+ &AllocateRegister( \$nDotL ); # FIXME: This only needs to be a scalar
+
+ ; NOTE: Gotta use -l here, since light direction = -l
+ ; DIRECTIONAL LIGHT
+ ; compute n dot l
+ dp3 $nDotL.x, -c[a0.x + 1], $worldNormal
+
+ if ( $HALF_LAMBERT == 0 )
+ {
+ ; lambert
+ max $nDotL.x, $nDotL.x, c0.x ; Clamp to zero
+ }
+ elsif ( $HALF_LAMBERT == 1 )
+ {
+ ; half-lambert
+ mad $nDotL.x, $nDotL.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5)^2
+ mul $nDotL.x, $nDotL.x, $nDotL.x
+ }
+ else
+ {
+ die "\$HALF_LAMBERT is hosed\n";
+ }
+
+ if( $add )
+ {
+ mad $linearColor.xyz, c[a0.x], $nDotL.x, $linearColor
+ }
+ else
+ {
+ mul $linearColor.xyz, c[a0.x], $nDotL.x
+ }
+
+ &FreeRegister( \$nDotL );
+}
+
+sub PointLight
+{
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+ local( $add ) = shift;
+
+ local( $lightDir );
+ &AllocateRegister( \$lightDir );
+
+ ; POINT LIGHT
+ ; compute light direction
+ sub $lightDir, c[a0.x+2], $worldPos
+
+ local( $lightDistSquared );
+ local( $ooLightDist );
+ &AllocateRegister( \$lightDistSquared );
+ &AllocateRegister( \$ooLightDist );
+
+ ; normalize light direction, maintain temporaries for attenuation
+ dp3 $lightDistSquared, $lightDir, $lightDir
+ rsq $ooLightDist, $lightDistSquared.x
+ mul $lightDir, $lightDir, $ooLightDist.x
+
+ local( $attenuationFactors );
+ &AllocateRegister( \$attenuationFactors );
+
+ ; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d')
+ dst $attenuationFactors, $lightDistSquared, $ooLightDist ; r4 = ( 1, d, d*d, 1/d )
+ &FreeRegister( \$lightDistSquared );
+ &FreeRegister( \$ooLightDist );
+ local( $attenuation );
+ &AllocateRegister( \$attenuation );
+ dp3 $attenuation, $attenuationFactors, c[a0.x+4] ; r3 = atten0 + d * atten1 + d*d * atten2
+
+ rcp $lightDir.w, $attenuation ; $lightDir.w = 1 / (atten0 + d * atten1 + d*d * atten2)
+
+ &FreeRegister( \$attenuationFactors );
+ &FreeRegister( \$attenuation );
+
+ local( $tmp );
+ &AllocateRegister( \$tmp ); # FIXME : really only needs to be a scalar
+
+ ; compute n dot l, fold in distance attenutation
+ dp3 $tmp.x, $lightDir, $worldNormal
+
+ if ( $HALF_LAMBERT == 0 )
+ {
+ ; lambert
+ max $tmp.x, $tmp.x, c0.x ; Clamp to zero
+ }
+ elsif ( $HALF_LAMBERT == 1 )
+ {
+ ; half-lambert
+ mad $tmp.x, $tmp.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5)^2
+ mul $tmp.x, $tmp.x, $tmp.x
+ }
+ else
+ {
+ die "\$HALF_LAMBERT is hosed\n";
+ }
+
+ mul $tmp.x, $tmp.x, $lightDir.w
+ if( $add )
+ {
+ mad $linearColor.xyz, c[a0.x], $tmp.x, $linearColor
+ }
+ else
+ {
+ mul $linearColor.xyz, c[a0.x], $tmp.x
+ }
+
+ &FreeRegister( \$lightDir );
+ &FreeRegister( \$tmp ); # FIXME : really only needs to be a scalar
+}
+
+sub SpotLight
+{
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+ local( $add ) = shift;
+
+ local( $lightDir );
+ &AllocateRegister( \$lightDir );
+
+ ; SPOTLIGHT
+ ; compute light direction
+ sub $lightDir, c[a0.x+2], $worldPos
+
+ local( $lightDistSquared );
+ local( $ooLightDist );
+ &AllocateRegister( \$lightDistSquared );
+ &AllocateRegister( \$ooLightDist );
+
+ ; normalize light direction, maintain temporaries for attenuation
+ dp3 $lightDistSquared, $lightDir, $lightDir
+ rsq $ooLightDist, $lightDistSquared.x
+ mul $lightDir, $lightDir, $ooLightDist.x
+
+ local( $attenuationFactors );
+ &AllocateRegister( \$attenuationFactors );
+
+ ; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d')
+ dst $attenuationFactors, $lightDistSquared, $ooLightDist ; r4 = ( 1, d, d*d, 1/d )
+
+ &FreeRegister( \$lightDistSquared );
+ &FreeRegister( \$ooLightDist );
+ local( $attenuation ); &AllocateRegister( \$attenuation );
+
+ dp3 $attenuation, $attenuationFactors, c[a0.x+4] ; r3 = atten0 + d * atten1 + d*d * atten2
+ rcp $lightDir.w, $attenuation ; r1.w = 1 / (atten0 + d * atten1 + d*d * atten2)
+
+ &FreeRegister( \$attenuationFactors );
+ &FreeRegister( \$attenuation );
+
+ local( $litSrc ); &AllocateRegister( \$litSrc );
+ local( $tmp ); &AllocateRegister( \$tmp ); # FIXME - only needs to be scalar
+
+ ; compute n dot l
+ dp3 $litSrc.x, $worldNormal, $lightDir
+
+ if ( $HALF_LAMBERT == 0 )
+ {
+ ; lambert
+ max $litSrc.x, $litSrc.x, c0.x ; Clamp to zero
+ }
+ elsif ( $HALF_LAMBERT == 1 )
+ {
+ ; half-lambert
+ mad $litSrc.x, $litSrc.x, $cHalf, $cHalf ; dot = (dot * 0.5 + 0.5) ^ 2
+ mul $litSrc.x, $litSrc.x, $litSrc.x
+ }
+ else
+ {
+ die "\$HALF_LAMBERT is hosed\n";
+ }
+
+ ; compute angular attenuation
+ dp3 $tmp.x, c[a0.x+1], -$lightDir ; dot = -delta * spot direction
+ sub $litSrc.y, $tmp.x, c[a0.x+3].z ; r2.y = dot - stopdot2
+ &FreeRegister( \$tmp );
+ mul $litSrc.y, $litSrc.y, c[a0.x+3].w ; r2.y = (dot - stopdot2) / (stopdot - stopdot2)
+ mov $litSrc.w, c[a0.x+3].x ; r2.w = exponent
+ local( $litDst ); &AllocateRegister( \$litDst );
+ lit $litDst, $litSrc ; r3.y = N dot L or 0, whichever is bigger
+ &FreeRegister( \$litSrc );
+ ; r3.z = pow((dot - stopdot2) / (stopdot - stopdot2), exponent)
+ min $litDst.z, $litDst.z, $cOne ; clamp pow() to 1
+
+ local( $tmp1 ); &AllocateRegister( \$tmp1 );
+ local( $tmp2 ); &AllocateRegister( \$tmp2 ); # FIXME - could be scalar
+
+ ; fold in distance attenutation with other factors
+ mul $tmp1, c[a0.x], $lightDir.w
+ mul $tmp2.x, $litDst.y, $litDst.z
+ if( $add )
+ {
+ mad $linearColor.xyz, $tmp1, $tmp2.x, $linearColor
+ }
+ else
+ {
+ mul $linearColor.xyz, $tmp1, $tmp2.x
+ }
+
+ &FreeRegister( \$lightDir );
+ &FreeRegister( \$litDst );
+ &FreeRegister( \$tmp1 );
+ &FreeRegister( \$tmp2 );
+}
+
+sub DoLight
+{
+ local( $lightType ) = shift;
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+ local( $add ) = shift;
+
+ if( $lightType eq "spot" )
+ {
+ &SpotLight( $worldPos, $worldNormal, $linearColor, $add );
+ }
+ elsif( $lightType eq "point" )
+ {
+ &PointLight( $worldPos, $worldNormal, $linearColor, $add );
+ }
+ elsif( $lightType eq "directional" )
+ {
+ &DirectionalLight( $worldNormal, $linearColor, $add );
+ }
+ else
+ {
+ die "don't know about light type \"$lightType\"\n";
+ }
+}
+
+sub DoLighting
+{
+ if( !defined $LIGHT_COMBO )
+ {
+ die "DoLighting called without using \$LIGHT_COMBO\n";
+ }
+ if ( !defined $HALF_LAMBERT )
+ {
+ die "DoLighting called without using \$HALF_LAMBERT\n";
+ }
+
+ my $staticLightType = $g_staticLightTypeArray[$LIGHT_COMBO];
+ my $ambientLightType = $g_ambientLightTypeArray[$LIGHT_COMBO];
+ my $localLightType1 = $g_localLightType1Array[$LIGHT_COMBO];
+ my $localLightType2 = $g_localLightType2Array[$LIGHT_COMBO];
+
+# print "\$staticLightType = $staticLightType\n";
+# print "\$ambientLightType = $ambientLightType\n";
+# print "\$localLightType1 = $localLightType1\n";
+# print "\$localLightType2 = $localLightType2\n";
+
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+
+ ; special case for no lighting
+ if( $staticLightType eq "none" && $ambientLightType eq "none" &&
+ $localLightType1 eq "none" && $localLightType2 eq "none" )
+ {
+ ; Have to write something here since debug d3d runtime will barf otherwise.
+ mov oD0, $cOne
+ return;
+ }
+
+ ; special case for static lighting only
+ ; Don't need to bother converting to linear space in this case.
+ if( $staticLightType eq "static" && $ambientLightType eq "none" &&
+ $localLightType1 eq "none" && $localLightType2 eq "none" )
+ {
+ mov oD0, $vSpecular
+ return;
+ }
+
+ alloc $linearColor
+ alloc $gammaColor
+
+ local( $add ) = 0;
+ if( $staticLightType eq "static" )
+ {
+ ; The static lighting comes in in gamma space and has also been premultiplied by $cOverbrightFactor
+ ; need to get it into
+ ; linear space so that we can do adds.
+ rcp $gammaColor.w, $cOverbrightFactor
+ mul $gammaColor.xyz, $vSpecular, $gammaColor.w
+ &GammaToLinear( $gammaColor, $linearColor );
+ $add = 1;
+ }
+
+ if( $ambientLightType eq "ambient" )
+ {
+ &AmbientLight( $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+
+ if( $localLightType1 ne "none" )
+ {
+ mov a0.x, $cLight0Offset
+ &DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+
+ if( $localLightType2 ne "none" )
+ {
+ mov a0.x, $cLight1Offset
+ &DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+
+ ;------------------------------------------------------------------------------
+ ; Output color (gamma correction)
+ ;------------------------------------------------------------------------------
+
+ &LinearToGamma( $linearColor, $gammaColor );
+ if( 0 )
+ {
+ mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor
+ }
+ else
+ {
+ mul $gammaColor.xyz, $gammaColor.xyz, $cOverbrightFactor
+ &ColorClamp( $gammaColor, "oD0" );
+ }
+
+; mov oD0.xyz, $linearColor
+ mov oD0.w, $cOne ; make sure all components are defined
+
+ free $linearColor
+ free $gammaColor
+}
+
+sub DoDynamicLightingToLinear
+{
+ local( $worldPos ) = shift;
+ local( $worldNormal ) = shift;
+ local( $linearColor ) = shift;
+
+ if( !defined $LIGHT_COMBO )
+ {
+ die "DoLighting called without using \$LIGHT_COMBO\n";
+ }
+ if ( !defined $HALF_LAMBERT )
+ {
+ die "DoLighting called without using \$HALF_LAMBERT\n";
+ }
+
+ my $staticLightType = $g_staticLightTypeArray[$LIGHT_COMBO];
+ my $ambientLightType = $g_ambientLightTypeArray[$LIGHT_COMBO];
+ my $localLightType1 = $g_localLightType1Array[$LIGHT_COMBO];
+ my $localLightType2 = $g_localLightType2Array[$LIGHT_COMBO];
+
+ # No lights at all. . note that we don't even consider static lighting here.
+ if( $ambientLightType eq "none" &&
+ $localLightType1 eq "none" && $localLightType2 eq "none" )
+ {
+ mov $linearColor, $cZero
+ return;
+ }
+
+ local( $add ) = 0;
+ if( $ambientLightType eq "ambient" )
+ {
+ &AmbientLight( $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+
+ if( $localLightType1 ne "none" )
+ {
+ mov a0.x, $cLight0Offset
+ &DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+
+ if( $localLightType2 ne "none" )
+ {
+ mov a0.x, $cLight1Offset
+ &DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add );
+ $add = 1;
+ }
+}
+
+sub NotImplementedYet
+{
+ &AllocateRegister( \$projPos );
+ dp4 $projPos.x, $worldPos, $cViewProj0
+ dp4 $projPos.y, $worldPos, $cViewProj1
+ dp4 $projPos.z, $worldPos, $cViewProj2
+ dp4 $projPos.w, $worldPos, $cViewProj3
+ mov oPos, $projPos
+ &FreeRegister( \$projPos );
+ exit;
+}
diff --git a/mp/src/materialsystem/stdshaders/shader_constant_register_map.h b/mp/src/materialsystem/stdshaders/shader_constant_register_map.h new file mode 100644 index 00000000..485bb7c4 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/shader_constant_register_map.h @@ -0,0 +1,81 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Provide convenient mapping for shader constants
+//
+// $NoKeywords: $
+//=============================================================================
+
+#ifndef C_CODE_HACK
+#include "common_vertexlitgeneric_dx9.h"
+#endif
+
+#define PSREG_SELFILLUMTINT PSREG_CONSTANT_00
+#define PSREG_DIFFUSE_MODULATION PSREG_CONSTANT_01
+#define PSREG_ENVMAP_TINT__SHADOW_TWEAKS PSREG_CONSTANT_02
+#define PSREG_SELFILLUM_SCALE_BIAS_EXP PSREG_CONSTANT_03
+#define PSREG_AMBIENT_CUBE PSREG_CONSTANT_04
+// PSREG_AMBIENT_CUBE PSREG_CONSTANT_05
+// PSREG_AMBIENT_CUBE PSREG_CONSTANT_06
+// PSREG_AMBIENT_CUBE PSREG_CONSTANT_07
+// PSREG_AMBIENT_CUBE PSREG_CONSTANT_08
+// PSREG_AMBIENT_CUBE PSREG_CONSTANT_09
+#define PSREG_ENVMAP_FRESNEL__SELFILLUMMASK PSREG_CONSTANT_10
+#define PSREG_EYEPOS_SPEC_EXPONENT PSREG_CONSTANT_11
+#define PSREG_FOG_PARAMS PSREG_CONSTANT_12
+#define PSREG_FLASHLIGHT_ATTENUATION PSREG_CONSTANT_13
+#define PSREG_FLASHLIGHT_POSITION_RIM_BOOST PSREG_CONSTANT_14
+#define PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_15
+// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_16
+// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_17
+// PSREG_FLASHLIGHT_TO_WORLD_TEXTURE PSREG_CONSTANT_18
+#define PSREG_FRESNEL_SPEC_PARAMS PSREG_CONSTANT_19
+#define PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_20
+// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_21
+// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_22
+// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_23
+// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_24
+// PSREG_LIGHT_INFO_ARRAY PSREG_CONSTANT_25
+#define PSREG_SPEC_RIM_PARAMS PSREG_CONSTANT_26
+// #define **free** PSREG_CONSTANT_27 //actually using this often blows constant limits, since literals have to get stuffed somewhere...
+#define PSREG_FLASHLIGHT_COLOR PSREG_CONSTANT_28
+#define PSREG_LINEAR_FOG_COLOR PSREG_CONSTANT_29
+#define PSREG_LIGHT_SCALE PSREG_CONSTANT_30
+#define PSREG_FLASHLIGHT_SCREEN_SCALE PSREG_CONSTANT_31
+// --- End of ps_2_0 and ps_2_b constants ---
+
+
+#ifndef C_CODE_HACK
+//for fxc code, map the constants to register names.
+#define PSREG_CONSTANT_00 c0
+#define PSREG_CONSTANT_01 c1
+#define PSREG_CONSTANT_02 c2
+#define PSREG_CONSTANT_03 c3
+#define PSREG_CONSTANT_04 c4
+#define PSREG_CONSTANT_05 c5
+#define PSREG_CONSTANT_06 c6
+#define PSREG_CONSTANT_07 c7
+#define PSREG_CONSTANT_08 c8
+#define PSREG_CONSTANT_09 c9
+#define PSREG_CONSTANT_10 c10
+#define PSREG_CONSTANT_11 c11
+#define PSREG_CONSTANT_12 c12
+#define PSREG_CONSTANT_13 c13
+#define PSREG_CONSTANT_14 c14
+#define PSREG_CONSTANT_15 c15
+#define PSREG_CONSTANT_16 c16
+#define PSREG_CONSTANT_17 c17
+#define PSREG_CONSTANT_18 c18
+#define PSREG_CONSTANT_19 c19
+#define PSREG_CONSTANT_20 c20
+#define PSREG_CONSTANT_21 c21
+#define PSREG_CONSTANT_22 c22
+#define PSREG_CONSTANT_23 c23
+#define PSREG_CONSTANT_24 c24
+#define PSREG_CONSTANT_25 c25
+#define PSREG_CONSTANT_26 c26
+#define PSREG_CONSTANT_27 c27
+#define PSREG_CONSTANT_28 c28
+#define PSREG_CONSTANT_29 c29
+#define PSREG_CONSTANT_30 c30
+#define PSREG_CONSTANT_31 c31
+#endif
diff --git a/mp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt b/mp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt new file mode 100644 index 00000000..f70ae0a2 --- /dev/null +++ b/mp/src/materialsystem/stdshaders/stdshader_dx9_20b.txt @@ -0,0 +1,11 @@ +//
+// Standard shaders collection
+//
+// These shaders are compiled as the following shader models:
+// _ps20.vcs
+// _ps20b.vcs
+// _vs20.vcs
+//
+
+example_model_ps20b.fxc
+example_model_vs20.fxc
diff --git a/mp/src/materialsystem/stdshaders/stdshader_dx9_30.txt b/mp/src/materialsystem/stdshaders/stdshader_dx9_30.txt new file mode 100644 index 00000000..5a09a37b --- /dev/null +++ b/mp/src/materialsystem/stdshaders/stdshader_dx9_30.txt @@ -0,0 +1,10 @@ +//
+// vs 3.0 ps 3.0 shaders collection
+//
+// These shaders are forced to compile as shader model 3.0
+// using the new compiler.
+// _ps30.vcs
+// _vs30.vcs
+//
+
+// There are no examples of such shaders in the SDK, but add yours here.
diff --git a/mp/src/public/appframework/ilaunchermgr.h b/mp/src/public/appframework/ilaunchermgr.h index 5d38b15a..7fa5dc76 100644 --- a/mp/src/public/appframework/ilaunchermgr.h +++ b/mp/src/public/appframework/ilaunchermgr.h @@ -10,7 +10,7 @@ #pragma once
#endif
-#if defined( USE_SDL ) || defined( OSX )
+#if defined( USE_SDL )
#include "tier0/threadtools.h"
#include "appframework/IAppSystem.h"
@@ -29,18 +29,12 @@ class CShowPixelsParams; #endif
// if you rev this version also update materialsystem/cmaterialsystem.cpp CMaterialSystem::Connect as it defines the string directly
-#if defined( USE_SDL )
- #define SDLMGR_INTERFACE_VERSION "SDLMgrInterface001"
-#elif defined( OSX )
- #define COCOAMGR_INTERFACE_VERSION "CocoaMgrInterface006"
-#endif
+#define SDLMGR_INTERFACE_VERSION "SDLMgrInterface001"
class CCocoaEvent;
class CStackCrawlParams;
-#if defined( USE_SDL )
typedef struct SDL_Cursor SDL_Cursor;
-#endif
class ILauncherMgr : public IAppSystem
{
@@ -103,11 +97,9 @@ public: virtual void *GetWindowRef() = 0;
virtual void SetMouseVisible( bool bState ) = 0;
-#ifdef USE_SDL
virtual void SetMouseCursor( SDL_Cursor *hCursor ) = 0;
virtual void SetForbidMouseGrab( bool bForbidMouseGrab ) = 0;
virtual void OnFrameRendered() = 0;
-#endif
virtual void SetGammaRamp( const uint16 *pRed, const uint16 *pGreen, const uint16 *pBlue ) = 0;
@@ -163,6 +155,6 @@ public: int m_MouseButton; // which of the CocoaMouseButton_t buttons this is for from above
};
-#endif // USE_SDL || OSX
+#endif // defined( USE_SDL )
#endif // ILAUNCHERMGR_H
diff --git a/mp/src/public/cdll_int.h b/mp/src/public/cdll_int.h index 1757d5d7..1801c383 100644 --- a/mp/src/public/cdll_int.h +++ b/mp/src/public/cdll_int.h @@ -525,7 +525,7 @@ public: virtual void SetGamestatsData( CGamestatsData *pGamestatsData ) = 0;
virtual CGamestatsData *GetGamestatsData() = 0;
-#if defined( USE_SDL ) || defined( OSX )
+#if defined( USE_SDL )
// we need to pull delta's from the cocoa mgr, the engine vectors this for us
virtual void GetMouseDelta( int &x, int &y, bool bIgnoreNextMouseDelta = false ) = 0;
#endif
diff --git a/mp/src/public/eiface.h b/mp/src/public/eiface.h index ea0a4ab7..821df8d6 100644 --- a/mp/src/public/eiface.h +++ b/mp/src/public/eiface.h @@ -407,6 +407,9 @@ public: // Server version from the steam.inf, this will be compared to the GC version
virtual int GetServerVersion() const = 0;
+
+ // Get sv.GetTime()
+ virtual float GetServerTime() const = 0;
};
diff --git a/mp/src/public/engine/ivdebugoverlay.h b/mp/src/public/engine/ivdebugoverlay.h index 51aeafd1..0b24c777 100644 --- a/mp/src/public/engine/ivdebugoverlay.h +++ b/mp/src/public/engine/ivdebugoverlay.h @@ -25,7 +25,7 @@ class Vector; // When used as a duration by a server-side NDebugOverlay:: call,
// causes the overlay to persist until the next server update.
-#define NDEBUG_PERSIST_TILL_NEXT_SERVER (0.01023f)
+#define NDEBUG_PERSIST_TILL_NEXT_SERVER (0.0f)
class OverlayText_t;
diff --git a/mp/src/public/headtrack/iheadtrack.h b/mp/src/public/headtrack/iheadtrack.h deleted file mode 100644 index 4f5fcced..00000000 --- a/mp/src/public/headtrack/iheadtrack.h +++ /dev/null @@ -1,84 +0,0 @@ -//===== Copyright (c), Valve Corporation, All rights reserved. ======//
-//
-// Purpose: Contains the IHeadTrack interface, which is implemented in headtrack.dll
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef IHEADTRACK_H
-#define IHEADTRACK_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier1/interface.h"
-#include "tier1/refcount.h"
-#include "appframework/IAppSystem.h"
-#include "mathlib/vmatrix.h"
-#include "view_shared.h"
-
-//-----------------------------------------------------------------------------
-// forward declarations
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// important enumeration
-//-----------------------------------------------------------------------------
-
-// NOTE NOTE NOTE!!!! If you up this, grep for "NEW_INTERFACE" to see if there is anything
-// waiting to be enabled during an interface revision.
-#define HEAD_TRACK_INTERFACE_VERSION "VHeadTrack001"
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-abstract_class IHeadTrack : public IAppSystem
-{
-public:
- virtual ~IHeadTrack() {}
-
- // Placeholder for API revision
- virtual bool Connect( CreateInterfaceFn factory ) = 0;
- virtual void Disconnect() = 0;
- virtual void *QueryInterface( const char *pInterfaceName ) = 0;
- virtual InitReturnVal_t Init() = 0;
- virtual void Shutdown() = 0;
-
- //-----------------------------------------------------------------------------
- // Tracking section
- //-----------------------------------------------------------------------------
- // All methods return true on success, false on failure.
-
- // Also sets the zero pose
- virtual bool ResetTracking() = 0;
-
- // Set the current pose as the "zero"
- virtual bool SetCurrentCameraAsZero() = 0;
-
- // Raw interfaces - one one or other of these, not both (GetCameraPoseZeroFromCurrent calls GetCameraFromWorldPose );
- virtual bool GetCameraFromWorldPose ( VMatrix *pResultCameraFromWorldPose, VMatrix *pResultCameraFromWorldPoseUnpredicted = NULL, double *pflAcquireTime = NULL ) = 0;
- virtual bool GetCameraPoseZeroFromCurrent ( VMatrix *pResultMatrix ) = 0;
-
- // All-in-one interfaces (they call GetCameraPoseZeroFromCurrent)
- // Grabs the current tracking data and sets up state for the Override* calls.
- virtual bool ProcessCurrentTrackingState ( float PlayerGameFov ) = 0;
-
- // Performs the distortion post-processing.
- virtual bool DoDistortionProcessing ( const vrect_t *SrcRect ) = 0;
-
-};
-
-
-
-//-----------------------------------------------------------------------------
-
-extern IHeadTrack *g_pHeadTrack;
-
-inline bool UseHeadTracking()
-{
- return g_pHeadTrack != NULL;
-}
-#endif // IHEADTRACK_H
diff --git a/mp/src/public/materialsystem/materialsystem_config.h b/mp/src/public/materialsystem/materialsystem_config.h index 1cdca782..1a8d1d1d 100644 --- a/mp/src/public/materialsystem/materialsystem_config.h +++ b/mp/src/public/materialsystem/materialsystem_config.h @@ -32,6 +32,7 @@ enum MaterialSystem_Config_Flags_t MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE = ( 1 << 13 ),
MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION = ( 1 << 14 ),
MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS = ( 1 << 15 ),
+ MATSYS_VIDCFG_FLAGS_DISABLE_PHONG = ( 1 << 16 ),
};
struct MaterialSystemHardwareIdentifier_t
@@ -62,6 +63,7 @@ struct MaterialSystem_Config_t bool LimitWindowedSize() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE ) != 0; }
bool ScaleToOutputResolution() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION ) != 0; }
bool UsingMultipleWindows() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS ) != 0; }
+ bool UsePhong() const { return ( m_Flags & MATSYS_VIDCFG_FLAGS_DISABLE_PHONG ) == 0; }
bool ShadowDepthTexture() const { return m_bShadowDepthTexture; }
bool MotionBlur() const { return m_bMotionBlur; }
bool SupportFlashlight() const { return m_bSupportFlashlight; }
@@ -157,6 +159,7 @@ struct MaterialSystem_Config_t SetFlag( MATSYS_VIDCFG_FLAGS_LIMIT_WINDOWED_SIZE, false );
SetFlag( MATSYS_VIDCFG_FLAGS_SCALE_TO_OUTPUT_RESOLUTION, false );
SetFlag( MATSYS_VIDCFG_FLAGS_USING_MULTIPLE_WINDOWS, false );
+ SetFlag( MATSYS_VIDCFG_FLAGS_DISABLE_PHONG, false );
m_VideoMode.m_Width = 640;
m_VideoMode.m_Height = 480;
diff --git a/mp/src/public/mathlib/mathlib.h b/mp/src/public/mathlib/mathlib.h index 83fdb6a0..e1873cd0 100644 --- a/mp/src/public/mathlib/mathlib.h +++ b/mp/src/public/mathlib/mathlib.h @@ -97,7 +97,9 @@ private: #ifdef DEBUG // stop crashing edit-and-continue
FORCEINLINE float clamp( float val, float minVal, float maxVal )
{
- if( val < minVal )
+ if ( maxVal < minVal )
+ return maxVal;
+ else if( val < minVal )
return minVal;
else if( val > maxVal )
return maxVal;
@@ -115,8 +117,8 @@ FORCEINLINE float clamp( float val, float minVal, float maxVal ) _mm_load_ss(&minVal) ),
_mm_load_ss(&maxVal) ) );
#else
- val = fpmin(maxVal, val);
val = fpmax(minVal, val);
+ val = fpmin(maxVal, val);
#endif
return val;
}
@@ -128,7 +130,9 @@ FORCEINLINE float clamp( float val, float minVal, float maxVal ) template< class T >
inline T clamp( T const &val, T const &minVal, T const &maxVal )
{
- if( val < minVal )
+ if ( maxVal < minVal )
+ return maxVal;
+ else if( val < minVal )
return minVal;
else if( val > maxVal )
return maxVal;
@@ -2172,9 +2176,9 @@ bool AlmostEqual(float a, float b, int maxUlps = 10); inline bool AlmostEqual( const Vector &a, const Vector &b, int maxUlps = 10)
{
- return AlmostEqual( a.x, a.x, maxUlps ) &&
- AlmostEqual( a.y, a.y, maxUlps ) &&
- AlmostEqual( a.z, a.z, maxUlps );
+ return AlmostEqual( a.x, b.x, maxUlps ) &&
+ AlmostEqual( a.y, b.y, maxUlps ) &&
+ AlmostEqual( a.z, b.z, maxUlps );
}
diff --git a/mp/src/public/optimize.h b/mp/src/public/optimize.h index b473a65d..b71dc895 100644 --- a/mp/src/public/optimize.h +++ b/mp/src/public/optimize.h @@ -226,7 +226,7 @@ struct FileHeader_t int maxBonesPerVert;
// must match checkSum in the .mdl
- long checkSum;
+ int checkSum;
int numLODs; // garymcthack - this is also specified in ModelHeader_t and should match
diff --git a/mp/src/public/renderparm.h b/mp/src/public/renderparm.h index 32c0fbc0..91c9cfd5 100644 --- a/mp/src/public/renderparm.h +++ b/mp/src/public/renderparm.h @@ -26,6 +26,7 @@ enum RenderParamVector_t VECTOR_RENDERPARM_HMDWARP_GROW_OUTIN,
VECTOR_RENDERPARM_HMDWARP_GROW_ABOVEBELOW,
VECTOR_RENDERPARM_HMDWARP_ASPECT,
+ INT_RENDERPARM_DISTORTION_TYPE,
MAX_VECTOR_RENDER_PARMS = 20
};
diff --git a/mp/src/public/steam/steam_api.h b/mp/src/public/steam/steam_api.h index fe021f80..e16f226b 100644 --- a/mp/src/public/steam/steam_api.h +++ b/mp/src/public/steam/steam_api.h @@ -512,8 +512,8 @@ inline bool CSteamAPIContext::Init() #if defined(USE_BREAKPAD_HANDLER) || defined(STEAM_API_EXPORTS)
// this should be called before the game initialized the steam APIs
-// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE__ macro )
-// pchTime should be of the format "hh:mm:ss" (such as from the __TIME__ macro )
+// pchDate should be of the format "Mmm dd yyyy" (such as from the __DATE __ macro )
+// pchTime should be of the format "hh:mm:ss" (such as from the __TIME __ macro )
// bFullMemoryDumps (Win32 only) -- writes out a uuid-full.dmp in the client/dumps folder
// pvContext-- can be NULL, will be the void * context passed into m_pfnPreMinidumpCallback
// PFNPreMinidumpCallback m_pfnPreMinidumpCallback -- optional callback which occurs just before a .dmp file is written during a crash. Applications can hook this to allow adding additional information into the .dmp comment stream.
diff --git a/mp/src/public/studio.h b/mp/src/public/studio.h index 7770c2af..9b58ab0c 100644 --- a/mp/src/public/studio.h +++ b/mp/src/public/studio.h @@ -1816,7 +1816,7 @@ struct vertexFileHeader_t DECLARE_BYTESWAP_DATADESC();
int id; // MODEL_VERTEX_FILE_ID
int version; // MODEL_VERTEX_FILE_VERSION
- long checksum; // same as studiohdr_t, ensures sync
+ int checksum; // same as studiohdr_t, ensures sync
int numLODs; // num of valid lods
int numLODVertexes[MAX_NUM_LODS]; // num verts for desired root lod
int numFixups; // num of vertexFileFixup_t
@@ -1991,7 +1991,7 @@ struct studiohdr_t int id;
int version;
- long checksum; // this has to be the same in the phy and vtx files to load!
+ int checksum; // this has to be the same in the phy and vtx files to load!
inline const char * pszName( void ) const { if (studiohdr2index && pStudioHdr2()->pszName()) return pStudioHdr2()->pszName(); else return name; }
char name[64];
diff --git a/mp/src/public/studio_virtualmodel.cpp b/mp/src/public/studio_virtualmodel.cpp index 748ed3b2..269e7cdf 100644 --- a/mp/src/public/studio_virtualmodel.cpp +++ b/mp/src/public/studio_virtualmodel.cpp @@ -572,4 +572,23 @@ void virtualmodel_t::AppendIKLocks( int group, const studiohdr_t *pStudioHdr ) }
m_iklock = iklock;
+
+ // copy knee directions for uninitialized knees
+ if ( group != 0 )
+ {
+ studiohdr_t *pBaseHdr = (studiohdr_t *)m_group[ 0 ].GetStudioHdr();
+ if ( pStudioHdr->numikchains == pBaseHdr->numikchains )
+ {
+ for (j = 0; j < pStudioHdr->numikchains; j++)
+ {
+ if ( pBaseHdr->pIKChain( j )->pLink(0)->kneeDir.LengthSqr() == 0.0f )
+ {
+ if ( pStudioHdr->pIKChain( j )->pLink(0)->kneeDir.LengthSqr() > 0.0f )
+ {
+ pBaseHdr->pIKChain( j )->pLink(0)->kneeDir = pStudioHdr->pIKChain( j )->pLink(0)->kneeDir;
+ }
+ }
+ }
+ }
+ }
}
diff --git a/mp/src/public/tier0/memalloc.h b/mp/src/public/tier0/memalloc.h index 52578760..2840d095 100644 --- a/mp/src/public/tier0/memalloc.h +++ b/mp/src/public/tier0/memalloc.h @@ -535,7 +535,7 @@ inline void MemAlloc_GlobalMemoryStatus( size_t *pusedMemory, size_t *pfreeMemor *pusedMemory = 0;
*pfreeMemory = 0;
}
-#define MemAlloc_MemoryAllocFailed() 1
+#define MemAlloc_MemoryAllocFailed() 0
#define MemAlloc_GetDebugInfoSize() 0
#define MemAlloc_SaveDebugInfo( pvDebugInfo ) ((void)0)
diff --git a/mp/src/public/tier0/platform.h b/mp/src/public/tier0/platform.h index 914cd39a..38e6b563 100644 --- a/mp/src/public/tier0/platform.h +++ b/mp/src/public/tier0/platform.h @@ -1085,7 +1085,7 @@ PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
-PLATFORM_INTERFACE unsigned long Plat_MSTime(); // Time in milliseconds.
+PLATFORM_INTERFACE unsigned int Plat_MSTime(); // Time in milliseconds.
PLATFORM_INTERFACE char * Plat_asctime( const struct tm *tm, char *buf );
PLATFORM_INTERFACE char * Plat_ctime( const time_t *timep, char *buf, size_t bufsize );
PLATFORM_INTERFACE struct tm * Plat_gmtime( const time_t *timep, struct tm *result );
diff --git a/mp/src/public/tier1/checksum_crc.h b/mp/src/public/tier1/checksum_crc.h index a8ef71e5..130577ee 100644 --- a/mp/src/public/tier1/checksum_crc.h +++ b/mp/src/public/tier1/checksum_crc.h @@ -10,7 +10,7 @@ #pragma once
#endif
-typedef unsigned long CRC32_t;
+typedef unsigned int CRC32_t;
void CRC32_Init( CRC32_t *pulCRC );
void CRC32_ProcessBuffer( CRC32_t *pulCRC, const void *p, int len );
diff --git a/mp/src/public/tier1/ilocalize.h b/mp/src/public/tier1/ilocalize.h index 348986ad..a3dd6bb8 100644 --- a/mp/src/public/tier1/ilocalize.h +++ b/mp/src/public/tier1/ilocalize.h @@ -135,7 +135,7 @@ private: typedef char locchar_t;
#define loc_snprintf Q_snprintf
- #define loc_sprintf_safe V_snprintf_safe
+ #define loc_sprintf_safe V_sprintf_safe
#define loc_sncat Q_strncat
#define loc_scat_safe V_strcat_safe
#define loc_sncpy Q_strncpy
@@ -148,7 +148,7 @@ private: typedef wchar_t locchar_t;
#define loc_snprintf V_snwprintf
- #define loc_sprintf_safe V_snwprintf_safe
+ #define loc_sprintf_safe V_swprintf_safe
#define loc_sncat V_wcsncat
#define loc_scat_safe V_wcscat_safe
#define loc_sncpy Q_wcsncpy
diff --git a/mp/src/public/tier1/lzmaDecoder.h b/mp/src/public/tier1/lzmaDecoder.h index eb501c10..8aa1f2ca 100644 --- a/mp/src/public/tier1/lzmaDecoder.h +++ b/mp/src/public/tier1/lzmaDecoder.h @@ -1,4 +1,3 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
//
// LZMA Decoder. Designed for run time decoding.
//
diff --git a/mp/src/public/tier1/strtools.h b/mp/src/public/tier1/strtools.h index 8e38436f..6089a8f4 100644 --- a/mp/src/public/tier1/strtools.h +++ b/mp/src/public/tier1/strtools.h @@ -290,7 +290,7 @@ template <size_t maxLenInCharacters> int V_vsprintf_safe( OUT_Z_ARRAY char (&pDe int V_snprintf( OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars, PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 3, 4 );
// gcc insists on only having format annotations on declarations, not definitions, which is why I have both.
template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 2, 3 );
-template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], const char *pFormat, ... )
+template <size_t maxLenInChars> int V_sprintf_safe( OUT_Z_ARRAY char (&pDest)[maxLenInChars], PRINTF_FORMAT_STRING const char *pFormat, ... )
{
va_list params;
va_start( params, pFormat );
diff --git a/mp/src/public/tier1/utlrbtree.h b/mp/src/public/tier1/utlrbtree.h index b2665194..6ea22614 100644 --- a/mp/src/public/tier1/utlrbtree.h +++ b/mp/src/public/tier1/utlrbtree.h @@ -1350,7 +1350,7 @@ int CUtlRBTree<T, I, L, M>::Depth( I node ) const int depthright = Depth( RightChild(node) );
int depthleft = Depth( LeftChild(node) );
- return max(depthright, depthleft) + 1;
+ return Max(depthright, depthleft) + 1;
}
diff --git a/mp/src/public/togl/glfuncs.inl b/mp/src/public/togl/glfuncs.inl new file mode 100644 index 00000000..dafd0949 --- /dev/null +++ b/mp/src/public/togl/glfuncs.inl @@ -0,0 +1,7 @@ +#if defined(LINUX) || defined(_WIN32)
+#include "togl/linuxwin/glfuncs.h"
+#endif
+#if defined(OSX)
+#include "togl/osx/glfuncs.h"
+#endif
+
diff --git a/mp/src/public/togl/linuxwin/cglmbuffer.h b/mp/src/public/togl/linuxwin/cglmbuffer.h new file mode 100644 index 00000000..ffec2742 --- /dev/null +++ b/mp/src/public/togl/linuxwin/cglmbuffer.h @@ -0,0 +1,190 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmprogram.h
+// GLMgr buffers (index / vertex)
+// ... maybe add PBO later as well
+//===============================================================================
+
+#ifndef CGLMBUFFER_H
+#define CGLMBUFFER_H
+
+#pragma once
+
+//===============================================================================
+
+extern bool g_bUsePseudoBufs;
+
+// forward declarations
+
+class GLMContext;
+
+enum EGLMBufferType
+{
+ kGLMVertexBuffer,
+ kGLMIndexBuffer,
+ kGLMUniformBuffer, // for bindable uniform
+ kGLMPixelBuffer, // for PBO
+
+ kGLMNumBufferTypes
+};
+
+// pass this in "options" to constructor to make a dynamic buffer
+#define GLMBufferOptionDynamic 0x00000001
+
+struct GLMBuffLockParams
+{
+ uint m_nOffset;
+ uint m_nSize;
+ bool m_bNoOverwrite;
+ bool m_bDiscard;
+};
+
+#define GL_STATIC_BUFFER_SIZE ( 2048 * 1024 )
+#define GL_MAX_STATIC_BUFFERS 2
+
+extern void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall = 128 * 1024 );
+
+//===============================================================================
+
+#if GL_ENABLE_INDEX_VERIFICATION
+
+struct GLDynamicBuf_t
+{
+ GLenum m_nGLType;
+ uint m_nHandle;
+ uint m_nActualBufSize;
+ uint m_nSize;
+
+ uint m_nLockOffset;
+ uint m_nLockSize;
+};
+
+class CGLMBufferSpanManager
+{
+ CGLMBufferSpanManager( const CGLMBufferSpanManager& );
+ CGLMBufferSpanManager& operator= ( const CGLMBufferSpanManager& );
+
+public:
+ CGLMBufferSpanManager();
+ ~CGLMBufferSpanManager();
+
+ void Init( GLMContext *pContext, EGLMBufferType nBufType, uint nInitialCapacity, uint nBufSize, bool bDynamic );
+ void Deinit();
+
+ inline GLMContext *GetContext() const { return m_pCtx; }
+
+ inline GLenum GetGLBufType() const { return ( m_nBufType == kGLMVertexBuffer ) ? GL_ARRAY_BUFFER_ARB : GL_ELEMENT_ARRAY_BUFFER_ARB; }
+
+ struct ActiveSpan_t
+ {
+ uint m_nStart;
+ uint m_nEnd;
+
+ GLDynamicBuf_t m_buf;
+ bool m_bOriginalAlloc;
+
+ inline ActiveSpan_t() { }
+ inline ActiveSpan_t( uint nStart, uint nEnd, GLDynamicBuf_t &buf, bool bOriginalAlloc ) : m_nStart( nStart ), m_nEnd( nEnd ), m_buf( buf ), m_bOriginalAlloc( bOriginalAlloc ) { Assert( nStart <= nEnd ); }
+ };
+
+ ActiveSpan_t *AddSpan( uint nOffset, uint nMaxSize, uint nActualSize, bool bDiscard, bool bNoOverwrite );
+
+ void DiscardAllSpans();
+
+ bool IsValid( uint nOffset, uint nSize ) const;
+
+private:
+ bool AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf );
+ void ReleaseDynamicBuf( GLDynamicBuf_t &buf );
+
+ GLMContext *m_pCtx;
+
+ EGLMBufferType m_nBufType;
+
+ uint m_nBufSize;
+ bool m_bDynamic;
+
+ CUtlVector<ActiveSpan_t> m_ActiveSpans;
+ CUtlVector<ActiveSpan_t> m_DeletedSpans;
+
+ int m_nSpanEndMax;
+
+ int m_nNumAllocatedBufs;
+ int m_nTotalBytesAllocated;
+};
+
+#endif // GL_ENABLE_INDEX_VERIFICATION
+
+class CGLMBuffer
+{
+public:
+ void Lock( GLMBuffLockParams *pParams, char **pAddressOut );
+ void Unlock( int nActualSize = -1, const void *pActualData = NULL );
+
+ friend class GLMContext; // only GLMContext can make CGLMBuffer objects
+ friend class GLMTester;
+ friend struct IDirect3D9;
+ friend struct IDirect3DDevice9;
+
+ CGLMBuffer( GLMContext *pCtx, EGLMBufferType type, uint size, uint options );
+ ~CGLMBuffer();
+
+ void SetModes( bool bAsyncMap, bool bExplicitFlush, bool bForce = false );
+ void FlushRange( uint offset, uint size );
+
+#if GL_ENABLE_INDEX_VERIFICATION
+ bool IsSpanValid( uint nOffset, uint nSize ) const;
+#endif
+
+ GLMContext *m_pCtx; // link back to parent context
+ EGLMBufferType m_type;
+ uint m_nSize;
+ uint m_nActualSize;
+
+ bool m_bDynamic;
+
+ GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
+ GLuint m_nHandle; // name of this program in the context
+
+ uint m_nRevision; // bump anytime the size changes or buffer is orphaned
+
+ bool m_bEnableAsyncMap; // mirror of the buffer state
+ bool m_bEnableExplicitFlush; // mirror of the buffer state
+
+ bool m_bMapped; // is it currently mapped
+
+ uint m_dirtyMinOffset; // when equal, range is empty
+ uint m_dirtyMaxOffset;
+
+ float *m_pLastMappedAddress;
+
+ int m_nPinnedMemoryOfs;
+
+ bool m_bPseudo; // true if the m_name is 0, and the backing is plain RAM
+
+ // in pseudo mode, there is just one RAM buffer that acts as the backing.
+ // expectation is that this mode would only be used for dynamic indices.
+ // since indices have to be consumed (copied to command stream) prior to return from a drawing call,
+ // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op.
+
+ char *m_pActualPseudoBuf; // storage for pseudo buffer
+ char *m_pPseudoBuf; // storage for pseudo buffer
+ char *m_pStaticBuffer;
+
+ GLMBuffLockParams m_LockParams;
+
+ static char ALIGN16 m_StaticBuffers[ GL_MAX_STATIC_BUFFERS ][ GL_STATIC_BUFFER_SIZE ] ALIGN16_POST;
+ static bool m_bStaticBufferUsed[ GL_MAX_STATIC_BUFFERS ];
+
+#if GL_ENABLE_INDEX_VERIFICATION
+ CGLMBufferSpanManager m_BufferSpanManager;
+#endif
+
+#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION
+ uint m_nDirtyRangeStart;
+ uint m_nDirtyRangeEnd;
+#endif
+};
+
+#endif // CGLMBUFFER_H
+
diff --git a/mp/src/public/togl/linuxwin/cglmfbo.h b/mp/src/public/togl/linuxwin/cglmfbo.h new file mode 100644 index 00000000..f3415795 --- /dev/null +++ b/mp/src/public/togl/linuxwin/cglmfbo.h @@ -0,0 +1,82 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmfbo.h
+// GLMgr FBO's (render targets)
+//
+//===============================================================================
+
+#ifndef CGLMFBO_H
+#define CGLMFBO_H
+
+#pragma once
+
+// good FBO references / recaps
+// http://www.songho.ca/opengl/gl_fbo.html
+// http://www.gamedev.net/reference/articles/article2331.asp
+
+// ext links
+
+// http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
+// http://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt
+
+//===============================================================================
+
+// tokens not in the SDK headers
+
+#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT
+ #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9
+#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+
+enum EGLMFBOAttachment
+{
+ kAttColor0, kAttColor1, kAttColor2, kAttColor3,
+ kAttDepth, kAttStencil, kAttDepthStencil,
+ kAttCount
+};
+
+struct GLMFBOTexAttachParams
+{
+ CGLMTex *m_tex;
+ int m_face; // keep zero if not cube map
+ int m_mip; // keep zero if notmip mapped
+ int m_zslice; // keep zero if not a 3D tex
+};
+
+class CGLMFBO
+{
+ friend class GLMContext;
+ friend class GLMTester;
+ friend class CGLMTex;
+
+ friend struct IDirect3D9;
+ friend struct IDirect3DDevice9;
+
+public:
+ CGLMFBO( GLMContext *ctx );
+ ~CGLMFBO( );
+
+protected:
+ void TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT );
+ void TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT );
+ // you can also pass GL_READ_FRAMEBUFFER_EXT or GL_DRAW_FRAMEBUFFER_EXT to selectively bind the receiving FBO to one or the other.
+
+ void TexScrub( CGLMTex *tex );
+ // search and destroy any attachment for the named texture
+
+ bool IsReady( void ); // aka FBO completeness check - ready to draw
+
+ GLMContext *m_ctx; // link back to parent context
+
+ GLuint m_name; // name of this FBO in the context
+
+ GLMFBOTexAttachParams m_attach[ kAttCount ]; // indexed by EGLMFBOAttachment
+};
+
+
+#endif
\ No newline at end of file diff --git a/mp/src/public/togl/linuxwin/cglmprogram.h b/mp/src/public/togl/linuxwin/cglmprogram.h new file mode 100644 index 00000000..ca32af00 --- /dev/null +++ b/mp/src/public/togl/linuxwin/cglmprogram.h @@ -0,0 +1,420 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmprogram.h
+// GLMgr programs (ARBVP/ARBfp)
+//
+//===============================================================================
+
+#ifndef CGLMPROGRAM_H
+#define CGLMPROGRAM_H
+
+#include <sys/stat.h>
+
+#pragma once
+
+// good ARB program references
+// http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html
+// http://petewarden.com/notes/archives/2005/06/fragment_progra_3.html
+
+// ext links
+
+// http://www.opengl.org/registry/specs/ARB/vertex_program.txt
+// http://www.opengl.org/registry/specs/ARB/fragment_program.txt
+// http://www.opengl.org/registry/specs/EXT/gpu_program_parameters.txt
+
+
+//===============================================================================
+
+// tokens not in the SDK headers
+
+//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT
+// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9
+//#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class CGLMShaderPair;
+class CGLMShaderPairCache;
+
+// CGLMProgram can contain two flavors of the same program, one in assembler, one in GLSL.
+// these flavors are pretty different in terms of the API's that are used to activate them -
+// for example, assembler programs can just get bound to the context, whereas GLSL programs
+// have to be linked. To some extent we try to hide that detail inside GLM.
+
+// for now, make CGLMProgram a container, it does not set policy or hold a preference as to which
+// flavor you want to use. GLMContext has to handle that.
+
+enum EGLMProgramType
+{
+ kGLMVertexProgram,
+ kGLMFragmentProgram,
+
+ kGLMNumProgramTypes
+};
+
+enum EGLMProgramLang
+{
+ kGLMARB,
+ kGLMGLSL,
+
+ kGLMNumProgramLangs
+};
+
+struct GLMShaderDesc
+{
+ union
+ {
+ GLuint arb; // ARB program object name
+ GLhandleARB glsl; // GLSL shader object handle (void*)
+ } m_object;
+
+ // these can change if shader text is edited
+ bool m_textPresent; // is this flavor(lang) of text present in the buffer?
+ int m_textOffset; // where is it
+ int m_textLength; // how big
+
+ bool m_compiled; // has this text been through a compile attempt
+ bool m_valid; // and if so, was the compile successful
+
+ int m_slowMark; // has it been flagged during a non native draw batch before. increment every time it's slow.
+
+ int m_highWater; // count of vec4's in the major uniform array ("vc" on vs, "pc" on ps)
+ // written by dxabstract.... gross!
+ int m_VSHighWaterBone; // count of vec4's in the bone-specific uniform array (only valid for vertex shaders)
+};
+
+GLenum GLMProgTypeToARBEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target
+GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target
+
+#define GL_SHADER_PAIR_CACHE_STATS 0
+
+class CGLMProgram
+{
+public:
+ friend class CGLMShaderPairCache;
+ friend class CGLMShaderPair;
+ friend class GLMContext; // only GLMContext can make CGLMProgram objects
+ friend class GLMTester;
+ friend struct IDirect3D9;
+ friend struct IDirect3DDevice9;
+
+ //===============================
+
+ // constructor is very light, it just makes one empty program object per flavor.
+ CGLMProgram( GLMContext *ctx, EGLMProgramType type );
+ ~CGLMProgram( );
+
+ void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program
+ void SetShaderName ( const char *name ); // only used for debugging/telemetry markup
+
+ bool CompileActiveSources ( void ); // compile only the flavors that were provided.
+ bool Compile ( EGLMProgramLang lang );
+ bool CheckValidity ( EGLMProgramLang lang );
+
+ void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that
+
+ void GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut );
+ void GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ); // mmmmmmmm-nnnnnnnn-filename
+
+#if GLMDEBUG
+ bool PollForChanges( void ); // check mirror for changes.
+ void ReloadStringFromEditable( void ); // populate m_string from editable item (react to change)
+ bool SyncWithEditable( void );
+#endif
+
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ EGLMProgramType m_type; // vertex or pixel
+
+ uint m_nHashTag; // serial number for hashing
+
+ char *m_text; // copy of text passed into constructor. Can change if editable shaders is enabled.
+ // note - it can contain multiple flavors, so use CGLMTextSectioner to scan it and locate them
+#if GLMDEBUG
+ CGLMEditableTextItem *m_editable; // editable text item for debugging
+#endif
+
+ GLMShaderDesc m_descs[ kGLMNumProgramLangs ];
+
+ uint m_samplerMask; // (1<<n) mask of sampler active locs, if this is a fragment shader (dxabstract sets this field)
+ uint m_samplerTypes; // SAMPLER_2D, etc.
+ uint m_nNumUsedSamplers;
+ uint m_maxSamplers;
+ uint m_maxVertexAttrs;
+ uint m_nCentroidMask;
+ uint m_nShadowDepthSamplerMask;
+
+ bool m_bTranslatedProgram;
+
+ char m_shaderName[64];
+};
+
+//===============================================================================
+
+struct GLMShaderPairInfo
+{
+ int m_status; // -1 means req'd index was out of bounds (loop stop..) 0 means not present. 1 means present/active.
+
+ char m_vsName[ 128 ];
+ int m_vsStaticIndex;
+ int m_vsDynamicIndex;
+
+ char m_psName[ 128 ];
+ int m_psStaticIndex;
+ int m_psDynamicIndex;
+};
+
+class CGLMShaderPair // a container for a linked GLSL shader pair, and metadata obtained post-link
+{
+
+public:
+
+ friend class CGLMProgram;
+ friend class GLMContext;
+ friend class CGLMShaderPairCache;
+
+ //===============================
+
+ // constructor just sets up a GLSL program object and leaves it empty.
+ CGLMShaderPair( GLMContext *ctx );
+ ~CGLMShaderPair( );
+
+ bool SetProgramPair ( CGLMProgram *vp, CGLMProgram *fp );
+ // true result means successful link and query
+
+ bool RefreshProgramPair ( void );
+ // re-link and re-query the uniforms
+
+ FORCEINLINE void UpdateScreenUniform( uint nWidthHeight )
+ {
+ if ( m_nScreenWidthHeight == nWidthHeight )
+ return;
+
+ m_nScreenWidthHeight = nWidthHeight;
+
+ uint nWidth = nWidthHeight & 0xFFFF, nHeight = nWidthHeight >> 16;
+ // Apply half pixel offset to output vertices to account for the pixel center difference between D3D9 and OpenGL.
+ // We output vertices in clip space, which ranges from [-1,1], so 1.0/width in clip space transforms into .5/width in screenspace, see: "Viewports and Clipping (Direct3D 9)" in the DXSDK
+ float v[4] = { 1.0f / nWidth, 1.0f / nHeight, nWidth, nHeight };
+ if ( m_locVertexScreenParams >= 0 )
+ gGL->glUniform4fv( m_locVertexScreenParams, 1, v );
+ }
+
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ CGLMProgram *m_vertexProg;
+ CGLMProgram *m_fragmentProg;
+
+ GLhandleARB m_program; // linked program object
+
+ // need meta data for attribs / samplers / params
+ // actually we only need it for samplers and params.
+ // attributes are hardwired.
+
+ // vertex stage uniforms
+ GLint m_locVertexParams; // "vc" per dx9asmtogl2 convention
+ GLint m_locVertexBoneParams; // "vcbones"
+ GLint m_locVertexInteger0; // "i0"
+
+ GLint m_locVertexBool0; // "b0"
+ GLint m_locVertexBool1; // "b1"
+ GLint m_locVertexBool2; // "b2"
+ GLint m_locVertexBool3; // "b3"
+ bool m_bHasBoolOrIntUniforms;
+
+ // fragment stage uniforms
+ GLint m_locFragmentParams; // "pc" per dx9asmtogl2 convention
+
+ int m_NumUniformBufferParams[kGLMNumProgramTypes];
+ GLint m_UniformBufferParams[kGLMNumProgramTypes][256];
+
+ GLint m_locFragmentFakeSRGBEnable; // "flSRGBWrite" - set to 1.0 to effect sRGB encoding on output
+ float m_fakeSRGBEnableValue; // shadow to avoid redundant sets of the m_locFragmentFakeSRGBEnable uniform
+ // init it to -1.0 at link or relink, so it will trip on any legit incoming value (0.0 or 1.0)
+
+ GLint m_locSamplers[ 16 ]; // "sampler0 ... sampler1..."
+
+ // other stuff
+ bool m_valid; // true on successful link
+ uint m_revision; // if this pair is relinked, bump this number.
+
+ GLint m_locVertexScreenParams; // vcscreen
+ uint m_nScreenWidthHeight;
+
+};
+
+//===============================================================================
+
+// N-row, M-way associative cache with LRU per row.
+// still needs some metric dump ability and some parameter tuning.
+// extra credit would be to make an auto-tuner.
+
+struct CGLMPairCacheEntry
+{
+ long long m_lastMark; // a mark of zero means an empty entry
+ CGLMProgram *m_vertexProg;
+ CGLMProgram *m_fragmentProg;
+ uint m_extraKeyBits;
+ CGLMShaderPair *m_pair;
+};
+
+class CGLMShaderPairCache // cache for linked GLSL shader pairs
+{
+
+public:
+
+protected:
+ friend class CGLMShaderPair;
+ friend class CGLMProgram;
+ friend class GLMContext;
+
+ //===============================
+
+ CGLMShaderPairCache( GLMContext *ctx );
+ ~CGLMShaderPairCache( );
+
+ FORCEINLINE CGLMShaderPair *SelectShaderPair ( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits );
+ void QueryShaderPair ( int index, GLMShaderPairInfo *infoOut );
+
+ // shoot down linked pairs that use the program in the arg
+ // return true if any had to be skipped due to conflict with currently bound pair
+ bool PurgePairsWithShader( CGLMProgram *prog );
+
+ // purge everything (when would GLM know how to do this ? at context destroy time, but any other times?)
+ // return true if any had to be skipped due to conflict with currently bound pair
+ bool Purge ( void );
+
+ // stats
+ void DumpStats ( void );
+
+ //===============================
+
+ FORCEINLINE uint HashRowIndex( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ) const;
+ FORCEINLINE CGLMPairCacheEntry* HashRowPtr( uint hashRowIndex ) const;
+
+ FORCEINLINE void HashRowProbe( CGLMPairCacheEntry *row, CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int &hitway, int &emptyway, int &oldestway );
+
+ CGLMShaderPair *SelectShaderPairInternal( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int rowIndex );
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ long long m_mark;
+
+ uint m_rowsLg2;
+ uint m_rows;
+ uint m_rowsMask;
+
+ uint m_waysLg2;
+ uint m_ways;
+
+ uint m_entryCount;
+
+ CGLMPairCacheEntry *m_entries; // array[ m_rows ][ m_ways ]
+
+ uint *m_evictions; // array[ m_rows ];
+
+#if GL_SHADER_PAIR_CACHE_STATS
+ uint *m_hits; // array[ m_rows ];
+#endif
+};
+
+FORCEINLINE uint CGLMShaderPairCache::HashRowIndex( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ) const
+{
+ return ( vp->m_nHashTag + fp->m_nHashTag + extraKeyBits * 7 ) & m_rowsMask;
+}
+
+FORCEINLINE CGLMPairCacheEntry* CGLMShaderPairCache::HashRowPtr( uint hashRowIndex ) const
+{
+ return &m_entries[ hashRowIndex * m_ways ];
+}
+
+FORCEINLINE void CGLMShaderPairCache::HashRowProbe( CGLMPairCacheEntry *row, CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int& hitway, int& emptyway, int& oldestway )
+{
+ hitway = -1;
+ emptyway = -1;
+ oldestway = -1;
+
+ // scan this row to see if the desired pair is present
+ CGLMPairCacheEntry *cursor = row;
+ long long oldestmark = 0xFFFFFFFFFFFFFFFFLL;
+
+ for( uint way = 0; way < m_ways; ++way )
+ {
+ if ( cursor->m_lastMark != 0 ) // occupied slot
+ {
+ // check if this is the oldest one on the row - only occupied slots are checked
+ if ( cursor->m_lastMark < oldestmark )
+ {
+ oldestway = way;
+ oldestmark = cursor->m_lastMark;
+ }
+
+ if ( ( cursor->m_vertexProg == vp ) && ( cursor->m_fragmentProg == fp ) && ( cursor->m_extraKeyBits == extraKeyBits ) ) // match?
+ {
+ // found it
+ hitway = way;
+ break;
+ }
+ }
+ else
+ {
+ // empty way, log it if first one seen
+ if (emptyway<0)
+ {
+ emptyway = way;
+ }
+ }
+ cursor++;
+ }
+}
+
+FORCEINLINE CGLMShaderPair *CGLMShaderPairCache::SelectShaderPair( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits )
+{
+ // select row where pair would be found if it exists
+ uint rowIndex = HashRowIndex( vp, fp, extraKeyBits );
+
+ CGLMPairCacheEntry *pCursor = HashRowPtr( rowIndex );
+
+ if ( ( pCursor->m_fragmentProg != fp ) || ( pCursor->m_vertexProg != vp ) || ( pCursor->m_extraKeyBits != extraKeyBits ) )
+ {
+ CGLMPairCacheEntry *pLastCursor = pCursor + m_ways;
+
+ ++pCursor;
+
+ while ( pCursor != pLastCursor )
+ {
+ if ( ( pCursor->m_fragmentProg == fp ) && ( pCursor->m_vertexProg == vp ) && ( pCursor->m_extraKeyBits == extraKeyBits ) ) // match?
+ break;
+ ++pCursor;
+ };
+
+ if ( pCursor == pLastCursor )
+ return SelectShaderPairInternal( vp, fp, extraKeyBits, rowIndex );
+ }
+
+ // found it. mark it and return
+ pCursor->m_lastMark = m_mark++;
+
+#if GL_SHADER_PAIR_CACHE_STATS
+ // count the hit
+ m_hits[ rowIndex ] ++;
+#endif
+
+ return pCursor->m_pair;
+}
+
+#endif
diff --git a/mp/src/public/togl/linuxwin/cglmquery.h b/mp/src/public/togl/linuxwin/cglmquery.h new file mode 100644 index 00000000..3cf6f79e --- /dev/null +++ b/mp/src/public/togl/linuxwin/cglmquery.h @@ -0,0 +1,90 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmquery.h
+// GLMgr queries
+//
+//===============================================================================
+
+#ifndef CGLMQUERY_H
+#define CGLMQUERY_H
+
+#pragma once
+
+#ifdef OSX
+#include "glmgr/glmgrbasics.h"
+#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class CGLMQuery;
+
+//===============================================================================
+
+enum EGLMQueryType
+{
+ EOcclusion,
+ EFence,
+ EGLMQueryCount
+};
+
+struct GLMQueryParams
+{
+ EGLMQueryType m_type;
+};
+
+class CGLMQuery
+{
+ // leave everything public til it's running
+public:
+ friend class GLMContext; // only GLMContext can make CGLMTex objects
+ friend struct IDirect3DDevice9;
+ friend struct IDirect3DQuery9;
+
+ GLMContext *m_ctx; // link back to parent context
+ GLMQueryParams m_params; // params created with
+
+ GLuint m_name; // name of the query object per se - could be fence, could be query object ... NOT USED WITH GL_ARB_sync!
+#ifdef HAVE_GL_ARB_SYNC
+ GLsync m_syncobj; // GL_ARB_sync object. NOT USED WITH GL_NV_fence or GL_APPLE_fence!
+#else
+ GLuint m_syncobj;
+#endif
+
+ bool m_started;
+ bool m_stopped;
+ bool m_done;
+
+ bool m_nullQuery; // was gl_nullqueries true at Start time - if so, continue to act like a null query through Stop/IsDone/Complete time
+ // restated - only Start should examine the convar.
+ static uint s_nTotalOcclusionQueryCreatesOrDeletes;
+
+ CGLMQuery( GLMContext *ctx, GLMQueryParams *params );
+ ~CGLMQuery( );
+
+ // for an occlusion query:
+ // Start = BeginQuery query-start goes into stream
+ // Stop = EndQuery query-end goes into stream - a fence is also set so we can probe for completion
+ // IsDone = TestFence use the added fence to ask if query-end has passed (i.e. will Complete block?)
+ // Complete = GetQueryObjectuivARB(uint id, enum pname, uint *params) - extract the sample count
+
+ // for a fence query:
+ // Start = SetFence fence goes into command stream
+ // Stop = NOP fences are self finishing - no need to call Stop on a fence
+ // IsDone = TestFence ask if fence passed
+ // Complete = FinishFence
+
+ void Start ( void );
+ void Stop ( void );
+ bool IsDone ( void );
+ void Complete ( uint *result );
+
+ // accessors for the started/stopped state
+ bool IsStarted ( void );
+ bool IsStopped ( void );
+};
+
+
+#endif
diff --git a/mp/src/public/togl/linuxwin/cglmtex.h b/mp/src/public/togl/linuxwin/cglmtex.h new file mode 100644 index 00000000..bdb83776 --- /dev/null +++ b/mp/src/public/togl/linuxwin/cglmtex.h @@ -0,0 +1,502 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmtex.h
+// GLMgr textures
+//
+//===============================================================================
+
+#ifndef CGLMTEX_H
+#define CGLMTEX_H
+
+#pragma once
+
+#ifdef OSX
+#include "glmgr/glmgrbasics.h"
+#endif
+#include "tier1/utlhash.h"
+#include "tier1/utlmap.h"
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class GLMTester;
+class CGLMTexLayoutTable;
+class CGLMTex;
+class CGLMFBO;
+
+struct IDirect3DSurface9;
+
+#if GLMDEBUG
+extern CGLMTex *g_pFirstCGMLTex;
+#endif
+
+// For GL_EXT_texture_sRGB_decode
+#ifndef GL_TEXTURE_SRGB_DECODE_EXT
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#endif
+
+#ifndef GL_DECODE_EXT
+#define GL_DECODE_EXT 0x8A49
+#endif
+
+#ifndef GL_SKIP_DECODE_EXT
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#endif
+
+//===============================================================================
+
+struct GLMTexFormatDesc
+{
+ const char *m_formatSummary; // for debug visibility
+
+ D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h
+
+ GLenum m_glIntFormat; // GL internal format
+ GLenum m_glIntFormatSRGB; // internal format if SRGB flavor
+ GLenum m_glDataFormat; // GL data format
+ GLenum m_glDataType; // GL data type
+
+ int m_chunkSize; // 1 or 4 - 4 is used for compressed textures
+ int m_bytesPerSquareChunk; // how many bytes for the smallest quantum (m_chunkSize x m_chunkSize)
+ // this description lets us calculate size cleanly without conditional logic for compression
+};
+const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format );
+
+//===============================================================================
+
+// utility function for generating slabs of texels. mostly for test.
+typedef struct
+{
+ // in
+ D3DFORMAT m_format;
+ void *m_dest; // dest address
+ int m_chunkCount; // square chunk count (single texels or compressed blocks)
+ int m_byteCountLimit; // caller expectation of max number of bytes to write out
+ float r,g,b,a; // color desired
+
+ // out
+ int m_bytesWritten;
+} GLMGenTexelParams;
+
+// return true if successful
+bool GLMGenTexels( GLMGenTexelParams *params );
+
+
+//===============================================================================
+
+struct GLMTexLayoutSlice
+{
+ int m_xSize,m_ySize,m_zSize; //texel dimensions of this slice
+ int m_storageOffset; //where in the storage slab does this slice live
+ int m_storageSize; //how much storage does this slice occupy
+};
+
+enum EGLMTexFlags
+{
+ kGLMTexMipped = 0x01,
+ kGLMTexMippedAuto = 0x02,
+ kGLMTexRenderable = 0x04,
+ kGLMTexIsStencil = 0x08,
+ kGLMTexIsDepth = 0x10,
+ kGLMTexSRGB = 0x20,
+ kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
+ // actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
+ // have mipmaps generated.
+};
+
+//===============================================================================
+
+struct GLMTexLayoutKey
+{
+ // input values: held const, these are the hash key for the form map
+ GLenum m_texGLTarget; // flavor of texture: GL_TEXTURE_2D, GL_TEXTURE_3D, GLTEXTURE_CUBE_MAP
+ D3DFORMAT m_texFormat; // D3D texel format
+ unsigned long m_texFlags; // mipped, autogen mips, render target, ... ?
+ unsigned long m_texSamples; // zero for a plain tex, 2/4/6/8 for "MSAA tex" (RBO backed)
+ int m_xSize,m_ySize,m_zSize; // size of base mip
+};
+
+bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b );
+
+#define GLM_TEX_MAX_MIPS 14
+#define GLM_TEX_MAX_FACES 6
+#define GLM_TEX_MAX_SLICES (GLM_TEX_MAX_MIPS * GLM_TEX_MAX_FACES)
+
+#pragma warning( push )
+#pragma warning( disable : 4200 )
+
+struct GLMTexLayout
+{
+ char *m_layoutSummary; // for debug visibility
+
+ // const inputs used for hashing
+ GLMTexLayoutKey m_key;
+
+ // refcount
+ int m_refCount;
+
+ // derived values:
+ GLMTexFormatDesc *m_format; // format specific info
+ int m_mipCount; // derived by starying at base size and working down towards 1x1
+ int m_faceCount; // 1 for 2d/3d, 6 for cubemap
+ int m_sliceCount; // product of faces and mips
+ int m_storageTotalSize; // size of storage slab required
+
+ // slice array
+ GLMTexLayoutSlice m_slices[0]; // dynamically allocated 2-d array [faces][mips]
+};
+
+#pragma warning( pop )
+
+class CGLMTexLayoutTable
+{
+public:
+ CGLMTexLayoutTable();
+
+ GLMTexLayout *NewLayoutRef( GLMTexLayoutKey *pDesiredKey ); // pass in a pointer to layout key - receive ptr to completed layout
+ void DelLayoutRef( GLMTexLayout *layout ); // pass in pointer to completed layout. refcount is dropped.
+
+ void DumpStats( void );
+protected:
+ CUtlMap< GLMTexLayoutKey, GLMTexLayout* > m_layoutMap;
+};
+
+//===============================================================================
+
+// a sampler specifies desired state for drawing on a given sampler index
+// this is the combination of a texture choice and a set of sampler parameters
+// see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx
+
+struct GLMTexLockParams
+{
+ // input params which identify the slice of interest
+ CGLMTex *m_tex;
+ int m_face;
+ int m_mip;
+
+ // identifies the region of the slice
+ GLMRegion m_region;
+
+ // tells GLM to force re-read of the texels back from GL
+ // i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
+ bool m_readback;
+};
+
+struct GLMTexLockDesc
+{
+ GLMTexLockParams m_req; // form of the lock request
+
+ bool m_active; // set true at lock time. cleared at unlock time.
+
+ int m_sliceIndex; // which slice in the layout
+ int m_sliceBaseOffset; // where is that in the texture data
+ int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested
+};
+
+//===============================================================================
+
+#define GLM_SAMPLER_COUNT 16
+
+typedef CBitVec<GLM_SAMPLER_COUNT> CTexBindMask;
+
+enum EGLMTexSliceFlag
+{
+ kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially
+ kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially
+ kSliceLocked = 0x04, // are one or more locks outstanding on this slice
+ kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects)
+};
+
+//===============================================================================
+
+#define GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS (2)
+#define GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS (2)
+#define GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS (2)
+#define GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS (2)
+#define GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS (4)
+#define GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS (5)
+#define GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS (1)
+#define GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS (1)
+
+struct GLMTexPackedSamplingParams
+{
+ uint32 m_addressU : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
+ uint32 m_addressV : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
+ uint32 m_addressW : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS;
+
+ uint32 m_minFilter : GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS;
+ uint32 m_magFilter : GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS;
+ uint32 m_mipFilter : GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS;
+
+ uint32 m_minLOD : GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS;
+ uint32 m_maxAniso : GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS;
+ uint32 m_compareMode : GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS;
+ uint32 m_srgb : GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS;
+ uint32 m_isValid : 1;
+};
+
+struct GLMTexSamplingParams
+{
+ union
+ {
+ GLMTexPackedSamplingParams m_packed;
+ uint32 m_bits;
+ };
+
+ uint32 m_borderColor;
+
+ FORCEINLINE bool operator== (const GLMTexSamplingParams& rhs ) const
+ {
+ return ( m_bits == rhs.m_bits ) && ( m_borderColor == rhs.m_borderColor );
+ }
+
+ FORCEINLINE void SetToDefaults()
+ {
+ m_bits = 0;
+ m_borderColor = 0;
+ m_packed.m_addressU = D3DTADDRESS_WRAP;
+ m_packed.m_addressV = D3DTADDRESS_WRAP;
+ m_packed.m_addressW = D3DTADDRESS_WRAP;
+ m_packed.m_minFilter = D3DTEXF_POINT;
+ m_packed.m_magFilter = D3DTEXF_POINT;
+ m_packed.m_mipFilter = D3DTEXF_NONE;
+ m_packed.m_maxAniso = 1;
+ m_packed.m_isValid = true;
+ }
+
+ FORCEINLINE void SetToSamplerObject( GLuint nSamplerObject ) const
+ {
+ static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
+ static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
+ static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
+ {
+ /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
+ /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
+ };
+
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
+
+ float flBorderColor[4] = { 0, 0, 0, 0 };
+ if ( m_borderColor )
+ {
+ flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
+ flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
+ flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
+ flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
+ }
+ gGL->glSamplerParameterfv( nSamplerObject, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
+ if ( m_packed.m_compareMode )
+ {
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
+ }
+ if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode )
+ {
+ gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
+ }
+ }
+
+ inline void DeltaSetToTarget( GLenum target, const GLMTexSamplingParams &curState )
+ {
+ static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
+ static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
+ static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
+ {
+ /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
+ /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
+ };
+
+ if ( m_packed.m_addressU != curState.m_packed.m_addressU )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
+ }
+
+ if ( m_packed.m_addressV != curState.m_packed.m_addressV )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
+ }
+
+ if ( m_packed.m_addressW != curState.m_packed.m_addressW )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
+ }
+
+ if ( ( m_packed.m_minFilter != curState.m_packed.m_minFilter ) ||
+ ( m_packed.m_magFilter != curState.m_packed.m_magFilter ) ||
+ ( m_packed.m_mipFilter != curState.m_packed.m_mipFilter ) ||
+ ( m_packed.m_maxAniso != curState.m_packed.m_maxAniso ) )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
+ gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
+ gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
+ }
+
+ if ( m_borderColor != curState.m_borderColor )
+ {
+ float flBorderColor[4] = { 0, 0, 0, 0 };
+ if ( m_borderColor )
+ {
+ flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
+ flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
+ flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
+ flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
+ }
+
+ gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
+ }
+
+ if ( m_packed.m_minLOD != curState.m_packed.m_minLOD )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
+ }
+
+ if ( m_packed.m_compareMode != curState.m_packed.m_compareMode )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
+ if ( m_packed.m_compareMode )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
+ }
+ }
+
+ if ( ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) && ( m_packed.m_srgb != curState.m_packed.m_srgb ) )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
+ }
+ }
+
+ inline void SetToTargetTexture( GLenum target )
+ {
+ static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 };
+ static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR };
+ static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter].
+ {
+ /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT
+ /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 },
+ /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling
+ };
+
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] );
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] );
+ gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] );
+ gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] );
+ gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] );
+ gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso );
+
+ float flBorderColor[4] = { 0, 0, 0, 0 };
+ if ( m_borderColor )
+ {
+ flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R
+ flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G
+ flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B
+ flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A
+ }
+ gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out
+ gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD );
+ gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE );
+ if ( m_packed.m_compareMode )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );
+ }
+ if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode )
+ {
+ gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT );
+ }
+ }
+};
+
+//===============================================================================
+
+class CGLMTex
+{
+
+public:
+
+ void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut );
+ void Unlock( GLMTexLockParams *params );
+
+protected:
+ friend class GLMContext; // only GLMContext can make CGLMTex objects
+ friend class GLMTester;
+ friend class CGLMFBO;
+
+ friend struct IDirect3DDevice9;
+ friend struct IDirect3DBaseTexture9;
+ friend struct IDirect3DTexture9;
+ friend struct IDirect3DSurface9;
+ friend struct IDirect3DCubeTexture9;
+ friend struct IDirect3DVolumeTexture9;
+
+ CGLMTex( GLMContext *ctx, GLMTexLayout *layout, const char *debugLabel = NULL );
+ ~CGLMTex( );
+
+ int CalcSliceIndex( int face, int mip );
+ void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
+
+ void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
+ void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
+ // last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
+ // this helps out ResetSRGB.
+
+ bool IsRBODirty() const;
+ void ForceRBONonDirty();
+ void ForceRBODirty();
+
+ void AllocBacking();
+ void ReleaseBacking();
+
+ // re-specify texture format to match desired sRGB form
+ // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
+
+ GLuint m_texName; // name of this texture in the context
+ GLenum m_texGLTarget;
+ uint m_nSamplerType; // SAMPLER_2D, etc.
+ GLMTexSamplingParams m_SamplingParams;
+ GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout)
+
+ uint m_nLastResolvedBatchCounter;
+
+ int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
+ int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
+ int m_mipCount;
+
+ GLMContext *m_ctx; // link back to parent context
+
+ CGLMFBO *m_pBlitSrcFBO;
+ CGLMFBO *m_pBlitDstFBO;
+
+ GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero)
+
+ int m_rtAttachCount; // how many RT's have this texture attached somewhere
+
+ char *m_pBacking; // backing storage if available
+
+ int m_lockCount; // lock reqs are stored in the GLMContext for tracking
+
+ CUtlVector<unsigned char> m_sliceFlags;
+
+ char *m_debugLabel; // strdup() of debugLabel passed in, or NULL
+
+ bool m_texClientStorage; // was CS selected for texture
+ bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet
+
+#if GLMDEBUG
+ CGLMTex *m_pPrevTex;
+ CGLMTex *m_pNextTex;
+#endif
+};
+
+#endif
diff --git a/mp/src/public/togl/linuxwin/dxabstract.h b/mp/src/public/togl/linuxwin/dxabstract.h new file mode 100644 index 00000000..ab5940e5 --- /dev/null +++ b/mp/src/public/togl/linuxwin/dxabstract.h @@ -0,0 +1,1412 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// dxabstract.h
+//
+//==================================================================================================
+#ifndef DXABSTRACT_H
+#define DXABSTRACT_H
+
+#ifdef DX_TO_GL_ABSTRACTION
+
+#include "togl/rendermechanism.h"
+
+#include "tier0/platform.h"
+#include "tier0/dbg.h"
+#include "tier1/utlmap.h"
+
+// turn this on to get refcount logging from IUnknown
+#define IUNKNOWN_ALLOC_SPEW 0
+#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0
+
+TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect );
+
+struct TOGL_CLASS IUnknown
+{
+ int m_refcount[2];
+ bool m_mark;
+
+ IUnknown()
+ {
+ m_refcount[0] = 1;
+ m_refcount[1] = 0;
+ m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1]));
+ }
+ #endif
+ };
+
+ virtual ~IUnknown()
+ {
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUdel (%08x) ",this ));
+ }
+ #endif
+ };
+
+ void AddRef( int which=0, char *comment = NULL )
+ {
+ Assert( which >= 0 );
+ Assert( which < 2 );
+ m_refcount[which]++;
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ;
+ if (!comment)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ }
+ #endif
+ };
+
+ ULONG __stdcall Release( int which=0, char *comment = NULL )
+ {
+ Assert( which >= 0 );
+ Assert( which < 2 );
+
+ //int oldrefcs[2] = { m_refcount[0], m_refcount[1] };
+ bool deleting = false;
+
+ m_refcount[which]--;
+ if ( (!m_refcount[0]) && (!m_refcount[1]) )
+ {
+ deleting = true;
+ }
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":""));
+ if (!comment)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ }
+ #endif
+
+ if (deleting)
+ {
+ if (m_mark)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ delete this;
+ return 0;
+ }
+ else
+ {
+ return m_refcount[0];
+ }
+ };
+
+ void SetMark( bool markValue, char *comment=NULL )
+ {
+ #if IUNKNOWN_ALLOC_SPEW
+ if (!m_mark && markValue) // leading edge detect
+ {
+ // print the same thing that the constructor would have printed if it had been marked from the beginning
+ // i.e. it's anticipated that callers asking for marking will do so right at create time
+ GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"..."));
+ }
+ #endif
+
+ m_mark = markValue;
+ }
+};
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// INTERFACES
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+struct TOGL_CLASS IDirect3DResource9 : public IUnknown
+{
+ IDirect3DDevice9 *m_device; // parent device
+ D3DRESOURCETYPE m_restype;
+
+ DWORD SetPriority(DWORD PriorityNew);
+};
+
+struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.."
+{
+ D3DSURFACE_DESC m_descZero; // desc of top level.
+ CGLMTex *m_tex; // a CGLMTex can represent all forms of tex
+ int m_srgbFlipCount;
+
+ virtual ~IDirect3DBaseTexture9();
+ D3DRESOURCETYPE TOGLMETHODCALLTYPE GetType();
+ DWORD TOGLMETHODCALLTYPE GetLevelCount();
+ HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D"
+{
+ IDirect3DSurface9 *m_surfZero; // surf of top level.
+ virtual ~IDirect3DTexture9();
+ HRESULT TOGLMETHODCALLTYPE LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
+ HRESULT TOGLMETHODCALLTYPE UnlockRect(UINT Level);
+ HRESULT TOGLMETHODCALLTYPE GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel);
+};
+
+struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map"
+{
+ IDirect3DSurface9 *m_surfZero[6]; // surfs of top level.
+ virtual ~IDirect3DCubeTexture9();
+ HRESULT TOGLMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface);
+ HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D"
+{
+ IDirect3DSurface9 *m_surfZero; // surf of top level.
+ D3DVOLUME_DESC m_volDescZero; // volume desc top level
+ virtual ~IDirect3DVolumeTexture9();
+ HRESULT TOGLMETHODCALLTYPE LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags);
+ HRESULT TOGLMETHODCALLTYPE UnlockBox(UINT Level);
+ HRESULT TOGLMETHODCALLTYPE GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc );
+};
+
+
+// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip.
+// no Create method, these are filled in by the various create surface methods.
+
+struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9
+{
+ virtual ~IDirect3DSurface9();
+ HRESULT TOGLMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
+ HRESULT TOGLMETHODCALLTYPE UnlockRect();
+ HRESULT TOGLMETHODCALLTYPE GetDesc(D3DSURFACE_DESC *pDesc);
+
+ D3DSURFACE_DESC m_desc;
+ CGLMTex *m_tex;
+ int m_face;
+ int m_mip;
+};
+
+struct TOGL_CLASS IDirect3D9 : public IUnknown
+{
+ virtual ~IDirect3D9();
+
+ UINT TOGLMETHODCALLTYPE GetAdapterCount();
+
+ HRESULT TOGLMETHODCALLTYPE GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps);
+ HRESULT TOGLMETHODCALLTYPE GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier);
+ HRESULT TOGLMETHODCALLTYPE CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat);
+ UINT TOGLMETHODCALLTYPE GetAdapterModeCount (UINT Adapter,D3DFORMAT Format);
+ HRESULT TOGLMETHODCALLTYPE EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode);
+ HRESULT TOGLMETHODCALLTYPE CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed);
+ HRESULT TOGLMETHODCALLTYPE GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode);
+ HRESULT TOGLMETHODCALLTYPE CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat);
+ HRESULT TOGLMETHODCALLTYPE CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels);
+
+ HRESULT TOGLMETHODCALLTYPE CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface);
+};
+
+struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown
+{
+ IDirect3DDevice9 *m_device;
+ uint m_elemCount;
+ D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ];
+
+ uint8 m_VertexAttribDescToStreamIndex[256];
+
+ virtual ~IDirect3DVertexDeclaration9();
+};
+
+struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown
+{
+ D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT
+ GLMContext *m_ctx;
+ CGLMQuery *m_query;
+
+ uint m_nIssueStartThreadID, m_nIssueEndThreadID;
+ uint m_nIssueStartDrawCallIndex, m_nIssueEndDrawCallIndex;
+ uint m_nIssueStartFrameIndex, m_nIssueEndFrameIndex;
+ uint m_nIssueStartQueryCreationCounter, m_nIssueEndQueryCreationCounter;
+
+ virtual ~IDirect3DQuery9();
+
+ HRESULT Issue(DWORD dwIssueFlags);
+ HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags);
+};
+
+struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown
+{
+ GLMContext *m_ctx;
+ CGLMBuffer *m_vtxBuffer;
+ D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc
+
+ virtual ~IDirect3DVertexBuffer9();
+ HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
+ HRESULT Unlock();
+ void UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
+};
+
+struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown
+{
+ GLMContext *m_ctx;
+ CGLMBuffer *m_idxBuffer;
+ D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc
+
+ virtual ~IDirect3DIndexBuffer9();
+
+ HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
+ HRESULT Unlock();
+ void UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
+
+ HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown
+{
+ CGLMProgram *m_pixProgram;
+ uint m_pixHighWater; // count of active constant slots referenced by shader.
+ uint m_pixSamplerMask; // (1<<n) mask of samplers referemnced by this pixel shader
+ // this can help FlushSamplers avoid SRGB flipping on textures not being referenced...
+ uint m_pixSamplerTypes; // SAMPLER_TYPE_2D, etc.
+
+ virtual ~IDirect3DPixelShader9();
+};
+
+struct TOGL_CLASS IDirect3DVertexShader9 : public IDirect3DResource9 //was IUnknown
+{
+ CGLMProgram *m_vtxProgram;
+ uint m_vtxHighWater; // count of active constant slots referenced by shader.
+ uint m_vtxHighWaterBone;
+ unsigned char m_vtxAttribMap[16]; // high nibble is usage, low nibble is usageindex, array position is attrib number
+ uint m_maxVertexAttrs;
+
+ virtual ~IDirect3DVertexShader9();
+};
+
+#ifdef _MSC_VER
+ typedef class TOGL_CLASS CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator;
+ typedef class TOGL_CLASS CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack;
+#else
+ typedef class CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator;
+ typedef class CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack;
+#endif
+
+struct TOGL_CLASS ID3DXMatrixStack //: public IUnknown
+{
+ int m_refcount[2];
+ bool m_mark;
+ CD3DMATRIXStack m_stack;
+ int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases.
+
+ ID3DXMatrixStack();
+ void AddRef( int which=0, char *comment = NULL );
+ ULONG Release( int which=0, char *comment = NULL );
+
+ HRESULT Create( void );
+
+ D3DXMATRIX* GetTop();
+ void Push();
+ void Pop();
+ void LoadIdentity();
+ void LoadMatrix( const D3DXMATRIX *pMat );
+ void MultMatrix( const D3DXMATRIX *pMat );
+ void MultMatrixLocal( const D3DXMATRIX *pMat );
+ HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z);
+
+ // Left multiply the current matrix with the computed rotation
+ // matrix, counterclockwise about the given axis with the given angle.
+ // (rotation is about the local origin of the object)
+ HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle);
+
+ // Left multiply the current matrix with the computed translation
+ // matrix. (transformation is about the local origin of the object)
+ HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z);
+};
+
+typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK;
+
+struct RenderTargetState_t
+{
+ void clear() { V_memset( this, 0, sizeof( *this ) ); }
+
+ CGLMTex *m_pRenderTargets[4];
+ CGLMTex *m_pDepthStencil;
+
+ inline bool RefersTo( CGLMTex * pSurf ) const
+ {
+ for ( uint i = 0; i < 4; i++ )
+ if ( m_pRenderTargets[i] == pSurf )
+ return true;
+
+ if ( m_pDepthStencil == pSurf )
+ return true;
+
+ return false;
+ }
+
+ static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs )
+ {
+ COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) );
+ uint64 lhs0 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[0];
+ uint64 rhs0 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[0];
+ if ( lhs0 < rhs0 )
+ return true;
+ else if ( lhs0 == rhs0 )
+ {
+ uint64 lhs1 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[1];
+ uint64 rhs1 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[1];
+ if ( lhs1 < rhs1 )
+ return true;
+ else if ( lhs1 == rhs1 )
+ {
+ return lhs.m_pDepthStencil < rhs.m_pDepthStencil;
+ }
+ }
+ return false;
+ }
+
+ inline bool operator < ( const RenderTargetState_t &rhs ) const
+ {
+ return LessFunc( *this, rhs );
+ }
+};
+
+typedef CUtlMap< RenderTargetState_t, CGLMFBO *> CGLMFBOMap;
+
+class simple_bitmap;
+
+struct TOGL_CLASS IDirect3DDevice9 : public IUnknown
+{
+ friend class GLMContext;
+ friend struct IDirect3DBaseTexture9;
+ friend struct IDirect3DTexture9;
+ friend struct IDirect3DCubeTexture9;
+ friend struct IDirect3DVolumeTexture9;
+ friend struct IDirect3DSurface9;
+ friend struct IDirect3DVertexBuffer9;
+ friend struct IDirect3DIndexBuffer9;
+ friend struct IDirect3DPixelShader9;
+ friend struct IDirect3DVertexShader9;
+ friend struct IDirect3DQuery9;
+ friend struct IDirect3DVertexDeclaration9;
+
+ IDirect3DDevice9();
+ virtual ~IDirect3DDevice9();
+
+ // Create call invoked from IDirect3D9
+ HRESULT TOGLMETHODCALLTYPE Create( IDirect3DDevice9Params *params );
+
+ //
+ // Basics
+ //
+ HRESULT TOGLMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters);
+ HRESULT TOGLMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport);
+ HRESULT TOGLMETHODCALLTYPE BeginScene();
+ HRESULT TOGLMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
+ HRESULT TOGLMETHODCALLTYPE EndScene();
+ HRESULT TOGLMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
+
+ // textures
+ HRESULT TOGLMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT TOGLMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT TOGLMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture);
+ HRESULT TOGLMETHODCALLTYPE SetTextureNonInline(DWORD Stage,IDirect3DBaseTexture9* pTexture);
+
+ HRESULT TOGLMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture);
+
+ // render targets, color and depthstencil, surfaces, blit
+ HRESULT TOGLMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT TOGLMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget);
+ HRESULT TOGLMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget);
+
+ HRESULT TOGLMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
+
+ HRESULT TOGLMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
+ HRESULT TOGLMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil);
+ HRESULT TOGLMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface);
+
+ HRESULT TOGLMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface); // ? is anyone using this ?
+ HRESULT TOGLMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface);
+ HRESULT TOGLMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter);
+
+ // pixel shaders
+ HRESULT TOGLMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *debugLabel = NULL, const uint32 *pCentroidMask = NULL );
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader);
+ HRESULT TOGLMETHODCALLTYPE SetPixelShaderNonInline(IDirect3DPixelShader9* pShader);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+ HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+
+ HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
+ HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
+
+ // vertex shaders
+ HRESULT TOGLMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader, const char *pShaderName, char *debugLabel = NULL);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader);
+ HRESULT TOGLMETHODCALLTYPE SetVertexShaderNonInline(IDirect3DVertexShader9* pShader);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+ HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
+ HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantBNonInline(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
+ HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantINonInline(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
+
+ // POSIX only - preheating for a specific vertex/pixel shader pair - trigger GLSL link inside GLM
+ HRESULT TOGLMETHODCALLTYPE LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps );
+ HRESULT TOGLMETHODCALLTYPE QueryShaderPair( int index, GLMShaderPairInfo *infoOut );
+
+ // vertex buffers
+ HRESULT TOGLMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl);
+ HRESULT TOGLMETHODCALLTYPE SetVertexDeclarationNonInline(IDirect3DVertexDeclaration9* pDecl);
+
+ HRESULT TOGLMETHODCALLTYPE SetFVF(DWORD FVF); // we might not be using these ?
+ HRESULT TOGLMETHODCALLTYPE GetFVF(DWORD* pFVF);
+
+ HRESULT CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
+ HRESULT SetStreamSourceNonInline(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
+
+ // index buffers
+ HRESULT TOGLMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData);
+ HRESULT TOGLMETHODCALLTYPE SetIndicesNonInline(IDirect3DIndexBuffer9* pIndexData);
+
+ // State management.
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateInline(D3DRENDERSTATETYPE State,DWORD Value);
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateConstInline(D3DRENDERSTATETYPE State,DWORD Value);
+ HRESULT TOGLMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value);
+
+ FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
+ HRESULT TOGLMETHODCALLTYPE SetSamplerStateNonInline(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
+
+ FORCEINLINE void TOGLMETHODCALLTYPE SetSamplerStates(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter );
+ void TOGLMETHODCALLTYPE SetSamplerStatesNonInline(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter );
+
+ // Draw.
+ HRESULT TOGLMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount);
+ HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount);
+ HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride);
+
+ // misc
+ BOOL TOGLMETHODCALLTYPE ShowCursor(BOOL bShow);
+ HRESULT TOGLMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses);
+ HRESULT TOGLMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial);
+ HRESULT TOGLMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable);
+ HRESULT TOGLMETHODCALLTYPE SetScissorRect(CONST RECT* pRect);
+ HRESULT TOGLMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery);
+ HRESULT TOGLMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps);
+ HRESULT TOGLMETHODCALLTYPE TestCooperativeLevel();
+ HRESULT TOGLMETHODCALLTYPE EvictManagedResources();
+ HRESULT TOGLMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*);
+ void TOGLMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp);
+
+ void TOGLMETHODCALLTYPE SaveGLState();
+ void TOGLMETHODCALLTYPE RestoreGLState();
+
+ // Talk to JasonM about this one. It's tricky in GL.
+ HRESULT TOGLMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane);
+
+ //
+ //
+ // **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+ //
+ //
+ HRESULT TOGLMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix);
+ HRESULT TOGLMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value);
+
+ void TOGLMETHODCALLTYPE AcquireThreadOwnership( );
+ void TOGLMETHODCALLTYPE ReleaseThreadOwnership( );
+ inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
+
+ FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg );
+ void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg );
+
+ void DumpStatsToConsole( const CCommand *pArgs );
+
+#if GLMDEBUG
+ void DumpTextures( const CCommand *pArgs );
+#endif
+
+private:
+ IDirect3DDevice9( const IDirect3DDevice9& );
+ IDirect3DDevice9& operator= ( const IDirect3DDevice9& );
+
+ // Flushing changes to GL
+ void FlushClipPlaneEquation();
+ void InitStates();
+ void FullFlushStates();
+ void UpdateBoundFBO();
+ void ResetFBOMap();
+ void ScrubFBOMap( CGLMTex *pTex );
+
+ // response to retired objects (when refcount goes to zero and they self-delete..)
+ void ReleasedVertexDeclaration( IDirect3DVertexDeclaration9 *pDecl );
+ void ReleasedTexture( IDirect3DBaseTexture9 *baseTex ); // called from texture destructor - need to scrub samplers
+ void ReleasedCGLMTex( CGLMTex *pTex );
+ void ReleasedSurface( IDirect3DSurface9 *surface ); // called from any surface destructor - need to scrub RT table if an RT
+ void ReleasedPixelShader( IDirect3DPixelShader9 *pixelShader ); // called from IDirect3DPixelShader9 destructor
+ void ReleasedVertexShader( IDirect3DVertexShader9 *vertexShader ); // called from IDirect3DVertexShader9 destructor
+ void ReleasedVertexBuffer( IDirect3DVertexBuffer9 *vertexBuffer ); // called from IDirect3DVertexBuffer9 destructor
+ void ReleasedIndexBuffer( IDirect3DIndexBuffer9 *indexBuffer ); // called from IDirect3DIndexBuffer9 destructor
+ void ReleasedQuery( IDirect3DQuery9 *query ); // called from IDirect3DQuery9 destructor
+
+ // Member variables
+
+ DWORD m_nValidMarker;
+
+ IDirect3DDevice9Params m_params; // mirror of the creation inputs
+
+ // D3D flavor stuff
+ IDirect3DSurface9 *m_pRenderTargets[4];
+ IDirect3DSurface9 *m_pDepthStencil;
+
+ IDirect3DSurface9 *m_pDefaultColorSurface; // default color surface.
+ IDirect3DSurface9 *m_pDefaultDepthStencilSurface; // queried by GetDepthStencilSurface.
+
+ IDirect3DVertexDeclaration9 *m_pVertDecl; // Set by SetVertexDeclaration...
+ D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource..
+ CGLMBuffer *m_vtx_buffers[ D3D_MAX_STREAMS ];
+ CGLMBuffer *m_pDummy_vtx_buffer;
+ D3DIndexDesc m_indices; // Set by SetIndices..
+
+ IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader...
+ IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader...
+
+ IDirect3DBaseTexture9 *m_textures[16]; // set by SetTexture... NULL if stage inactive
+ D3DSamplerDesc m_samplers[16]; // set by SetSamplerState..
+ // GLM flavor stuff
+ GLMContext *m_ctx;
+ CGLMFBOMap *m_pFBOs;
+ bool m_bFBODirty;
+
+ struct ObjectStats_t
+ {
+ int m_nTotalFBOs;
+ int m_nTotalVertexShaders;
+ int m_nTotalPixelShaders;
+ int m_nTotalVertexDecls;
+ int m_nTotalIndexBuffers;
+ int m_nTotalVertexBuffers;
+ int m_nTotalRenderTargets;
+ int m_nTotalTextures;
+ int m_nTotalSurfaces;
+ int m_nTotalQueries;
+
+ void clear() { V_memset( this, 0, sizeof(* this ) ); }
+
+ ObjectStats_t &operator -= ( const ObjectStats_t &rhs )
+ {
+ m_nTotalFBOs -= rhs.m_nTotalFBOs;
+ m_nTotalVertexShaders -= rhs.m_nTotalVertexShaders;
+ m_nTotalPixelShaders -= rhs.m_nTotalPixelShaders;
+ m_nTotalVertexDecls -= rhs.m_nTotalVertexDecls;
+ m_nTotalIndexBuffers -= rhs.m_nTotalIndexBuffers;
+ m_nTotalVertexBuffers -= rhs.m_nTotalVertexBuffers;
+ m_nTotalRenderTargets -= rhs.m_nTotalRenderTargets;
+ m_nTotalTextures -= rhs.m_nTotalTextures;
+ m_nTotalSurfaces -= rhs.m_nTotalSurfaces;
+ m_nTotalQueries -= m_nTotalQueries;
+ return *this;
+ }
+ };
+ ObjectStats_t m_ObjectStats;
+ ObjectStats_t m_PrevObjectStats;
+ void PrintObjectStats( const ObjectStats_t &stats );
+
+ // GL state
+ struct
+ {
+ // render state buckets
+ GLAlphaTestEnable_t m_AlphaTestEnable;
+ GLAlphaTestFunc_t m_AlphaTestFunc;
+
+ GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable;
+
+ GLDepthTestEnable_t m_DepthTestEnable;
+ GLDepthMask_t m_DepthMask;
+ GLDepthFunc_t m_DepthFunc;
+
+ GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes];
+ GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes];
+
+ GLColorMaskSingle_t m_ColorMaskSingle;
+ GLColorMaskMultiple_t m_ColorMaskMultiple;
+
+ GLCullFaceEnable_t m_CullFaceEnable;
+ GLCullFrontFace_t m_CullFrontFace;
+ GLPolygonMode_t m_PolygonMode;
+ GLDepthBias_t m_DepthBias;
+ GLScissorEnable_t m_ScissorEnable;
+ GLScissorBox_t m_ScissorBox;
+ GLViewportBox_t m_ViewportBox;
+ GLViewportDepthRange_t m_ViewportDepthRange;
+
+ GLBlendEnable_t m_BlendEnable;
+ GLBlendFactor_t m_BlendFactor;
+ GLBlendEquation_t m_BlendEquation;
+ GLBlendColor_t m_BlendColor;
+ GLBlendEnableSRGB_t m_BlendEnableSRGB;
+
+ GLStencilTestEnable_t m_StencilTestEnable;
+ GLStencilFunc_t m_StencilFunc;
+ GLStencilOp_t m_StencilOp;
+ GLStencilWriteMask_t m_StencilWriteMask;
+
+ GLClearColor_t m_ClearColor;
+ GLClearDepth_t m_ClearDepth;
+ GLClearStencil_t m_ClearStencil;
+
+ bool m_FogEnable; // not really pushed to GL, just latched here
+
+ // samplers
+ GLMTexSamplingParams m_samplers[ 16 ];
+ } gl;
+
+#if GL_BATCH_PERF_ANALYSIS
+ simple_bitmap *m_pBatch_vis_bitmap;
+ uint m_nBatchVisY;
+ uint m_nBatchVisFrameIndex, m_nBatchVisFileIdx;
+ uint m_nNumProgramChanges;
+
+ uint m_nTotalD3DCalls;
+ double m_flTotalD3DTime;
+ uint m_nTotalGLCalls;
+ double m_flTotalGLTime;
+ uint m_nTotalPrims;
+
+ uint m_nOverallProgramChanges;
+ uint m_nOverallDraws;
+ uint m_nOverallPrims;
+ uint m_nOverallD3DCalls;
+ double m_flOverallD3DTime;
+ uint m_nOverallGLCalls;
+ double m_flOverallGLTime;
+
+ double m_flOverallPresentTime;
+ double m_flOverallPresentTimeSquared;
+ double m_flOverallSwapWindowTime;
+ double m_flOverallSwapWindowTimeSquared;
+ uint m_nOverallPresents;
+#endif
+};
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value )
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetSamplerStateNonInline( Sampler, Type, Value );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ Assert( Sampler < 16 );
+
+ m_ctx->SetSamplerDirty( Sampler );
+
+ switch( Type )
+ {
+ case D3DSAMP_ADDRESSU:
+ m_ctx->SetSamplerAddressU( Sampler, Value );
+ break;
+ case D3DSAMP_ADDRESSV:
+ m_ctx->SetSamplerAddressV( Sampler, Value );
+ break;
+ case D3DSAMP_ADDRESSW:
+ m_ctx->SetSamplerAddressW( Sampler, Value );
+ break;
+ case D3DSAMP_BORDERCOLOR:
+ m_ctx->SetSamplerBorderColor( Sampler, Value );
+ break;
+ case D3DSAMP_MAGFILTER:
+ m_ctx->SetSamplerMagFilter( Sampler, Value );
+ break;
+ case D3DSAMP_MIPFILTER:
+ m_ctx->SetSamplerMipFilter( Sampler, Value );
+ break;
+ case D3DSAMP_MINFILTER:
+ m_ctx->SetSamplerMinFilter( Sampler, Value );
+ break;
+ case D3DSAMP_MIPMAPLODBIAS:
+ m_ctx->SetSamplerMipMapLODBias( Sampler, Value );
+ break;
+ case D3DSAMP_MAXMIPLEVEL:
+ m_ctx->SetSamplerMaxMipLevel( Sampler, Value);
+ break;
+ case D3DSAMP_MAXANISOTROPY:
+ m_ctx->SetSamplerMaxAnisotropy( Sampler, Value);
+ break;
+ case D3DSAMP_SRGBTEXTURE:
+ m_samplers[ Sampler ].m_srgb = Value;
+ m_ctx->SetSamplerSRGBTexture(Sampler, Value);
+ break;
+ case D3DSAMP_SHADOWFILTER:
+ m_ctx->SetShadowFilter(Sampler, Value);
+ break;
+
+ default: DXABSTRACT_BREAK_ON_ERROR(); break;
+ }
+ return S_OK;
+#endif
+}
+
+FORCEINLINE void TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerStates(
+ DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW,
+ DWORD MinFilter, DWORD MagFilter, DWORD MipFilter )
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ SetSamplerStatesNonInline( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ Assert( Sampler < 16);
+
+ m_ctx->SetSamplerDirty( Sampler );
+
+ m_ctx->SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetTextureNonInline( Stage, pTexture );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_textures[Stage] = pTexture;
+ m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL );
+ return S_OK;
+#endif
+}
+
+inline GLenum D3DCompareFuncToGL( DWORD function )
+{
+ switch ( function )
+ {
+ case D3DCMP_NEVER : return GL_NEVER; // Always fail the test.
+ case D3DCMP_LESS : return GL_LESS; // Accept the new pixel if its value is less than the value of the current pixel.
+ case D3DCMP_EQUAL : return GL_EQUAL; // Accept the new pixel if its value equals the value of the current pixel.
+ case D3DCMP_LESSEQUAL : return GL_LEQUAL; // Accept the new pixel if its value is less than or equal to the value of the current pixel. **
+ case D3DCMP_GREATER : return GL_GREATER; // Accept the new pixel if its value is greater than the value of the current pixel.
+ case D3DCMP_NOTEQUAL : return GL_NOTEQUAL; // Accept the new pixel if its value does not equal the value of the current pixel.
+ case D3DCMP_GREATEREQUAL: return GL_GEQUAL; // Accept the new pixel if its value is greater than or equal to the value of the current pixel.
+ case D3DCMP_ALWAYS : return GL_ALWAYS; // Always pass the test.
+ default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF;
+ }
+}
+
+FORCEINLINE GLenum D3DBlendOperationToGL( DWORD operation )
+{
+ switch (operation)
+ {
+ case D3DBLENDOP_ADD : return GL_FUNC_ADD; // The result is the destination added to the source. Result = Source + Destination
+
+ /* not covered by dxabstract.h..
+ case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination
+ case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source
+ case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination)
+ case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination)
+ */
+ default:
+ DXABSTRACT_BREAK_ON_ERROR();
+ return 0xFFFFFFFF;
+ break;
+ }
+}
+
+FORCEINLINE GLenum D3DBlendFactorToGL( DWORD equation )
+{
+ switch (equation)
+ {
+ case D3DBLEND_ZERO : return GL_ZERO; // Blend factor is (0, 0, 0, 0).
+ case D3DBLEND_ONE : return GL_ONE; // Blend factor is (1, 1, 1, 1).
+ case D3DBLEND_SRCCOLOR : return GL_SRC_COLOR; // Blend factor is (Rs, Gs, Bs, As).
+ case D3DBLEND_INVSRCCOLOR : return GL_ONE_MINUS_SRC_COLOR; // Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As).
+ case D3DBLEND_SRCALPHA : return GL_SRC_ALPHA; // Blend factor is (As, As, As, As).
+ case D3DBLEND_INVSRCALPHA : return GL_ONE_MINUS_SRC_ALPHA; // Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As).
+ case D3DBLEND_DESTALPHA : return GL_DST_ALPHA; // Blend factor is (Ad Ad Ad Ad).
+ case D3DBLEND_INVDESTALPHA : return GL_ONE_MINUS_DST_ALPHA; // Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad).
+ case D3DBLEND_DESTCOLOR : return GL_DST_COLOR; // Blend factor is (Rd, Gd, Bd, Ad).
+ case D3DBLEND_INVDESTCOLOR : return GL_ONE_MINUS_DST_COLOR; // Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad).
+ case D3DBLEND_SRCALPHASAT : return GL_SRC_ALPHA_SATURATE; // Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad).
+
+ /*
+ // these are weird.... break if we hit them
+ case D3DBLEND_BOTHSRCALPHA : Assert(0); return GL_ZERO; // Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls.
+ case D3DBLEND_BOTHINVSRCALPHA: Assert(0); return GL_ZERO; // Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state.
+ case D3DBLEND_BLENDFACTOR : Assert(0); return GL_ZERO; // Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
+
+ dxabstract.h has not heard of these, so let them hit the debugger if they come through
+ case D3DBLEND_INVBLENDFACTOR: //Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
+ case D3DBLEND_SRCCOLOR2: // Blend factor is (PSOutColor[1]r, PSOutColor[1]g, PSOutColor[1]b, not used). This flag is available in Direct3D 9Ex only.
+ case D3DBLEND_INVSRCCOLOR2: // Blend factor is (1 - PSOutColor[1]r, 1 - PSOutColor[1]g, 1 - PSOutColor[1]b, not used)). This flag is available in Direct3D 9Ex only.
+ */
+ default:
+ DXABSTRACT_BREAK_ON_ERROR();
+ return 0xFFFFFFFF;
+ break;
+ }
+}
+
+
+FORCEINLINE GLenum D3DStencilOpToGL( DWORD operation )
+{
+ switch( operation )
+ {
+ case D3DSTENCILOP_KEEP : return GL_KEEP;
+ case D3DSTENCILOP_ZERO : return GL_ZERO;
+ case D3DSTENCILOP_REPLACE : return GL_REPLACE;
+ case D3DSTENCILOP_INCRSAT : return GL_INCR;
+ case D3DSTENCILOP_DECRSAT : return GL_DECR;
+ case D3DSTENCILOP_INVERT : return GL_INVERT;
+ case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
+ case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
+ default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF;
+ }
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateInline( D3DRENDERSTATETYPE State, DWORD Value )
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetRenderState( State, Value );
+#else
+ TOGL_NULL_DEVICE_CHECK;
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+
+ switch (State)
+ {
+ case D3DRS_ZENABLE: // kGLDepthTestEnable
+ {
+ gl.m_DepthTestEnable.enable = Value;
+ m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable );
+ break;
+ }
+ case D3DRS_ZWRITEENABLE: // kGLDepthMask
+ {
+ gl.m_DepthMask.mask = Value;
+ m_ctx->WriteDepthMask( &gl.m_DepthMask );
+ break;
+ }
+ case D3DRS_ZFUNC:
+ {
+ // kGLDepthFunc
+ GLenum func = D3DCompareFuncToGL( Value );
+ gl.m_DepthFunc.func = func;
+ m_ctx->WriteDepthFunc( &gl.m_DepthFunc );
+ break;
+ }
+ case D3DRS_COLORWRITEENABLE: // kGLColorMaskSingle
+ {
+ gl.m_ColorMaskSingle.r = ((Value & D3DCOLORWRITEENABLE_RED) != 0) ? 0xFF : 0x00;
+ gl.m_ColorMaskSingle.g = ((Value & D3DCOLORWRITEENABLE_GREEN)!= 0) ? 0xFF : 0x00;
+ gl.m_ColorMaskSingle.b = ((Value & D3DCOLORWRITEENABLE_BLUE) != 0) ? 0xFF : 0x00;
+ gl.m_ColorMaskSingle.a = ((Value & D3DCOLORWRITEENABLE_ALPHA)!= 0) ? 0xFF : 0x00;
+ m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle );
+ break;
+ }
+ case D3DRS_CULLMODE: // kGLCullFaceEnable / kGLCullFrontFace
+ {
+ switch (Value)
+ {
+ case D3DCULL_NONE:
+ {
+ gl.m_CullFaceEnable.enable = false;
+ gl.m_CullFrontFace.value = GL_CCW; //doesn't matter
+
+ m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
+ m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
+ break;
+ }
+
+ case D3DCULL_CW:
+ {
+ gl.m_CullFaceEnable.enable = true;
+ gl.m_CullFrontFace.value = GL_CW; //origGL_CCW;
+
+ m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
+ m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
+ break;
+ }
+ case D3DCULL_CCW:
+ {
+ gl.m_CullFaceEnable.enable = true;
+ gl.m_CullFrontFace.value = GL_CCW; //origGL_CW;
+
+ m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
+ m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
+ break;
+ }
+ default:
+ {
+ DXABSTRACT_BREAK_ON_ERROR();
+ break;
+ }
+ }
+ break;
+ }
+ //-------------------------------------------------------------------------------------------- alphablend stuff
+ case D3DRS_ALPHABLENDENABLE: // kGLBlendEnable
+ {
+ gl.m_BlendEnable.enable = Value;
+ m_ctx->WriteBlendEnable( &gl.m_BlendEnable );
+ break;
+ }
+ case D3DRS_BLENDOP: // kGLBlendEquation // D3D blend-op ==> GL blend equation
+ {
+ GLenum equation = D3DBlendOperationToGL( Value );
+ gl.m_BlendEquation.equation = equation;
+ m_ctx->WriteBlendEquation( &gl.m_BlendEquation );
+ break;
+ }
+ case D3DRS_SRCBLEND: // kGLBlendFactor // D3D blend-factor ==> GL blend factor
+ case D3DRS_DESTBLEND: // kGLBlendFactor
+ {
+ GLenum factor = D3DBlendFactorToGL( Value );
+
+ if (State==D3DRS_SRCBLEND)
+ {
+ gl.m_BlendFactor.srcfactor = factor;
+ }
+ else
+ {
+ gl.m_BlendFactor.dstfactor = factor;
+ }
+ m_ctx->WriteBlendFactor( &gl.m_BlendFactor );
+ break;
+ }
+ case D3DRS_SRGBWRITEENABLE: // kGLBlendEnableSRGB
+ {
+ gl.m_BlendEnableSRGB.enable = Value;
+ m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB );
+ break;
+ }
+ //-------------------------------------------------------------------------------------------- alphatest stuff
+ case D3DRS_ALPHATESTENABLE:
+ {
+ gl.m_AlphaTestEnable.enable = Value;
+ m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable );
+ break;
+ }
+ case D3DRS_ALPHAREF:
+ {
+ gl.m_AlphaTestFunc.ref = Value / 255.0f;
+ m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc );
+ break;
+ }
+ case D3DRS_ALPHAFUNC:
+ {
+ GLenum func = D3DCompareFuncToGL( Value );;
+ gl.m_AlphaTestFunc.func = func;
+ m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc );
+ break;
+ }
+ //-------------------------------------------------------------------------------------------- stencil stuff
+ case D3DRS_STENCILENABLE: // GLStencilTestEnable_t
+ {
+ gl.m_StencilTestEnable.enable = Value;
+ m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable );
+ break;
+ }
+ case D3DRS_STENCILFAIL: // GLStencilOp_t "what do you do if stencil test fails"
+ {
+ GLenum stencilop = D3DStencilOpToGL( Value );
+ gl.m_StencilOp.sfail = stencilop;
+
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
+ break;
+ }
+ case D3DRS_STENCILZFAIL: // GLStencilOp_t "what do you do if stencil test passes *but* depth test fails, if depth test happened"
+ {
+ GLenum stencilop = D3DStencilOpToGL( Value );
+ gl.m_StencilOp.dpfail = stencilop;
+
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
+ break;
+ }
+ case D3DRS_STENCILPASS: // GLStencilOp_t "what do you do if stencil test and depth test both pass"
+ {
+ GLenum stencilop = D3DStencilOpToGL( Value );
+ gl.m_StencilOp.dppass = stencilop;
+
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
+ m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
+ break;
+ }
+ case D3DRS_STENCILFUNC: // GLStencilFunc_t
+ {
+ GLenum stencilfunc = D3DCompareFuncToGL( Value );
+ gl.m_StencilFunc.frontfunc = gl.m_StencilFunc.backfunc = stencilfunc;
+
+ m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
+ break;
+ }
+ case D3DRS_STENCILREF: // GLStencilFunc_t
+ {
+ gl.m_StencilFunc.ref = Value;
+ m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
+ break;
+ }
+ case D3DRS_STENCILMASK: // GLStencilFunc_t
+ {
+ gl.m_StencilFunc.mask = Value;
+ m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
+ break;
+ }
+ case D3DRS_STENCILWRITEMASK: // GLStencilWriteMask_t
+ {
+ gl.m_StencilWriteMask.mask = Value;
+ m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask );
+ break;
+ }
+ case D3DRS_FOGENABLE: // none of these are implemented yet... erk
+ {
+ gl.m_FogEnable = (Value != 0);
+ GLMPRINTF(("-D- fogenable = %d",Value ));
+ break;
+ }
+ case D3DRS_SCISSORTESTENABLE: // kGLScissorEnable
+ {
+ gl.m_ScissorEnable.enable = Value;
+ m_ctx->WriteScissorEnable( &gl.m_ScissorEnable );
+ break;
+ }
+ case D3DRS_DEPTHBIAS: // kGLDepthBias
+ {
+ // the value in the dword is actually a float
+ float fvalue = *(float*)&Value;
+ gl.m_DepthBias.units = fvalue;
+
+ m_ctx->WriteDepthBias( &gl.m_DepthBias );
+ break;
+ }
+ // good ref on these: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/
+ case D3DRS_SLOPESCALEDEPTHBIAS:
+ {
+ // the value in the dword is actually a float
+ float fvalue = *(float*)&Value;
+ gl.m_DepthBias.factor = fvalue;
+
+ m_ctx->WriteDepthBias( &gl.m_DepthBias );
+ break;
+ }
+ // Alpha to coverage
+ case D3DRS_ADAPTIVETESS_Y:
+ {
+ gl.m_AlphaToCoverageEnable.enable = Value;
+ m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable );
+ break;
+ }
+ case D3DRS_CLIPPLANEENABLE: // kGLClipPlaneEnable
+ {
+ // d3d packs all the enables into one word.
+ // we break that out so we don't do N glEnable calls to sync -
+ // GLM is tracking one unique enable per plane.
+ for( int i=0; i<kGLMUserClipPlanes; i++)
+ {
+ gl.m_ClipPlaneEnable[i].enable = (Value & (1<<i)) != 0;
+ }
+
+ for( int x=0; x<kGLMUserClipPlanes; x++)
+ m_ctx->WriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x );
+ break;
+ }
+ //-------------------------------------------------------------------------------------------- polygon/fill mode
+ case D3DRS_FILLMODE:
+ {
+ GLuint mode = 0;
+ switch(Value)
+ {
+ case D3DFILL_POINT: mode = GL_POINT; break;
+ case D3DFILL_WIREFRAME: mode = GL_LINE; break;
+ case D3DFILL_SOLID: mode = GL_FILL; break;
+ default: DXABSTRACT_BREAK_ON_ERROR(); break;
+ }
+ gl.m_PolygonMode.values[0] = gl.m_PolygonMode.values[1] = mode;
+ m_ctx->WritePolygonMode( &gl.m_PolygonMode );
+ break;
+ }
+ }
+
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateConstInline( D3DRENDERSTATETYPE State, DWORD Value )
+{
+ // State is a compile time constant - luckily no need to do anything special to get the compiler to optimize this case.
+ return SetRenderStateInline( State, Value );
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetIndicesNonInline( pIndexData );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ // just latch it.
+ m_indices.m_idxBuffer = pIndexData;
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetStreamSourceNonInline( StreamNumber, pStreamData, OffsetInBytes, Stride );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ Assert( StreamNumber < D3D_MAX_STREAMS );
+ Assert( ( Stride & 3 ) == 0 ); // we support non-DWORD aligned strides, but on some drivers (like AMD's) perf goes off a cliff
+
+ // perfectly legal to see a vertex buffer of NULL get passed in here.
+ // so we need an array to track these.
+ // OK, we are being given the stride, we don't need to calc it..
+
+ GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_name: -1, OffsetInBytes, Stride));
+
+ if ( !pStreamData )
+ {
+ OffsetInBytes = 0;
+ Stride = 0;
+
+ m_vtx_buffers[ StreamNumber ] = m_pDummy_vtx_buffer;
+ }
+ else
+ {
+ // We do not support strides of 0
+ Assert( Stride > 0 );
+ m_vtx_buffers[ StreamNumber ] = pStreamData->m_vtxBuffer;
+ }
+
+ m_streams[ StreamNumber ].m_vtxBuffer = pStreamData;
+ m_streams[ StreamNumber ].m_offset = OffsetInBytes;
+ m_streams[ StreamNumber ].m_stride = Stride;
+
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) // groups of 4 floats!
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetVertexShaderConstantFNonInline( StartRegister, pConstantData, Vector4fCount );
+#else
+ TOGL_NULL_DEVICE_CHECK;
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetProgramParametersF( kGLMVertexProgram, StartRegister, (float *)pConstantData, Vector4fCount );
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetVertexShaderConstantBNonInline( StartRegister, pConstantData, BoolCount );
+#else
+ TOGL_NULL_DEVICE_CHECK;
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetProgramParametersB( kGLMVertexProgram, StartRegister, (int *)pConstantData, BoolCount );
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT IDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) // groups of 4 ints!
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetVertexShaderConstantINonInline( StartRegister, pConstantData, Vector4iCount );
+#else
+ TOGL_NULL_DEVICE_CHECK;
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetProgramParametersI( kGLMVertexProgram, StartRegister, (int *)pConstantData, Vector4iCount );
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetPixelShaderConstantFNonInline(StartRegister, pConstantData, Vector4fCount);
+#else
+ TOGL_NULL_DEVICE_CHECK;
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetProgramParametersF( kGLMFragmentProgram, StartRegister, (float *)pConstantData, Vector4fCount );
+ return S_OK;
+#endif
+}
+
+HRESULT IDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetVertexShaderNonInline(pShader);
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetVertexProgram( pShader ? pShader->m_vtxProgram : NULL );
+ m_vertexShader = pShader;
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetPixelShaderNonInline(pShader);
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetFragmentProgram( pShader ? pShader->m_pixProgram : NULL );
+ m_pixelShader = pShader;
+ return S_OK;
+#endif
+}
+
+FORCEINLINE HRESULT IDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl)
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetVertexDeclarationNonInline(pDecl);
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_pVertDecl = pDecl;
+ return S_OK;
+#endif
+}
+
+FORCEINLINE void IDirect3DDevice9::SetMaxUsedVertexShaderConstantsHint( uint nMaxReg )
+{
+#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
+ return SetMaxUsedVertexShaderConstantsHintNonInline( nMaxReg );
+#else
+ Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
+ m_ctx->SetMaxUsedVertexShaderConstantsHint( nMaxReg );
+#endif
+}
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// D3DX
+// ------------------------------------------------------------------------------------------------------------------------------ //
+struct ID3DXInclude
+{
+ virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes);
+ virtual HRESULT Close(LPCVOID pData);
+};
+typedef ID3DXInclude* LPD3DXINCLUDE;
+
+
+struct TOGL_CLASS ID3DXBuffer : public IUnknown
+{
+ void* GetBufferPointer();
+ DWORD GetBufferSize();
+};
+
+typedef ID3DXBuffer* LPD3DXBUFFER;
+
+class ID3DXConstantTable : public IUnknown
+{
+};
+typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE;
+
+TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 );
+TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack);
+TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * );
+
+TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ pOut->x = pV1->x - pV2->x;
+ pOut->y = pV1->y - pV2->y;
+ pOut->z = pV1->z - pV2->z;
+ return pOut;
+}
+
+TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ D3DXVECTOR3 v;
+
+ v.x = pV1->y * pV2->z - pV1->z * pV2->y;
+ v.y = pV1->z * pV2->x - pV1->x * pV2->z;
+ v.z = pV1->x * pV2->y - pV1->y * pV2->x;
+
+ *pOut = v;
+ return pOut;
+}
+
+TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z;
+}
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP);
+
+TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM );
+
+
+TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
+
+// Build an ortho projection matrix. (right-handed)
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf );
+
+// Transform a plane by a matrix. The vector (a,b,c) must be normal.
+// M should be the inverse transpose of the transformation desired.
+TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion);
+
+TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions );
+
+TOGL_INTERFACE HRESULT D3DXCompileShader(
+ LPCSTR pSrcData,
+ UINT SrcDataLen,
+ CONST D3DXMACRO* pDefines,
+ LPD3DXINCLUDE pInclude,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ LPD3DXBUFFER* ppShader,
+ LPD3DXBUFFER* ppErrorMsgs,
+ LPD3DXCONSTANTTABLE* ppConstantTable);
+
+// fake D3D usage constant for SRGB tex creation
+#define D3DUSAGE_TEXTURE_SRGB (0x80000000L)
+
+#else
+
+ //USE_ACTUAL_DX
+ #ifndef WIN32
+ #error sorry man
+ #endif
+
+ #ifdef _X360
+ #include "d3d9.h"
+ #include "d3dx9.h"
+ #else
+ #include <windows.h>
+ #include "../../dx9sdk/include/d3d9.h"
+ #include "../../dx9sdk/include/d3dx9.h"
+ #endif
+ typedef HWND VD3DHWND;
+
+#endif // DX_TO_GL_ABSTRACTION
+
+#endif // DXABSTRACT_H
diff --git a/mp/src/public/togl/linuxwin/dxabstract_types.h b/mp/src/public/togl/linuxwin/dxabstract_types.h new file mode 100644 index 00000000..c021ca78 --- /dev/null +++ b/mp/src/public/togl/linuxwin/dxabstract_types.h @@ -0,0 +1,1712 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// dxabstract_types.h
+//
+//==================================================================================================
+#ifndef DXABSTRACT_TYPES_H
+#define DXABSTRACT_TYPES_H
+
+#pragma once
+
+#if GL_BATCH_PERF_ANALYSIS
+ class simple_bitmap;
+#endif
+
+struct IUnknown;
+struct IDirect3D9;
+struct IDirect3DDevice9;
+struct IDirect3DResource9;
+struct IDirect3DBaseTexture9;
+struct IDirect3DTexture9;
+struct IDirect3DCubeTexture9;
+struct IDirect3DVolumeTexture9;
+struct IDirect3DSurface9;
+struct IDirect3DVertexDeclaration9;
+struct IDirect3DQuery9;
+struct IDirect3DVertexBuffer9;
+struct IDirect3DIndexBuffer9;
+struct IDirect3DPixelShader9;
+struct IDirect3DVertexShader9;
+struct IDirect3DDevice9Params;
+
+class GLMContext;
+struct GLMRect;
+struct GLMShaderPairInfo;
+class CGLMBuffer;
+class CGLMQuery;
+class CGLMTex;
+class CGLMProgram;
+class CGLMFBO;
+
+#ifdef TOGL_DLL_EXPORT
+ #define TOGL_INTERFACE DLL_EXPORT
+ #define TOGL_OVERLOAD DLL_GLOBAL_EXPORT
+ #define TOGL_CLASS DLL_CLASS_EXPORT
+ #define TOGL_GLOBAL DLL_GLOBAL_EXPORT
+#else
+ #define TOGL_INTERFACE DLL_IMPORT
+ #define TOGL_OVERLOAD DLL_GLOBAL_IMPORT
+ #define TOGL_CLASS DLL_CLASS_IMPORT
+ #define TOGL_GLOBAL DLL_GLOBAL_IMPORT
+#endif
+
+#ifdef OSX
+#error "Do not use this header's types on OSX until togo is ported to Mac!"
+#endif
+
+#define TOGLMETHODCALLTYPE __stdcall
+//#define TOGLMETHODCALLTYPE
+
+#define DXABSTRACT_BREAK_ON_ERROR() DebuggerBreak()
+
+typedef void* VD3DHWND;
+typedef void* VD3DHANDLE;
+
+#define MAKEFOURCC(ch0, ch1, ch2, ch3) ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+
+//
+//
+// Stuff that would be in windows.h
+//
+//
+#if !defined(_WINNT_)
+
+ typedef int INT;
+ typedef unsigned long ULONG;
+ typedef long LONG;
+ typedef float FLOAT;
+ typedef unsigned int DWORD;
+ typedef unsigned short WORD;
+ typedef long long LONGLONG;
+ typedef unsigned int UINT;
+ typedef long HRESULT;
+ typedef unsigned char BYTE;
+ #define CONST const
+
+ #if defined(POSIX)
+ typedef size_t ULONG_PTR;
+ #else
+ typedef unsigned long ULONG_PTR;
+ #endif
+
+ typedef ULONG_PTR SIZE_T;
+
+ typedef const char* LPCSTR;
+ typedef char* LPSTR;
+ typedef DWORD* LPDWORD;
+
+ #define ZeroMemory RtlZeroMemory
+ #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
+
+ typedef union _LARGE_INTEGER
+ {
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+ } LARGE_INTEGER;
+
+ typedef struct _GUID
+ {
+ bool operator==( const struct _GUID &other ) const;
+
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+ } GUID;
+
+ typedef struct _RECT
+ {
+ int left;
+ int top;
+ int right;
+ int bottom;
+ } RECT;
+
+ typedef struct tagPOINT
+ {
+ LONG x;
+ LONG y;
+ } POINT, *PPOINT, *LPPOINT;
+
+ typedef struct _MEMORYSTATUS
+ {
+ DWORD dwLength;
+ SIZE_T dwTotalPhys;
+ } MEMORYSTATUS, *LPMEMORYSTATUS;
+
+ typedef DWORD COLORREF;
+ #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+
+ #define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
+
+ #define S_FALSE ((HRESULT)0x00000001L)
+ #define S_OK 0
+ #define E_FAIL ((HRESULT)0x80004005L)
+ #define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+
+ #define FAILED(hr) ((HRESULT)(hr) < 0)
+ #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
+
+ struct RGNDATA
+ {
+ };
+
+ typedef const void* LPCVOID;
+#endif
+
+//-----------------------------------------------------------------------------
+
+typedef enum _D3DFORMAT D3DFORMAT;
+
+#define D3DSI_OPCODE_MASK 0x0000FFFF
+#define D3DSP_TEXTURETYPE_MASK 0x78000000
+
+#define D3DUSAGE_AUTOGENMIPMAP 0x00000400L
+#define D3DSP_DCL_USAGE_MASK 0x0000000f
+
+#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000
+#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16
+
+
+/* Flags to construct D3DRS_COLORWRITEENABLE */
+#define D3DCOLORWRITEENABLE_RED (1L<<0)
+#define D3DCOLORWRITEENABLE_GREEN (1L<<1)
+#define D3DCOLORWRITEENABLE_BLUE (1L<<2)
+#define D3DCOLORWRITEENABLE_ALPHA (1L<<3)
+
+#define D3DSGR_NO_CALIBRATION 0x00000000L
+
+#define D3DXINLINE inline
+
+#define D3D_SDK_VERSION 32
+
+#define _FACD3D 0x876
+#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
+
+#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150)
+#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152)
+#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154)
+#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153)
+#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087)
+#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380)
+#define D3D_OK S_OK
+
+#define D3DPRESENT_RATE_DEFAULT 0x00000000
+
+//
+// DevCaps
+//
+// we need to see who in Source land is interested in these values, as dxabstract is currently reporting zero for the whole Caps word
+#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */
+#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */
+#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */
+#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */
+#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */
+#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */
+#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */
+#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */
+#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */
+#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */
+#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */
+#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */
+#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */
+#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */
+#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */
+
+//
+// PrimitiveMiscCaps
+//
+#define D3DPMISCCAPS_MASKZ 0x00000002L
+#define D3DPMISCCAPS_CULLNONE 0x00000010L
+#define D3DPMISCCAPS_CULLCW 0x00000020L
+#define D3DPMISCCAPS_CULLCCW 0x00000040L
+#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L
+#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */
+#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */
+#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */
+#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */
+#define D3DPMISCCAPS_NULLREFERENCE 0x00001000L /* Reference Device that doesnt render */
+#define D3DPMISCCAPS_PERSTAGECONSTANT 0x00008000L /* Device supports per-stage constants */
+#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000L /* Device supports different bit depths for MRT */
+#define D3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000L /* Device clamps fog blend factor per vertex */
+
+// Flags field for Issue
+#define D3DISSUE_END (1 << 0) // Tells the runtime to issue the end of a query, changing it's state to "non-signaled".
+#define D3DISSUE_BEGIN (1 << 1) // Tells the runtime to issue the beginng of a query.
+
+
+#define D3DPRESENT_INTERVAL_ONE 0x00000001L
+#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L
+
+/*
+ * Options for clearing
+ */
+#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */
+#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */
+#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */
+
+
+#define D3DENUM_WHQL_LEVEL 0x00000002L
+
+
+
+
+#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation
+ in programmable and fixed function pixel shaders */
+#define D3DDEVCAPS2_STREAMOFFSET 0x00000001L /* Device supports offsets in streams. Must be set by DX9 drivers */
+
+#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */
+
+#define D3DCREATE_PUREDEVICE 0x00000010L
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L
+#define D3DCREATE_FPU_PRESERVE 0x00000002L
+#define D3DPRASTERCAPS_FOGRANGE 0x00010000L
+#define D3DPRASTERCAPS_FOGTABLE 0x00000100L
+#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L
+#define D3DPRASTERCAPS_WFOG 0x00100000L
+#define D3DPRASTERCAPS_ZFOG 0x00200000L
+#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L
+#define D3DPRASTERCAPS_WBUFFER 0x00040000L
+#define D3DPRASTERCAPS_ZTEST 0x00000010L
+
+//
+// Caps2
+//
+#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L
+#define D3DPRASTERCAPS_SCISSORTEST 0x01000000L
+#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */
+#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */
+#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */
+#define D3DCREATE_MULTITHREADED 0x00000004L
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */
+#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L
+#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L
+#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */
+#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */
+#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L
+#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */
+#define D3DTEXOPCAPS_ADD 0x00000040L
+#define D3DTEXOPCAPS_MODULATE2X 0x00000010L
+#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L
+#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L
+#define D3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100L /* device supports D3DTSS_TCI_SPHEREMAP */
+#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L
+
+// The following usages are valid only for querying CheckDeviceFormat
+#define D3DUSAGE_QUERY_SRGBREAD (0x00010000L)
+#define D3DUSAGE_QUERY_FILTER (0x00020000L)
+#define D3DUSAGE_QUERY_SRGBWRITE (0x00040000L)
+#define D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING (0x00080000L)
+#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L)
+
+/* Usages for Vertex/Index buffers */
+#define D3DUSAGE_WRITEONLY (0x00000008L)
+#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L)
+#define D3DUSAGE_DONOTCLIP (0x00000020L)
+#define D3DUSAGE_POINTS (0x00000040L)
+#define D3DUSAGE_RTPATCHES (0x00000080L)
+#define D3DUSAGE_NPATCHES (0x00000100L)
+
+
+// Flags field for GetData
+#define D3DGETDATA_FLUSH (1 << 0) // Tells the runtime to flush if the query is outstanding.
+
+#define D3DFVF_XYZ 0x002
+
+
+#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector
+#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only)
+#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write)
+#define D3DTA_TEXTURE 0x00000002 // select texture color (read only)
+#define D3DTA_TFACTOR 0x00000003 // select D3DRS_TEXTUREFACTOR (read only)
+#define D3DTA_SPECULAR 0x00000004 // select specular color (read only)
+#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write)
+#define D3DTA_CONSTANT 0x00000006 // select texture stage constant
+#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier)
+#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier)
+
+
+#define D3DUSAGE_RENDERTARGET (0x00000001L)
+#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L)
+#define D3DUSAGE_QUERY_FILTER (0x00020000L)
+#define D3DUSAGE_DEPTHSTENCIL (0x00000002L)
+#define D3DUSAGE_WRITEONLY (0x00000008L)
+#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L)
+#define D3DUSAGE_DYNAMIC (0x00000200L)
+
+#define D3DSI_INSTLENGTH_MASK 0x0F000000
+#define D3DSI_INSTLENGTH_SHIFT 24
+#define D3DSP_TEXTURETYPE_SHIFT 27
+#define D3DSP_REGTYPE_SHIFT 28
+#define D3DSP_REGTYPE_SHIFT2 8
+#define D3DSP_REGTYPE_MASK 0x70000000
+#define D3DSP_REGTYPE_MASK2 0x00001800
+
+#define D3DSP_REGNUM_MASK 0x000007FF
+
+#define D3DSP_DSTMOD_SHIFT 20
+#define D3DSP_DSTMOD_MASK 0x00F00000
+#define D3DSPDM_MSAMPCENTROID (4<<D3DSP_DSTMOD_SHIFT) // Relevant to multisampling only:
+ // When the pixel center is not covered, sample
+ // attribute or compute gradients/LOD
+ // using multisample "centroid" location.
+ // "Centroid" is some location within the covered
+ // region of the pixel.
+
+#define D3DXSHADER_DEBUG (1 << 0)
+#define D3DXSHADER_AVOID_FLOW_CONTROL (1 << 9)
+
+
+#define D3DLOCK_READONLY 0x00000010L
+#define D3DLOCK_DISCARD 0x00002000L
+#define D3DLOCK_NOOVERWRITE 0x00001000L
+#define D3DLOCK_NOSYSLOCK 0x00000800L
+
+#define D3DLOCK_NO_DIRTY_UPDATE 0x00008000L
+
+
+#define D3DDMAPSAMPLER 256
+#define D3DVERTEXTEXTURESAMPLER0 (D3DDMAPSAMPLER+1)
+#define D3DSP_SRCMOD_SHIFT 24
+
+
+#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
+#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b)
+#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)
+
+// maps floating point channels (0.f to 1.f range) to D3DCOLOR
+#define D3DCOLOR_COLORVALUE(r,g,b,a) \
+ D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f))
+
+#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
+
+#define D3DSP_DCL_USAGEINDEX_SHIFT 16
+#define D3DSP_DCL_USAGEINDEX_MASK 0x000f0000
+
+// Bit masks for destination parameter modifiers
+#define D3DSPDM_NONE (0<<D3DSP_DSTMOD_SHIFT) // nop
+#define D3DSPDM_SATURATE (1<<D3DSP_DSTMOD_SHIFT) // clamp to 0. to 1. range
+#define D3DSPDM_PARTIALPRECISION (2<<D3DSP_DSTMOD_SHIFT) // Partial precision hint
+#define D3DSPDM_MSAMPCENTROID (4<<D3DSP_DSTMOD_SHIFT) // Relevant to multisampling only:
+ // When the pixel center is not covered, sample
+ // attribute or compute gradients/LOD
+ // using multisample "centroid" location.
+ // "Centroid" is some location within the covered
+ // region of the pixel.
+
+// Value when there is no swizzle (X is taken from X, Y is taken from Y,
+// Z is taken from Z, W is taken from W
+//
+#define D3DVS_NOSWIZZLE (D3DVS_X_X | D3DVS_Y_Y | D3DVS_Z_Z | D3DVS_W_W)
+
+// extract major/minor from version cap
+#define D3DSHADER_VERSION_MAJOR(_Version) (((_Version)>>8)&0xFF)
+#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF)
+
+#define D3DSHADER_ADDRESSMODE_SHIFT 13
+#define D3DSHADER_ADDRESSMODE_MASK (1 << D3DSHADER_ADDRESSMODE_SHIFT)
+
+#define D3DPS_END() 0x0000FFFF
+
+// ps_2_0 texld controls
+#define D3DSI_TEXLD_PROJECT (0x01 << D3DSP_OPCODESPECIFICCONTROL_SHIFT)
+#define D3DSI_TEXLD_BIAS (0x02 << D3DSP_OPCODESPECIFICCONTROL_SHIFT)
+
+
+// destination parameter write mask
+#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red)
+#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green)
+#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue)
+#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha)
+#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components
+
+#define D3DVS_SWIZZLE_SHIFT 16
+#define D3DVS_SWIZZLE_MASK 0x00FF0000
+
+// The following bits define where to take component X from:
+
+#define D3DVS_X_X (0 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Y (1 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Z (2 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_W (3 << D3DVS_SWIZZLE_SHIFT)
+
+// The following bits define where to take component Y from:
+
+#define D3DVS_Y_X (0 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Y (1 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Z (2 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_W (3 << (D3DVS_SWIZZLE_SHIFT + 2))
+
+// The following bits define where to take component Z from:
+
+#define D3DVS_Z_X (0 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Y (1 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Z (2 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_W (3 << (D3DVS_SWIZZLE_SHIFT + 4))
+
+// The following bits define where to take component W from:
+
+#define D3DVS_W_X (0 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Y (1 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Z (2 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_W (3 << (D3DVS_SWIZZLE_SHIFT + 6))
+
+// source parameter modifiers
+#define D3DSP_SRCMOD_SHIFT 24
+#define D3DSP_SRCMOD_MASK 0x0F000000
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ENUMS
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE
+{
+ D3DSPSM_NONE = 0<<D3DSP_SRCMOD_SHIFT, // nop
+ D3DSPSM_NEG = 1<<D3DSP_SRCMOD_SHIFT, // negate
+ D3DSPSM_BIAS = 2<<D3DSP_SRCMOD_SHIFT, // bias
+ D3DSPSM_BIASNEG = 3<<D3DSP_SRCMOD_SHIFT, // bias and negate
+ D3DSPSM_SIGN = 4<<D3DSP_SRCMOD_SHIFT, // sign
+ D3DSPSM_SIGNNEG = 5<<D3DSP_SRCMOD_SHIFT, // sign and negate
+ D3DSPSM_COMP = 6<<D3DSP_SRCMOD_SHIFT, // complement
+ D3DSPSM_X2 = 7<<D3DSP_SRCMOD_SHIFT, // *2
+ D3DSPSM_X2NEG = 8<<D3DSP_SRCMOD_SHIFT, // *2 and negate
+ D3DSPSM_DZ = 9<<D3DSP_SRCMOD_SHIFT, // divide through by z component
+ D3DSPSM_DW = 10<<D3DSP_SRCMOD_SHIFT, // divide through by w component
+ D3DSPSM_ABS = 11<<D3DSP_SRCMOD_SHIFT, // abs()
+ D3DSPSM_ABSNEG = 12<<D3DSP_SRCMOD_SHIFT, // -abs()
+ D3DSPSM_NOT = 13<<D3DSP_SRCMOD_SHIFT, // for predicate register: "!p0"
+ D3DSPSM_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_PARAM_SRCMOD_TYPE;
+
+
+typedef enum _D3DSAMPLER_TEXTURE_TYPE
+{
+ D3DSTT_UNKNOWN = 0<<D3DSP_TEXTURETYPE_SHIFT, // uninitialized value
+ D3DSTT_2D = 2<<D3DSP_TEXTURETYPE_SHIFT, // dcl_2d s# (for declaring a 2-D texture)
+ D3DSTT_CUBE = 3<<D3DSP_TEXTURETYPE_SHIFT, // dcl_cube s# (for declaring a cube texture)
+ D3DSTT_VOLUME = 4<<D3DSP_TEXTURETYPE_SHIFT, // dcl_volume s# (for declaring a volume texture)
+ D3DSTT_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSAMPLER_TEXTURE_TYPE;
+
+typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE
+{
+ D3DSIO_NOP = 0,
+ D3DSIO_MOV ,
+ D3DSIO_ADD ,
+ D3DSIO_SUB ,
+ D3DSIO_MAD ,
+ D3DSIO_MUL ,
+ D3DSIO_RCP ,
+ D3DSIO_RSQ ,
+ D3DSIO_DP3 ,
+ D3DSIO_DP4 ,
+ D3DSIO_MIN , //10
+ D3DSIO_MAX ,
+ D3DSIO_SLT ,
+ D3DSIO_SGE ,
+ D3DSIO_EXP ,
+ D3DSIO_LOG ,
+ D3DSIO_LIT ,
+ D3DSIO_DST ,
+ D3DSIO_LRP ,
+ D3DSIO_FRC ,
+ D3DSIO_M4x4 , //20
+ D3DSIO_M4x3 ,
+ D3DSIO_M3x4 ,
+ D3DSIO_M3x3 ,
+ D3DSIO_M3x2 ,
+ D3DSIO_CALL ,
+ D3DSIO_CALLNZ ,
+ D3DSIO_LOOP ,
+ D3DSIO_RET ,
+ D3DSIO_ENDLOOP ,
+ D3DSIO_LABEL , //30
+ D3DSIO_DCL ,
+ D3DSIO_POW ,
+ D3DSIO_CRS ,
+ D3DSIO_SGN ,
+ D3DSIO_ABS ,
+ D3DSIO_NRM ,
+ D3DSIO_SINCOS ,
+ D3DSIO_REP ,
+ D3DSIO_ENDREP ,
+ D3DSIO_IF , //40
+ D3DSIO_IFC ,
+ D3DSIO_ELSE ,
+ D3DSIO_ENDIF ,
+ D3DSIO_BREAK ,
+ D3DSIO_BREAKC ,
+ D3DSIO_MOVA ,
+ D3DSIO_DEFB ,
+ D3DSIO_DEFI ,
+
+ D3DSIO_TEXCOORD = 64,
+ D3DSIO_TEXKILL ,
+ D3DSIO_TEX ,
+ D3DSIO_TEXBEM ,
+ D3DSIO_TEXBEML ,
+ D3DSIO_TEXREG2AR ,
+ D3DSIO_TEXREG2GB ,
+ D3DSIO_TEXM3x2PAD ,
+ D3DSIO_TEXM3x2TEX ,
+ D3DSIO_TEXM3x3PAD ,
+ D3DSIO_TEXM3x3TEX ,
+ D3DSIO_RESERVED0 ,
+ D3DSIO_TEXM3x3SPEC ,
+ D3DSIO_TEXM3x3VSPEC ,
+ D3DSIO_EXPP ,
+ D3DSIO_LOGP ,
+ D3DSIO_CND ,
+ D3DSIO_DEF ,
+ D3DSIO_TEXREG2RGB ,
+ D3DSIO_TEXDP3TEX ,
+ D3DSIO_TEXM3x2DEPTH ,
+ D3DSIO_TEXDP3 ,
+ D3DSIO_TEXM3x3 ,
+ D3DSIO_TEXDEPTH ,
+ D3DSIO_CMP ,
+ D3DSIO_BEM ,
+ D3DSIO_DP2ADD ,
+ D3DSIO_DSX ,
+ D3DSIO_DSY ,
+ D3DSIO_TEXLDD ,
+ D3DSIO_SETP ,
+ D3DSIO_TEXLDL ,
+ D3DSIO_BREAKP ,
+
+ D3DSIO_PHASE = 0xFFFD,
+ D3DSIO_COMMENT = 0xFFFE,
+ D3DSIO_END = 0xFFFF,
+
+ D3DSIO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+typedef enum _D3DVS_RASTOUT_OFFSETS
+{
+ D3DSRO_POSITION = 0,
+ D3DSRO_FOG,
+ D3DSRO_POINT_SIZE,
+ D3DSRO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DVS_RASTOUT_OFFSETS;
+
+/* SwapEffects */
+typedef enum _D3DSWAPEFFECT
+{
+ D3DSWAPEFFECT_DISCARD = 1,
+ D3DSWAPEFFECT_COPY = 3,
+
+ D3DSWAPEFFECT_FORCE_DWORD = 0x7fffffff
+} D3DSWAPEFFECT;
+
+typedef enum _D3DRESOURCETYPE
+{
+ D3DRTYPE_SURFACE = 1,
+ D3DRTYPE_TEXTURE = 3,
+ D3DRTYPE_VOLUMETEXTURE = 4,
+ D3DRTYPE_CUBETEXTURE = 5,
+ D3DRTYPE_VERTEXBUFFER = 6,
+ D3DRTYPE_INDEXBUFFER = 7,
+
+ D3DRTYPE_FORCE_DWORD = 0x7fffffff
+} D3DRESOURCETYPE;
+
+typedef enum _D3DDEVTYPE
+{
+ D3DDEVTYPE_HAL = 1,
+ D3DDEVTYPE_REF = 2,
+
+ D3DDEVTYPE_NULLREF = 4,
+
+ D3DDEVTYPE_FORCE_DWORD = 0x7fffffff
+} D3DDEVTYPE;
+
+typedef enum _D3DSTENCILOP
+{
+ D3DSTENCILOP_KEEP = 1,
+ D3DSTENCILOP_ZERO = 2,
+ D3DSTENCILOP_REPLACE = 3,
+ D3DSTENCILOP_INCRSAT = 4,
+ D3DSTENCILOP_DECRSAT = 5,
+ D3DSTENCILOP_INVERT = 6,
+ D3DSTENCILOP_INCR = 7,
+ D3DSTENCILOP_DECR = 8,
+ D3DSTENCILOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSTENCILOP;
+
+typedef enum _D3DPATCHEDGESTYLE
+{
+ D3DPATCHEDGE_DISCRETE = 0,
+ D3DPATCHEDGE_CONTINUOUS = 1,
+ D3DPATCHEDGE_FORCE_DWORD = 0x7fffffff,
+} D3DPATCHEDGESTYLE;
+
+
+/* Debug monitor tokens (DEBUG only)
+
+ Note that if D3DRS_DEBUGMONITORTOKEN is set, the call is treated as
+ passing a token to the debug monitor. For example, if, after passing
+ D3DDMT_ENABLE/DISABLE to D3DRS_DEBUGMONITORTOKEN other token values
+ are passed in, the enabled/disabled state of the debug
+ monitor will still persist.
+
+ The debug monitor defaults to enabled.
+
+ Calling GetRenderState on D3DRS_DEBUGMONITORTOKEN is not of any use.
+*/
+typedef enum _D3DDEBUGMONITORTOKENS
+{
+ D3DDMT_ENABLE = 0, // enable debug monitor
+} D3DDEBUGMONITORTOKENS;
+
+typedef enum _D3DDEGREETYPE
+{
+ D3DDEGREE_LINEAR = 1,
+ D3DDEGREE_QUADRATIC = 2,
+ D3DDEGREE_CUBIC = 3,
+ D3DDEGREE_FORCE_DWORD = 0x7fffffff,
+} D3DDEGREETYPE;
+
+typedef enum _D3DBLENDOP
+{
+ D3DBLENDOP_ADD = 1,
+ D3DBLENDOP_SUBTRACT = 2,
+ D3DBLENDOP_REVSUBTRACT = 3,
+ D3DBLENDOP_MIN = 4,
+ D3DBLENDOP_MAX = 5,
+ D3DBLENDOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DBLENDOP;
+
+typedef enum _D3DMULTISAMPLE_TYPE
+{
+ D3DMULTISAMPLE_NONE = 0,
+ D3DMULTISAMPLE_NONMASKABLE = 1,
+ D3DMULTISAMPLE_2_SAMPLES = 2,
+ D3DMULTISAMPLE_3_SAMPLES = 3,
+ D3DMULTISAMPLE_4_SAMPLES = 4,
+ D3DMULTISAMPLE_5_SAMPLES = 5,
+ D3DMULTISAMPLE_6_SAMPLES = 6,
+ D3DMULTISAMPLE_7_SAMPLES = 7,
+ D3DMULTISAMPLE_8_SAMPLES = 8,
+ D3DMULTISAMPLE_9_SAMPLES = 9,
+ D3DMULTISAMPLE_10_SAMPLES = 10,
+ D3DMULTISAMPLE_11_SAMPLES = 11,
+ D3DMULTISAMPLE_12_SAMPLES = 12,
+ D3DMULTISAMPLE_13_SAMPLES = 13,
+ D3DMULTISAMPLE_14_SAMPLES = 14,
+ D3DMULTISAMPLE_15_SAMPLES = 15,
+ D3DMULTISAMPLE_16_SAMPLES = 16,
+
+ D3DMULTISAMPLE_FORCE_DWORD = 0x7fffffff
+} D3DMULTISAMPLE_TYPE;
+
+/* Pool types */
+typedef enum _D3DPOOL
+{
+ D3DPOOL_DEFAULT = 0,
+ D3DPOOL_MANAGED = 1,
+ D3DPOOL_SYSTEMMEM = 2,
+ D3DPOOL_SCRATCH = 3,
+
+ D3DPOOL_FORCE_DWORD = 0x7fffffff
+} D3DPOOL;
+
+typedef enum _D3DQUERYTYPE
+{
+ D3DQUERYTYPE_RESOURCEMANAGER = 5, /* D3DISSUE_END */
+ D3DQUERYTYPE_EVENT = 8, /* D3DISSUE_END */
+ D3DQUERYTYPE_OCCLUSION = 9, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_TIMESTAMP = 10, /* D3DISSUE_END */
+ D3DQUERYTYPE_TIMESTAMPFREQ = 12, /* D3DISSUE_END */
+ D3DQUERYTYPE_INTERFACETIMINGS = 14, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_PIXELTIMINGS = 16, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_CACHEUTILIZATION = 18, /* D3DISSUE_BEGIN, D3DISSUE_END */
+} D3DQUERYTYPE;
+
+typedef enum _D3DRENDERSTATETYPE
+{
+ D3DRS_ZENABLE = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */
+ D3DRS_FILLMODE = 8, /* D3DFILLMODE */
+ D3DRS_SHADEMODE = 9, /* D3DSHADEMODE */
+ D3DRS_ZWRITEENABLE = 14, /* TRUE to enable z writes */
+ D3DRS_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */
+ D3DRS_LASTPIXEL = 16, /* TRUE for last-pixel on lines */
+ D3DRS_SRCBLEND = 19, /* D3DBLEND */
+ D3DRS_DESTBLEND = 20, /* D3DBLEND */
+ D3DRS_CULLMODE = 22, /* D3DCULL */
+ D3DRS_ZFUNC = 23, /* D3DCMPFUNC */
+ D3DRS_ALPHAREF = 24, /* D3DFIXED */
+ D3DRS_ALPHAFUNC = 25, /* D3DCMPFUNC */
+ D3DRS_DITHERENABLE = 26, /* TRUE to enable dithering */
+ D3DRS_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */
+ D3DRS_FOGENABLE = 28, /* TRUE to enable fog blending */
+ D3DRS_SPECULARENABLE = 29, /* TRUE to enable specular */
+ D3DRS_FOGCOLOR = 34, /* D3DCOLOR */
+ D3DRS_FOGTABLEMODE = 35, /* D3DFOGMODE */
+ D3DRS_FOGSTART = 36, /* Fog start (for both vertex and pixel fog) */
+ D3DRS_FOGEND = 37, /* Fog end */
+ D3DRS_FOGDENSITY = 38, /* Fog density */
+ D3DRS_RANGEFOGENABLE = 48, /* Enables range-based fog */
+ D3DRS_STENCILENABLE = 52, /* BOOL enable/disable stenciling */
+ D3DRS_STENCILFAIL = 53, /* D3DSTENCILOP to do if stencil test fails */
+ D3DRS_STENCILZFAIL = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */
+ D3DRS_STENCILPASS = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */
+ D3DRS_STENCILFUNC = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */
+ D3DRS_STENCILREF = 57, /* Reference value used in stencil test */
+ D3DRS_STENCILMASK = 58, /* Mask value used in stencil test */
+ D3DRS_STENCILWRITEMASK = 59, /* Write mask applied to values written to stencil buffer */
+ D3DRS_TEXTUREFACTOR = 60, /* D3DCOLOR used for multi-texture blend */
+ D3DRS_WRAP0 = 128, /* wrap for 1st texture coord. set */
+ D3DRS_WRAP1 = 129, /* wrap for 2nd texture coord. set */
+ D3DRS_WRAP2 = 130, /* wrap for 3rd texture coord. set */
+ D3DRS_WRAP3 = 131, /* wrap for 4th texture coord. set */
+ D3DRS_WRAP4 = 132, /* wrap for 5th texture coord. set */
+ D3DRS_WRAP5 = 133, /* wrap for 6th texture coord. set */
+ D3DRS_WRAP6 = 134, /* wrap for 7th texture coord. set */
+ D3DRS_WRAP7 = 135, /* wrap for 8th texture coord. set */
+ D3DRS_CLIPPING = 136,
+ D3DRS_LIGHTING = 137,
+ D3DRS_AMBIENT = 139,
+ D3DRS_FOGVERTEXMODE = 140,
+ D3DRS_COLORVERTEX = 141,
+ D3DRS_LOCALVIEWER = 142,
+ D3DRS_NORMALIZENORMALS = 143,
+ D3DRS_DIFFUSEMATERIALSOURCE = 145,
+ D3DRS_SPECULARMATERIALSOURCE = 146,
+ D3DRS_AMBIENTMATERIALSOURCE = 147,
+ D3DRS_EMISSIVEMATERIALSOURCE = 148,
+ D3DRS_VERTEXBLEND = 151,
+ D3DRS_CLIPPLANEENABLE = 152,
+ D3DRS_POINTSIZE = 154, /* float point size */
+ D3DRS_POINTSIZE_MIN = 155, /* float point size min threshold */
+ D3DRS_POINTSPRITEENABLE = 156, /* BOOL point texture coord control */
+ D3DRS_POINTSCALEENABLE = 157, /* BOOL point size scale enable */
+ D3DRS_POINTSCALE_A = 158, /* float point attenuation A value */
+ D3DRS_POINTSCALE_B = 159, /* float point attenuation B value */
+ D3DRS_POINTSCALE_C = 160, /* float point attenuation C value */
+ D3DRS_MULTISAMPLEANTIALIAS = 161, // BOOL - set to do FSAA with multisample buffer
+ D3DRS_MULTISAMPLEMASK = 162, // DWORD - per-sample enable/disable
+ D3DRS_PATCHEDGESTYLE = 163, // Sets whether patch edges will use float style tessellation
+ D3DRS_DEBUGMONITORTOKEN = 165, // DEBUG ONLY - token to debug monitor
+ D3DRS_POINTSIZE_MAX = 166, /* float point size max threshold */
+ D3DRS_INDEXEDVERTEXBLENDENABLE = 167,
+ D3DRS_COLORWRITEENABLE = 168, // per-channel write enable
+ D3DRS_TWEENFACTOR = 170, // float tween factor
+ D3DRS_BLENDOP = 171, // D3DBLENDOP setting
+ D3DRS_POSITIONDEGREE = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default)
+ D3DRS_NORMALDEGREE = 173, // NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC
+ D3DRS_SCISSORTESTENABLE = 174,
+ D3DRS_SLOPESCALEDEPTHBIAS = 175,
+ D3DRS_ANTIALIASEDLINEENABLE = 176,
+ D3DRS_MINTESSELLATIONLEVEL = 178,
+ D3DRS_MAXTESSELLATIONLEVEL = 179,
+ D3DRS_ADAPTIVETESS_X = 180,
+ D3DRS_ADAPTIVETESS_Y = 181,
+ D3DRS_ADAPTIVETESS_Z = 182,
+ D3DRS_ADAPTIVETESS_W = 183,
+ D3DRS_ENABLEADAPTIVETESSELLATION = 184,
+ D3DRS_TWOSIDEDSTENCILMODE = 185, /* BOOL enable/disable 2 sided stenciling */
+ D3DRS_CCW_STENCILFAIL = 186, /* D3DSTENCILOP to do if ccw stencil test fails */
+ D3DRS_CCW_STENCILZFAIL = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */
+ D3DRS_CCW_STENCILPASS = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */
+ D3DRS_CCW_STENCILFUNC = 189, /* D3DCMPFUNC fn. ccw Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */
+ D3DRS_COLORWRITEENABLE1 = 190, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_COLORWRITEENABLE2 = 191, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_COLORWRITEENABLE3 = 192, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_BLENDFACTOR = 193, /* D3DCOLOR used for a constant blend factor during alpha blending for devices that support D3DPBLENDCAPS_BLENDFACTOR */
+ D3DRS_SRGBWRITEENABLE = 194, /* Enable rendertarget writes to be DE-linearized to SRGB (for formats that expose D3DUSAGE_QUERY_SRGBWRITE) */
+ D3DRS_DEPTHBIAS = 195,
+ D3DRS_WRAP8 = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */
+ D3DRS_WRAP9 = 199,
+ D3DRS_WRAP10 = 200,
+ D3DRS_WRAP11 = 201,
+ D3DRS_WRAP12 = 202,
+ D3DRS_WRAP13 = 203,
+ D3DRS_WRAP14 = 204,
+ D3DRS_WRAP15 = 205,
+ D3DRS_SEPARATEALPHABLENDENABLE = 206, /* TRUE to enable a separate blending function for the alpha channel */
+ D3DRS_SRCBLENDALPHA = 207, /* SRC blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+ D3DRS_DESTBLENDALPHA = 208, /* DST blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+ D3DRS_BLENDOPALPHA = 209, /* Blending operation for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+
+
+ D3DRS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DRENDERSTATETYPE;
+
+typedef enum _D3DCULL
+{
+ D3DCULL_NONE = 1,
+ D3DCULL_CW = 2,
+ D3DCULL_CCW = 3,
+ D3DCULL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DCULL;
+
+typedef enum _D3DTEXTUREFILTERTYPE
+{
+ D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only)
+ D3DTEXF_POINT = 1, // nearest
+ D3DTEXF_LINEAR = 2, // linear interpolation
+ D3DTEXF_ANISOTROPIC = 3, // anisotropic
+ D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DTEXTUREFILTERTYPE;
+
+typedef enum _D3DBACKBUFFER_TYPE
+{
+ D3DBACKBUFFER_TYPE_MONO = 0,
+
+ D3DBACKBUFFER_TYPE_FORCE_DWORD = 0x7fffffff
+} D3DBACKBUFFER_TYPE;
+
+#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)
+#define D3DTS_WORLD D3DTS_WORLDMATRIX(0)
+#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1)
+#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2)
+#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3)
+
+typedef enum _D3DCMPFUNC
+{
+ D3DCMP_NEVER = 1,
+ D3DCMP_LESS = 2,
+ D3DCMP_EQUAL = 3,
+ D3DCMP_LESSEQUAL = 4,
+ D3DCMP_GREATER = 5,
+ D3DCMP_NOTEQUAL = 6,
+ D3DCMP_GREATEREQUAL = 7,
+ D3DCMP_ALWAYS = 8,
+ D3DCMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DCMPFUNC;
+
+typedef enum _D3DZBUFFERTYPE
+{
+ D3DZB_FALSE = 0,
+ D3DZB_TRUE = 1, // Z buffering
+ D3DZB_USEW = 2, // W buffering
+ D3DZB_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DZBUFFERTYPE;
+
+typedef enum _D3DFILLMODE
+{
+ D3DFILL_POINT = 1,
+ D3DFILL_WIREFRAME = 2,
+ D3DFILL_SOLID = 3,
+ D3DFILL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DFILLMODE;
+
+typedef enum _D3DBLEND
+{
+ D3DBLEND_ZERO = 1,
+ D3DBLEND_ONE = 2,
+ D3DBLEND_SRCCOLOR = 3,
+ D3DBLEND_INVSRCCOLOR = 4,
+ D3DBLEND_SRCALPHA = 5,
+ D3DBLEND_INVSRCALPHA = 6,
+ D3DBLEND_DESTALPHA = 7,
+ D3DBLEND_INVDESTALPHA = 8,
+ D3DBLEND_DESTCOLOR = 9,
+ D3DBLEND_INVDESTCOLOR = 10,
+ D3DBLEND_SRCALPHASAT = 11,
+ D3DBLEND_BOTHSRCALPHA = 12,
+ D3DBLEND_BOTHINVSRCALPHA = 13,
+ D3DBLEND_BLENDFACTOR = 14, /* Only supported if D3DPBLENDCAPS_BLENDFACTOR is on */
+ D3DBLEND_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DBLEND;
+
+// Values for material source
+typedef enum _D3DMATERIALCOLORSOURCE
+{
+ D3DMCS_MATERIAL = 0, // Color from material is used
+ D3DMCS_COLOR1 = 1, // Diffuse vertex color is used
+ D3DMCS_COLOR2 = 2, // Specular vertex color is used
+ D3DMCS_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DMATERIALCOLORSOURCE;
+
+typedef enum _D3DCUBEMAP_FACES
+{
+ D3DCUBEMAP_FACE_POSITIVE_Z = 4,
+
+ D3DCUBEMAP_FACE_FORCE_DWORD = 0x7fffffff
+} D3DCUBEMAP_FACES;
+
+typedef enum _D3DTEXTURETRANSFORMFLAGS
+{
+ D3DTTFF_DISABLE = 0, // texture coordinates are passed directly
+ D3DTTFF_COUNT3 = 3, // rasterizer should expect 3-D texture coords
+ D3DTTFF_PROJECTED = 256, // texcoords to be divided by COUNTth element
+ D3DTTFF_FORCE_DWORD = 0x7fffffff,
+} D3DTEXTURETRANSFORMFLAGS;
+
+typedef enum _D3DTEXTUREADDRESS
+{
+ D3DTADDRESS_WRAP = 0,
+ D3DTADDRESS_CLAMP = 1,
+ D3DTADDRESS_BORDER = 2,
+ D3DTADDRESS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTEXTUREADDRESS;
+
+typedef enum _D3DSHADEMODE
+{
+ D3DSHADE_FLAT = 1,
+ D3DSHADE_GOURAUD = 2,
+ D3DSHADE_PHONG = 3,
+ D3DSHADE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSHADEMODE;
+
+typedef enum _D3DFOGMODE
+{
+ D3DFOG_NONE = 0,
+ D3DFOG_LINEAR = 3,
+ D3DFOG_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DFOGMODE;
+
+typedef struct _D3DRECT
+{
+ LONG x1;
+ LONG y1;
+ LONG x2;
+ LONG y2;
+} D3DRECT;
+
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE
+{
+ D3DSPR_TEMP = 0, // Temporary Register File
+ D3DSPR_INPUT = 1, // Input Register File
+ D3DSPR_CONST = 2, // Constant Register File
+ D3DSPR_ADDR = 3, // Address Register (VS)
+ D3DSPR_TEXTURE = 3, // Texture Register File (PS)
+ D3DSPR_RASTOUT = 4, // Rasterizer Register File
+ D3DSPR_ATTROUT = 5, // Attribute Output Register File
+ D3DSPR_TEXCRDOUT = 6, // Texture Coordinate Output Register File
+ D3DSPR_OUTPUT = 6, // Output register file for VS3.0+
+ D3DSPR_CONSTINT = 7, // Constant Integer Vector Register File
+ D3DSPR_COLOROUT = 8, // Color Output Register File
+ D3DSPR_DEPTHOUT = 9, // Depth Output Register File
+ D3DSPR_SAMPLER = 10, // Sampler State Register File
+ D3DSPR_CONST2 = 11, // Constant Register File 2048 - 4095
+ D3DSPR_CONST3 = 12, // Constant Register File 4096 - 6143
+ D3DSPR_CONST4 = 13, // Constant Register File 6144 - 8191
+ D3DSPR_CONSTBOOL = 14, // Constant Boolean register file
+ D3DSPR_LOOP = 15, // Loop counter register file
+ D3DSPR_TEMPFLOAT16 = 16, // 16-bit float temp register file
+ D3DSPR_MISCTYPE = 17, // Miscellaneous (single) registers.
+ D3DSPR_LABEL = 18, // Label
+ D3DSPR_PREDICATE = 19, // Predicate register
+ D3DSPR_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_PARAM_REGISTER_TYPE;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
+#endif
+
+typedef struct _D3DMATRIX
+{
+ union
+ {
+ struct
+ {
+ float _11, _12, _13, _14;
+ float _21, _22, _23, _24;
+ float _31, _32, _33, _34;
+ float _41, _42, _43, _44;
+ };
+ float m[4][4];
+ };
+} D3DMATRIX;
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+typedef struct _D3DVERTEXBUFFER_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+ UINT Size;
+
+ DWORD FVF;
+
+} D3DVERTEXBUFFER_DESC;
+
+class TOGL_CLASS D3DXMATRIX : public D3DMATRIX
+{
+public:
+ D3DXMATRIX operator*( const D3DXMATRIX &o ) const;
+ operator FLOAT* ();
+ float& operator()( int row, int column );
+ const float& operator()( int row, int column ) const;
+};
+
+typedef DWORD D3DCOLOR;
+
+typedef enum _D3DSAMPLERSTATETYPE
+{
+ D3DSAMP_ADDRESSU = 1, /* D3DTEXTUREADDRESS for U coordinate */
+ D3DSAMP_ADDRESSV = 2, /* D3DTEXTUREADDRESS for V coordinate */
+ D3DSAMP_ADDRESSW = 3, /* D3DTEXTUREADDRESS for W coordinate */
+ D3DSAMP_BORDERCOLOR = 4, /* D3DCOLOR */
+ D3DSAMP_MAGFILTER = 5, /* D3DTEXTUREFILTER filter to use for magnification */
+ D3DSAMP_MINFILTER = 6, /* D3DTEXTUREFILTER filter to use for minification */
+ D3DSAMP_MIPFILTER = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */
+ D3DSAMP_MIPMAPLODBIAS = 8, /* float Mipmap LOD bias */
+ D3DSAMP_MAXMIPLEVEL = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */
+ D3DSAMP_MAXANISOTROPY = 10, /* DWORD maximum anisotropy */
+ D3DSAMP_SRGBTEXTURE = 11, /* Default = 0 (which means Gamma 1.0,
+ no correction required.) else correct for
+ Gamma = 2.2 */
+ D3DSAMP_SHADOWFILTER = 12, /* Tells the sampler that it should be doing shadow compares */
+ D3DSAMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSAMPLERSTATETYPE;
+
+typedef enum _D3DDECLTYPE
+{
+ D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
+ D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
+ D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
+ D3DDECLTYPE_FLOAT4 = 3, // 4D float
+ D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
+ // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
+ D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
+ D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
+ D3DDECLTYPE_SHORT4 = 7, // 4D signed short
+
+// The following types are valid only with vertex shaders >= 2.0
+
+
+ D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
+ D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
+ D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
+ D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
+ D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
+ D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
+ D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
+ D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
+ D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
+ D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
+} D3DDECLTYPE;
+
+typedef enum _D3DDECLMETHOD
+{
+ D3DDECLMETHOD_DEFAULT = 0,
+ D3DDECLMETHOD_PARTIALU,
+ D3DDECLMETHOD_PARTIALV,
+ D3DDECLMETHOD_CROSSUV, // Normal
+ D3DDECLMETHOD_UV,
+ D3DDECLMETHOD_LOOKUP, // Lookup a displacement map
+ D3DDECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map
+} D3DDECLMETHOD;
+
+typedef enum _D3DDECLUSAGE
+{
+ D3DDECLUSAGE_POSITION = 0,
+ D3DDECLUSAGE_BLENDWEIGHT = 1,
+ D3DDECLUSAGE_BLENDINDICES = 2,
+ D3DDECLUSAGE_NORMAL = 3,
+ D3DDECLUSAGE_PSIZE = 4,
+ D3DDECLUSAGE_TEXCOORD = 5,
+ D3DDECLUSAGE_TANGENT = 6,
+ D3DDECLUSAGE_BINORMAL = 7,
+ D3DDECLUSAGE_TESSFACTOR = 8,
+ D3DDECLUSAGE_PLUGH = 9, // mystery value
+ D3DDECLUSAGE_COLOR = 10,
+ D3DDECLUSAGE_FOG = 11,
+ D3DDECLUSAGE_DEPTH = 12,
+ D3DDECLUSAGE_SAMPLE = 13,
+} D3DDECLUSAGE;
+
+typedef enum _D3DPRIMITIVETYPE
+{
+ D3DPT_POINTLIST = 1,
+ D3DPT_LINELIST = 2,
+ D3DPT_TRIANGLELIST = 4,
+ D3DPT_TRIANGLESTRIP = 5,
+ D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DPRIMITIVETYPE;
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// STRUCTURES
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+typedef struct TOGL_CLASS D3DXPLANE
+{
+ float& operator[]( int i );
+ bool operator==( const D3DXPLANE &o );
+ bool operator!=( const D3DXPLANE &o );
+ operator float*();
+ operator const float*() const;
+
+ float a, b, c, d;
+} D3DXPLANE;
+
+typedef enum _D3DVERTEXBLENDFLAGS
+{
+ D3DVBF_DISABLE = 0, // Disable vertex blending
+ D3DVBF_1WEIGHTS = 1, // 2 matrix blending
+ D3DVBF_2WEIGHTS = 2, // 3 matrix blending
+ D3DVBF_3WEIGHTS = 3, // 4 matrix blending
+ D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR
+ D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0
+ D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DVERTEXBLENDFLAGS;
+
+typedef struct _D3DINDEXBUFFER_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+ UINT Size;
+} D3DINDEXBUFFER_DESC;
+
+typedef struct _D3DVERTEXELEMENT9
+{
+ WORD Stream; // Stream index
+ WORD Offset; // Offset in the stream in bytes
+ BYTE Type; // Data type
+ BYTE Method; // Processing method
+ BYTE Usage; // Semantics
+ BYTE UsageIndex; // Semantic index
+} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;
+
+
+#define MAX_DEVICE_IDENTIFIER_STRING 512
+typedef struct _D3DADAPTER_IDENTIFIER9
+{
+ char Driver[MAX_DEVICE_IDENTIFIER_STRING];
+ char Description[MAX_DEVICE_IDENTIFIER_STRING];
+ char DeviceName[32]; /* Device name for GDI (ex. \\.\DISPLAY1) */
+
+ LARGE_INTEGER DriverVersion; /* Defined for 32 bit components */
+
+ DWORD VendorId;
+ DWORD DeviceId;
+ DWORD SubSysId;
+ DWORD Revision;
+ DWORD VideoMemory;
+
+} D3DADAPTER_IDENTIFIER9;
+
+typedef struct _D3DCOLORVALUE
+{
+ float r;
+ float g;
+ float b;
+ float a;
+} D3DCOLORVALUE;
+
+typedef struct _D3DMATERIAL9
+{
+ D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */
+ D3DCOLORVALUE Ambient; /* Ambient color RGB */
+ D3DCOLORVALUE Specular; /* Specular 'shininess' */
+ D3DCOLORVALUE Emissive; /* Emissive color RGB */
+ float Power; /* Sharpness if specular highlight */
+} D3DMATERIAL9;
+
+typedef struct _D3DVOLUME_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+
+ UINT Width;
+ UINT Height;
+ UINT Depth;
+} D3DVOLUME_DESC;
+
+typedef struct _D3DVIEWPORT9
+{
+ DWORD X;
+ DWORD Y; /* Viewport Top left */
+ DWORD Width;
+ DWORD Height; /* Viewport Dimensions */
+ float MinZ; /* Min/max of clip Volume */
+ float MaxZ;
+} D3DVIEWPORT9;
+
+typedef struct _D3DPSHADERCAPS2_0
+{
+ DWORD Caps;
+ INT DynamicFlowControlDepth;
+ INT NumTemps;
+ INT StaticFlowControlDepth;
+ INT NumInstructionSlots;
+} D3DPSHADERCAPS2_0;
+
+typedef struct _D3DCAPS9
+{
+ /* Device Info */
+ D3DDEVTYPE DeviceType;
+
+ /* Caps from DX7 Draw */
+ DWORD Caps;
+ DWORD Caps2;
+
+ /* Cursor Caps */
+ DWORD CursorCaps;
+
+ /* 3D Device Caps */
+ DWORD DevCaps;
+
+ DWORD PrimitiveMiscCaps;
+ DWORD RasterCaps;
+ DWORD TextureCaps;
+ DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's
+
+ DWORD MaxTextureWidth, MaxTextureHeight;
+ DWORD MaxVolumeExtent;
+
+ DWORD MaxTextureAspectRatio;
+ DWORD MaxAnisotropy;
+
+ DWORD TextureOpCaps;
+ DWORD MaxTextureBlendStages;
+ DWORD MaxSimultaneousTextures;
+
+ DWORD VertexProcessingCaps;
+ DWORD MaxActiveLights;
+ DWORD MaxUserClipPlanes;
+ DWORD MaxVertexBlendMatrices;
+ DWORD MaxVertexBlendMatrixIndex;
+
+ DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call
+ DWORD MaxStreams;
+
+ DWORD VertexShaderVersion;
+ DWORD MaxVertexShaderConst; // number of vertex shader constant registers
+
+ DWORD PixelShaderVersion;
+
+ // Here are the DX9 specific ones
+ DWORD DevCaps2;
+ D3DPSHADERCAPS2_0 PS20Caps;
+
+ DWORD NumSimultaneousRTs; // Will be at least 1
+ DWORD MaxVertexShader30InstructionSlots;
+ DWORD MaxPixelShader30InstructionSlots;
+
+ // only on Posix/GL
+ DWORD FakeSRGBWrite; // 1 for parts which can't support SRGB writes due to driver issues - 0 for others
+ DWORD MixedSizeTargets; // 1 for parts which can mix attachment sizes (RT's color vs depth)
+ DWORD CanDoSRGBReadFromRTs; // 0 when we're on Leopard, 1 when on Snow Leopard
+} D3DCAPS9;
+
+typedef struct _D3DDISPLAYMODE
+{
+ UINT Width;
+ UINT Height;
+ UINT RefreshRate;
+ D3DFORMAT Format;
+} D3DDISPLAYMODE;
+
+typedef struct _D3DGAMMARAMP
+{
+ WORD red [256];
+ WORD green[256];
+ WORD blue [256];
+} D3DGAMMARAMP;
+
+
+/* Resize Optional Parameters */
+typedef struct _D3DPRESENT_PARAMETERS_
+{
+ UINT BackBufferWidth;
+ UINT BackBufferHeight;
+ D3DFORMAT BackBufferFormat;
+ UINT BackBufferCount;
+
+ D3DMULTISAMPLE_TYPE MultiSampleType;
+ DWORD MultiSampleQuality;
+
+ D3DSWAPEFFECT SwapEffect;
+ VD3DHWND hDeviceWindow;
+ BOOL Windowed;
+ BOOL EnableAutoDepthStencil;
+ D3DFORMAT AutoDepthStencilFormat;
+ DWORD Flags;
+
+ /* FullScreen_RefreshRateInHz must be zero for Windowed mode */
+ UINT FullScreen_RefreshRateInHz;
+ UINT PresentationInterval;
+} D3DPRESENT_PARAMETERS;
+
+typedef struct _D3DDEVICE_CREATION_PARAMETERS
+{
+ UINT AdapterOrdinal;
+ D3DDEVTYPE DeviceType;
+ VD3DHWND hFocusWindow;
+ DWORD BehaviorFlags;
+} D3DDEVICE_CREATION_PARAMETERS;
+
+/* Structures for LockBox */
+typedef struct _D3DBOX
+{
+ UINT Left;
+ UINT Top;
+ UINT Right;
+ UINT Bottom;
+ UINT Front;
+ UINT Back;
+} D3DBOX;
+
+typedef struct _D3DLOCKED_BOX
+{
+ INT RowPitch;
+ INT SlicePitch;
+ void* pBits;
+} D3DLOCKED_BOX;
+
+typedef struct _D3DSURFACE_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+
+ D3DMULTISAMPLE_TYPE MultiSampleType;
+ DWORD MultiSampleQuality;
+ UINT Width;
+ UINT Height;
+} D3DSURFACE_DESC;
+
+
+typedef struct _D3DLOCKED_RECT
+{
+ INT Pitch;
+ void* pBits;
+} D3DLOCKED_RECT;
+
+
+typedef struct _D3DRASTER_STATUS
+{
+ BOOL InVBlank;
+ UINT ScanLine;
+} D3DRASTER_STATUS;
+
+typedef enum _D3DLIGHTTYPE
+{
+ D3DLIGHT_POINT = 1,
+ D3DLIGHT_SPOT = 2,
+ D3DLIGHT_DIRECTIONAL = 3,
+ D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DLIGHTTYPE;
+
+typedef struct TOGL_CLASS _D3DVECTOR
+{
+ float x;
+ float y;
+ float z;
+} D3DVECTOR;
+
+class TOGL_CLASS D3DXVECTOR2
+{
+public:
+ operator FLOAT* ();
+ operator CONST FLOAT* () const;
+
+ float x,y;
+};
+
+class TOGL_CLASS D3DXVECTOR3 : public D3DVECTOR
+{
+public:
+ D3DXVECTOR3() {}
+ D3DXVECTOR3( float a, float b, float c );
+ operator FLOAT* ();
+ operator CONST FLOAT* () const;
+};
+
+typedef enum _D3DXINCLUDE_TYPE
+{
+ D3DXINC_LOCAL,
+
+ // force 32-bit size enum
+ D3DXINC_FORCE_DWORD = 0x7fffffff
+
+} D3DXINCLUDE_TYPE;
+
+typedef struct _D3DLIGHT9
+{
+ D3DLIGHTTYPE Type; /* Type of light source */
+ D3DCOLORVALUE Diffuse; /* Diffuse color of light */
+ D3DCOLORVALUE Specular; /* Specular color of light */
+ D3DCOLORVALUE Ambient; /* Ambient color of light */
+ D3DVECTOR Position; /* Position in world space */
+ D3DVECTOR Direction; /* Direction in world space */
+ float Range; /* Cutoff range */
+ float Falloff; /* Falloff */
+ float Attenuation0; /* Constant attenuation */
+ float Attenuation1; /* Linear attenuation */
+ float Attenuation2; /* Quadratic attenuation */
+ float Theta; /* Inner angle of spotlight cone */
+ float Phi; /* Outer angle of spotlight cone */
+} D3DLIGHT9;
+
+class TOGL_CLASS D3DXVECTOR4
+{
+public:
+ D3DXVECTOR4() {}
+ D3DXVECTOR4( float a, float b, float c, float d );
+
+ float x,y,z,w;
+};
+
+//----------------------------------------------------------------------------
+// D3DXMACRO:
+// ----------
+// Preprocessor macro definition. The application pass in a NULL-terminated
+// array of this structure to various D3DX APIs. This enables the application
+// to #define tokens at runtime, before the file is parsed.
+//----------------------------------------------------------------------------
+
+typedef struct _D3DXMACRO
+{
+ LPCSTR Name;
+ LPCSTR Definition;
+
+} D3DXMACRO, *LPD3DXMACRO;
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+//
+// Also look for any functions marked with "**** FIXED FUNCTION STUFF"
+//
+// It's only laying around here so we don't have to chop up the shader system a lot to strip out the fixed function code paths.
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTRANSFORMSTATETYPE
+{
+ D3DTS_VIEW = 2,
+ D3DTS_PROJECTION = 3,
+ D3DTS_TEXTURE0 = 16,
+ D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTRANSFORMSTATETYPE;
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTEXTUREOP
+{
+ // Control
+ D3DTOP_DISABLE = 1, // disables stage
+ D3DTOP_SELECTARG1 = 2, // the default
+ D3DTOP_SELECTARG2 = 3,
+
+ // Modulate
+ D3DTOP_MODULATE = 4, // multiply args together
+ D3DTOP_MODULATE2X = 5, // multiply and 1 bit
+ D3DTOP_MODULATE4X = 6, // multiply and 2 bits
+
+ // Add
+ D3DTOP_ADD = 7, // add arguments together
+ D3DTOP_ADDSIGNED = 8, // add with -0.5 bias
+ D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit
+ D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation
+ D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product
+ // Arg1 + Arg2 - Arg1*Arg2
+ // = Arg1 + (1-Arg1)*Arg2
+
+ // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha)
+ D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha
+ D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha
+ D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR
+
+ // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha)
+ D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha
+ D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color
+
+ // Specular mapping
+ D3DTOP_PREMODULATE = 17, // modulate with next texture before use
+ D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB
+ // COLOROP only
+ D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A
+ // COLOROP only
+ D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB
+ // COLOROP only
+ D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A
+ // COLOROP only
+
+ // Bump mapping
+ D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation
+ D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel
+
+ // This can do either diffuse or specular bump mapping with correct input.
+ // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B)
+ // where each component has been scaled and offset to make it signed.
+ // The result is replicated into all four (including alpha) channels.
+ // This is a valid COLOROP only.
+ D3DTOP_DOTPRODUCT3 = 24,
+
+ // Triadic ops
+ D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2
+ D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2
+
+ D3DTOP_FORCE_DWORD = 0x7fffffff,
+} D3DTEXTUREOP;
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTEXTURESTAGESTATETYPE
+{
+ D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */
+ D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */
+ D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */
+ D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */
+ D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */
+ D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */
+ D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */
+ D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */
+ D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */
+ D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */
+ D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */
+ D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */
+
+
+ D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTEXTURESTAGESTATETYPE;
+
+//===========================================================================//
+
+enum GLMVertexAttributeIndex
+{
+ kGLMGenericAttr00 = 0,
+ kGLMGenericAttr01,
+ kGLMGenericAttr02,
+ kGLMGenericAttr03,
+ kGLMGenericAttr04,
+ kGLMGenericAttr05,
+ kGLMGenericAttr06,
+ kGLMGenericAttr07,
+ kGLMGenericAttr08,
+ kGLMGenericAttr09,
+ kGLMGenericAttr10,
+ kGLMGenericAttr11,
+ kGLMGenericAttr12,
+ kGLMGenericAttr13,
+ kGLMGenericAttr14,
+ kGLMGenericAttr15,
+
+ kGLMVertexAttributeIndexMax // ideally < 32
+};
+
+struct GLMVertexAttributeDesc // all the info you need to do vertex setup for one attribute
+{
+ CGLMBuffer *m_pBuffer; // NULL allowed in which case m_offset is the full 32-bit pointer.. so you can draw from plain RAM if desired
+ GLuint m_nCompCount; // comp count of the attribute (1-4)
+ GLenum m_datatype; // data type of the attribute (GL_FLOAT, GL_UNSIGNED_BYTE, etc)
+ GLuint m_stride;
+ GLuint m_offset; // net offset to attribute 'zero' within the buffer.
+ GLuint m_streamOffset; // net offset to attribute 'zero' within the buffer.
+ GLboolean m_normalized; // apply to any fixed point data that needs normalizing, esp color bytes
+
+ inline uint GetDataTypeSizeInBytes() const
+ {
+ switch ( m_datatype )
+ {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_HALF_FLOAT:
+ return 2;
+ case GL_INT:
+ case GL_FLOAT:
+ return 4;
+ default:
+ Assert( 0 );
+ break;
+ }
+ return 0;
+ }
+
+ inline uint GetTotalAttributeSizeInBytes() const { Assert( m_nCompCount ); return m_nCompCount * GetDataTypeSizeInBytes(); }
+
+ // may need a seed value at some point to be able to disambiguate re-lifed buffers holding same pointer
+ // simpler alternative is to do shoot-down inside the vertex/index buffer free calls.
+ // I'd rather not have to have each attribute fiddling a ref count on the buffer to which it refers..
+
+//#define EQ(fff) ( (src.fff) == (fff) )
+ // test in decreasing order of likelihood of difference, but do not include the buffer revision as caller is not supplying it..
+ //inline bool operator== ( const GLMVertexAttributeDesc& src ) const { return EQ( m_pBuffer ) && EQ( m_offset ) && EQ( m_stride ) && EQ( m_datatype ) && EQ( m_normalized ) && EQ( m_nCompCount ); }
+//#undef EQ
+
+ uint m_bufferRevision; // only set in GLM context's copy, to disambiguate references that are same offset / same buffer but cross an orphan event
+};
+
+#define MAX_D3DVERTEXELEMENTS 16
+
+struct D3DVERTEXELEMENT9_GL
+{
+ // fields right out of the original decl element (copied)
+ D3DVERTEXELEMENT9 m_dxdecl; // d3d info
+ // WORD Stream; // Stream index
+ // WORD Offset; // Offset in the stream in bytes
+ // BYTE Type; // Data type
+ // BYTE Method; // Processing method
+ // BYTE Usage; // Semantics
+ // BYTE UsageIndex; // Semantic index
+
+ GLMVertexAttributeDesc m_gldecl;
+ // CGLMBuffer *m_buffer; // late-dropped from selected stream desc (left NULL, will replace with stream source buffer at sync time)
+ // GLuint m_datasize; // component count (1,2,3,4) of the attrib
+ // GLenum m_datatype; // data type of the attribute (GL_FLOAT et al)
+ // GLuint m_stride; // late-dropped from stream desc
+ // GLuint m_offset; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL.
+ // GLuint m_normalized; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL.
+};
+
+struct IDirect3DDevice9Params
+{
+ UINT m_adapter;
+ D3DDEVTYPE m_deviceType;
+ VD3DHWND m_focusWindow;
+ DWORD m_behaviorFlags;
+ D3DPRESENT_PARAMETERS m_presentationParameters;
+};
+
+#define D3D_MAX_STREAMS 4
+struct D3DStreamDesc
+{
+ IDirect3DVertexBuffer9 *m_vtxBuffer;
+ uint m_offset;
+ uint m_stride;
+};
+
+struct D3DIndexDesc
+{
+ IDirect3DIndexBuffer9 *m_idxBuffer;
+};
+
+// we latch sampler values until draw time and then convert them all to GL form
+// note these are similar in name to the fields of a GLMTexSamplingParams but contents are not
+// particularly in the texture filtering area
+
+struct D3DSamplerDesc
+{
+ DWORD m_srgb; // D3DSAMP_SRGBTEXTURE 0 = no SRGB sampling
+};
+
+// Tracking and naming sampler dimensions
+#define SAMPLER_TYPE_2D 0
+#define SAMPLER_TYPE_CUBE 1
+#define SAMPLER_TYPE_3D 2
+#define SAMPLER_TYPE_UNUSED 3
+
+#endif // DXABSTRACT_TYPES_H
diff --git a/mp/src/public/togl/linuxwin/glbase.h b/mp/src/public/togl/linuxwin/glbase.h new file mode 100644 index 00000000..445d3665 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glbase.h @@ -0,0 +1,104 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glbase.h
+//
+//===============================================================================
+
+#ifndef GLBASE_H
+#define GLBASE_H
+
+#ifdef DX_TO_GL_ABSTRACTION
+
+#undef HAVE_GL_ARB_SYNC
+
+#ifndef OSX
+ #define HAVE_GL_ARB_SYNC 1
+#endif
+
+#ifdef OSX
+ #include <OpenGL/OpenGL.h>
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glext.h>
+ #include <OpenGL/CGLTypes.h>
+ #include <OpenGL/CGLRenderers.h>
+ #include <OpenGL/CGLCurrent.h>
+ #include <OpenGL/CGLProfiler.h>
+ #include <ApplicationServices/ApplicationServices.h>
+#elif defined(DX_TO_GL_ABSTRACTION)
+ #include <GL/gl.h>
+ #include <GL/glext.h>
+#else
+ #error
+#endif
+
+#ifdef DX_TO_GL_ABSTRACTION
+ #ifndef WIN32
+ #define Debugger DebuggerBreak
+ #endif
+ #undef CurrentTime
+
+ // prevent some conflicts in SDL headers...
+ #undef M_PI
+ #include <stdint.h>
+ #ifndef _STDINT_H_
+ #define _STDINT_H_ 1
+ #endif
+#endif
+
+//===============================================================================
+// glue to call out to Obj-C land (these are in glmgrcocoa.mm)
+#ifdef OSX
+ bool NewNSGLContext( unsigned long *attribs, PseudoNSGLContextPtr nsglShareCtx, PseudoNSGLContextPtr *nsglCtxOut, CGLContextObj *cglCtxOut );
+ CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx );
+ void DelNSGLContext( PseudoNSGLContextPtr nsglCtx );
+#endif
+
+// Set TOGL_SUPPORT_NULL_DEVICE to 1 to support the NULL ref device
+#define TOGL_SUPPORT_NULL_DEVICE 0
+
+#if TOGL_SUPPORT_NULL_DEVICE
+ #define TOGL_NULL_DEVICE_CHECK if( m_params.m_deviceType == D3DDEVTYPE_NULLREF ) return S_OK;
+ #define TOGL_NULL_DEVICE_CHECK_RET_VOID if( m_params.m_deviceType == D3DDEVTYPE_NULLREF ) return;
+#else
+ #define TOGL_NULL_DEVICE_CHECK
+ #define TOGL_NULL_DEVICE_CHECK_RET_VOID
+#endif
+
+// GL_ENABLE_INDEX_VERIFICATION enables index range verification on all dynamic IB/VB's (obviously slow)
+#define GL_ENABLE_INDEX_VERIFICATION 0
+
+// GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION (currently win32 only) - If 1, VirtualAlloc/VirtualProtect is used to detect cases where the app locks a buffer, copies the ptr away, unlocks, then tries to later write to the buffer.
+#define GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION 0
+
+#define GL_BATCH_TELEMETRY_ZONES 0
+
+// GL_BATCH_PERF_ANALYSIS - Enables gl_batch_vis, and various per-batch telemetry statistics messages.
+#define GL_BATCH_PERF_ANALYSIS 0
+#define GL_BATCH_PERF_ANALYSIS_WRITE_PNGS 0
+
+// GL_TELEMETRY_ZONES - Causes every single OpenGL call to generate a telemetry event
+#define GL_TELEMETRY_ZONES 0
+
+// GL_DUMP_ALL_API_CALLS - Causes a debug message to be printed for every API call if s_bDumpCalls bool is set to 1
+#define GL_DUMP_ALL_API_CALLS 0
+
+// Must also enable PIX_ENABLE to use GL_TELEMETRY_GPU_ZONES.
+#define GL_TELEMETRY_GPU_ZONES 0
+
+// Records global # of OpenGL calls/total cycles spent inside GL
+#define GL_TRACK_API_TIME GL_BATCH_PERF_ANALYSIS
+
+#define GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS ( GL_TELEMETRY_ZONES || GL_TRACK_API_TIME || GL_DUMP_ALL_API_CALLS )
+
+#if GL_BATCH_PERF_ANALYSIS
+ #define GL_BATCH_PERF(...) __VA_ARGS__
+#else
+ #define GL_BATCH_PERF(...)
+#endif
+
+#define kGLMUserClipPlanes 2
+#define kGLMScratchFBOCount 4
+
+#endif // DX_TO_GL_ABSTRACTION
+
+#endif // GLBASE_H
diff --git a/mp/src/public/togl/linuxwin/glentrypoints.h b/mp/src/public/togl/linuxwin/glentrypoints.h new file mode 100644 index 00000000..d1347175 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glentrypoints.h @@ -0,0 +1,378 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glentrypoints.h
+//
+//===============================================================================
+
+#ifndef GLENTRYPOINTS_H
+#define GLENTRYPOINTS_H
+
+#pragma once
+
+#ifdef DX_TO_GL_ABSTRACTION
+
+#include "tier0/platform.h"
+#include "tier0/dynfunction.h"
+#include "tier0/vprof_telemetry.h"
+#include "interface.h"
+
+#include "togl/rendermechanism.h"
+
+void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL);
+
+#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
+class CGLExecuteHelperBase
+{
+public:
+ inline void StartCall(const char *pName);
+ inline void StopCall(const char *pName);
+#if GL_TRACK_API_TIME
+ TmU64 m_nStartTime;
+#endif
+};
+
+template < class FunctionType, typename Result >
+class CGLExecuteHelper : public CGLExecuteHelperBase
+{
+public:
+ inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(); StopCall(pName); }
+ template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a); StopCall(pName); }
+ template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b); StopCall(pName); }
+ template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
+
+ inline operator Result() const { return m_Result; }
+ inline operator char*() const { return (char*)m_Result; }
+
+ FunctionType m_pFn;
+
+ Result m_Result;
+};
+
+template < class FunctionType>
+class CGLExecuteHelper<FunctionType, void> : public CGLExecuteHelperBase
+{
+public:
+ inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(); StopCall(pName); }
+ template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a); StopCall(pName); }
+ template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b); StopCall(pName); }
+ template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
+
+ FunctionType m_pFn;
+};
+#endif
+
+template < class FunctionType, typename Result >
+class CDynamicFunctionOpenGLBase
+{
+public:
+ // Construct with a NULL function pointer. You must manually call
+ // Lookup() before you can call a dynamic function through this interface.
+ CDynamicFunctionOpenGLBase() : m_pFn(NULL) {}
+
+ // Construct and do a lookup right away. You will need to make sure that
+ // the lookup actually succeeded, as the gl library might have failed to load
+ // or (fn) might not exist in it.
+ CDynamicFunctionOpenGLBase(const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(fn, fallback);
+ }
+
+ // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
+ CDynamicFunctionOpenGLBase(const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(fn, okay, fallback);
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // This allows you to chain lookups like this:
+ // bool okay = true;
+ // x.Lookup(lib, "x", okay);
+ // y.Lookup(lib, "y", okay);
+ // z.Lookup(lib, "z", okay);
+ // if (okay) { printf("All functions were loaded successfully!\n"); }
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return (okay)).
+ bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ if (!okay)
+ return false;
+ else if (this->m_pFn == NULL)
+ {
+ this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, false, (void *) fallback);
+ this->SetFuncName( fn );
+ }
+ okay = m_pFn != NULL;
+ return okay;
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return true).
+ bool Lookup(const char *fn, FunctionType fallback=NULL)
+ {
+ bool okay = true;
+ return Lookup(fn, okay, fallback);
+ }
+
+ // Invalidates the current lookup. Makes the function pointer NULL. You
+ // will need to call Lookup() before you can call a dynamic function
+ // through this interface again.
+ void Reset() { m_pFn = NULL; }
+
+ // Force this to be a specific function pointer.
+ void Force(FunctionType ptr) { m_pFn = ptr; }
+
+ // Retrieve the actual function pointer.
+ FunctionType Pointer() const { return m_pFn; }
+
+#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
+ #if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS
+ #define GL_FUNC_NAME m_szName
+ #else
+ #define GL_FUNC_NAME ""
+ #endif
+
+ inline CGLExecuteHelper<FunctionType, Result> operator() () const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME ); }
+
+ template<typename T>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a); }
+
+ template<typename T, typename U>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b); }
+
+ template<typename T, typename U, typename V>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c ) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c); }
+
+ template<typename T, typename U, typename V, typename W>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d); }
+
+ template<typename T, typename U, typename V, typename W, typename X>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i, C j) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i, j); }
+#else
+ operator FunctionType() const { return m_pFn; }
+#endif
+
+ // Can be used to verify that we have an actual function looked up and
+ // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
+ operator bool () const { return m_pFn != NULL; }
+ bool operator !() const { return m_pFn == NULL; }
+
+protected:
+ FunctionType m_pFn;
+
+#if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS
+ char m_szName[32];
+ inline void SetFuncName(const char *pFn) { V_strncpy( m_szName, pFn, sizeof( m_szName ) ); }
+#else
+ inline void SetFuncName(const char *pFn) { (void)pFn; }
+#endif
+};
+
+// This works a lot like CDynamicFunctionMustInit, but we use SDL_GL_GetProcAddress().
+template < const bool bRequired, class FunctionType, typename Result >
+class CDynamicFunctionOpenGL : public CDynamicFunctionOpenGLBase< FunctionType, Result >
+{
+private: // forbid default constructor.
+ CDynamicFunctionOpenGL() {}
+
+public:
+ CDynamicFunctionOpenGL(const char *fn, FunctionType fallback=NULL)
+ {
+ bool okay = true;
+ Lookup(fn, okay, fallback);
+ this->SetFuncName( fn );
+ }
+
+ CDynamicFunctionOpenGL(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ Lookup(fn, okay, fallback);
+ this->SetFuncName( fn );
+ }
+
+ // Please note this is not virtual.
+ // !!! FIXME: we might want to fall back and try "EXT" or "ARB" versions in some case.
+ bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ if (this->m_pFn == NULL)
+ {
+ this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, bRequired, (void *) fallback);
+ this->SetFuncName( fn );
+ }
+ return okay;
+ }
+};
+
+enum GLDriverStrings_t
+{
+ cGLVendorString,
+ cGLRendererString,
+ cGLVersionString,
+ cGLExtensionsString,
+
+ cGLTotalDriverStrings
+};
+
+enum GLDriverProvider_t
+{
+ cGLDriverProviderUnknown,
+ cGLDriverProviderNVIDIA,
+ cGLDriverProviderAMD,
+ cGLDriverProviderIntel,
+ cGLDriverProviderIntelOpenSource,
+ cGLDriverProviderApple,
+
+ cGLTotalDriverProviders
+};
+
+// This provides all the entry points for a given OpenGL context.
+// ENTRY POINTS ARE ONLY VALID FOR THE CONTEXT THAT WAS CURRENT WHEN
+// YOU LOOKED THEM UP. 99% of the time, this is not a problem, but
+// that 1% is really hard to track down. Always access the GL
+// through this class!
+class COpenGLEntryPoints
+{
+ COpenGLEntryPoints( const COpenGLEntryPoints & );
+ COpenGLEntryPoints &operator= ( const COpenGLEntryPoints & );
+
+public:
+ // The GL context you are looking up entry points for must be current when you construct this object!
+ COpenGLEntryPoints();
+ ~COpenGLEntryPoints();
+
+ void ClearEntryPoints();
+
+ uint64 m_nTotalGLCycles, m_nTotalGLCalls;
+
+ int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2.
+ int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1.
+ int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0.
+ bool m_bHave_OpenGL;
+
+ char *m_pGLDriverStrings[cGLTotalDriverStrings];
+ GLDriverProvider_t m_nDriverProvider;
+
+ #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
+ #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn;
+ #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn;
+ #include "togl/glfuncs.inl"
+ #undef GL_FUNC_VOID
+ #undef GL_FUNC
+ #undef GL_EXT
+
+ bool HasSwapTearExtension() const
+ {
+#ifdef _WIN32
+ return m_bHave_WGL_EXT_swap_control_tear;
+#else
+ return m_bHave_GLX_EXT_swap_control_tear;
+#endif
+ }
+};
+
+// This will be set to the current OpenGL context's entry points.
+extern COpenGLEntryPoints *gGL;
+typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, bool &, const bool, void *);
+
+#ifdef TOGL_DLL_EXPORT
+ DLL_EXPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
+ DLL_EXPORT void ToGLDisconnectLibraries();
+ DLL_EXPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
+ DLL_EXPORT void ClearOpenGLEntryPoints();
+#else
+ DLL_IMPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
+ DLL_IMPORT void ToGLDisconnectLibraries();
+ DLL_IMPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
+ DLL_IMPORT void ClearOpenGLEntryPoints();
+#endif
+
+#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS
+inline void CGLExecuteHelperBase::StartCall(const char *pName)
+{
+ (void)pName;
+
+#if GL_TELEMETRY_ZONES
+ tmEnter( TELEMETRY_LEVEL3, TMZF_NONE, pName );
+#endif
+
+#if GL_TRACK_API_TIME
+ m_nStartTime = tmFastTime();
+#endif
+
+#if GL_DUMP_ALL_API_CALLS
+ static bool s_bDumpCalls;
+ if ( s_bDumpCalls )
+ {
+ char buf[128];
+ buf[0] = 'G';
+ buf[1] = 'L';
+ buf[2] = ':';
+ size_t l = strlen( pName );
+ memcpy( buf + 3, pName, l );
+ buf[3 + l] = '\n';
+ buf[4 + l] = '\0';
+ Plat_DebugString( buf );
+ }
+#endif
+}
+
+inline void CGLExecuteHelperBase::StopCall(const char *pName)
+{
+#if GL_TRACK_API_TIME
+ uint64 nTotalCycles = tmFastTime() - m_nStartTime;
+#endif
+
+#if GL_TELEMETRY_ZONES
+ tmLeave( TELEMETRY_LEVEL3 );
+#endif
+
+#if GL_TRACK_API_TIME
+ //double flMilliseconds = g_Telemetry.flRDTSCToMilliSeconds * nTotalCycles;
+ if (gGL)
+ {
+ gGL->m_nTotalGLCycles += nTotalCycles;
+ gGL->m_nTotalGLCalls++;
+ }
+#endif
+}
+#endif
+
+#endif // DX_TO_GL_ABSTRACTION
+
+#endif // GLENTRYPOINTS_H
diff --git a/mp/src/public/togl/linuxwin/glfuncs.h b/mp/src/public/togl/linuxwin/glfuncs.h new file mode 100644 index 00000000..3ef3772c --- /dev/null +++ b/mp/src/public/togl/linuxwin/glfuncs.h @@ -0,0 +1,236 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+// !!! FIXME: Some of these aren't base OpenGL...pick out the extensions.
+// !!! FIXME: Also, look up these -1, -1 versions numbers.
+GL_FUNC(OpenGL,true,GLenum,glGetError,(void),())
+GL_FUNC_VOID(OpenGL,true,glActiveTexture,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glAlphaFunc,(GLenum a,GLclampf b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glAttachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBegin,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glBindAttribLocationARB,(GLhandleARB a,GLuint b,const GLcharARB *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glBindBufferARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBindProgramARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBindTexture,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBlendColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glBlendEquation,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glBlendFunc,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBufferDataARB,(GLenum a,GLsizeiptrARB b,const GLvoid *c,GLenum d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glClear,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glClearColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glClearDepth,(GLclampd a),(a))
+GL_FUNC_VOID(OpenGL,true,glClearStencil,(GLint a),(a))
+GL_FUNC_VOID(OpenGL,true,glClipPlane,(GLenum a,const GLdouble *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glColorMask,(GLboolean a,GLboolean b,GLboolean c,GLboolean d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glCompileShaderARB,(GLhandleARB a),(a))
+GL_FUNC_VOID(OpenGL,true,glCompressedTexImage2D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLint f,GLsizei g,const GLvoid *h),(a,b,c,d,e,f,g,h))
+GL_FUNC_VOID(OpenGL,true,glCompressedTexImage3D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLsizei h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC(OpenGL,true,GLhandleARB,glCreateProgramObjectARB,(void),())
+GL_FUNC(OpenGL,true,GLhandleARB,glCreateShaderObjectARB,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteBuffersARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteObjectARB,(GLhandleARB a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteProgramsARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteQueriesARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteShader,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteTextures,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDepthFunc,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDepthMask,(GLboolean a),(a))
+GL_FUNC_VOID(OpenGL,true,glDepthRange,(GLclampd a,GLclampd b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDetachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDisable,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDisableVertexAttribArray,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glDrawArrays,(GLenum a,GLint b,GLsizei c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glDrawBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDrawRangeElements,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glDrawRangeElementsBaseVertex,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f, GLenum g),(a,b,c,d,e,f,g))
+GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glEnd,(void),())
+GL_FUNC_VOID(OpenGL,true,glFinish,(void),())
+GL_FUNC_VOID(OpenGL,true,glFlush,(void),())
+GL_FUNC_VOID(OpenGL,true,glFrontFace,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glGenBuffersARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenProgramsARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenQueriesARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenTextures,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetBooleanv,(GLenum a,GLboolean *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetCompressedTexImage,(GLenum a,GLint b,GLvoid *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glGetDoublev,(GLenum a,GLdouble *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetFloatv,(GLenum a,GLfloat *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetInfoLogARB,(GLhandleARB a,GLsizei b,GLsizei *c,GLcharARB *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glGetIntegerv,(GLenum a,GLint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetObjectParameterivARB,(GLhandleARB a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glGetProgramivARB,(GLenum a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC(OpenGL,true,const GLubyte *,glGetString,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glGetTexImage,(GLenum a,GLint b,GLenum c,GLenum d,GLvoid *e),(a,b,c,d,e))
+GL_FUNC(OpenGL,true,GLint,glGetUniformLocationARB,(GLhandleARB a,const GLcharARB *b),(a,b))
+GL_FUNC(OpenGL,true,GLboolean,glIsEnabled,(GLenum a),(a))
+GL_FUNC(OpenGL,true,GLboolean,glIsTexture,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glLinkProgramARB,(GLhandleARB a),(a))
+GL_FUNC(OpenGL,true,GLvoid*,glMapBufferARB,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glOrtho,(GLdouble a,GLdouble b,GLdouble c,GLdouble d,GLdouble e,GLdouble f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glPixelStorei,(GLenum a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPolygonMode,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPolygonOffset,(GLfloat a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPopAttrib,(void),())
+GL_FUNC_VOID(OpenGL,true,glProgramStringARB,(GLenum a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glPushAttrib,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glReadBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glScissor,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glShaderSourceARB,(GLhandleARB a,GLsizei b,const GLcharARB **c,const GLint *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glStencilFunc,(GLenum a,GLint b,GLuint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glStencilMask,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glStencilOp,(GLenum a,GLenum b,GLenum c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexCoord2f,(GLfloat a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glTexImage2D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLint f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC_VOID(OpenGL,true,glTexImage3D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLenum h,GLenum i,const GLvoid *j),(a,b,c,d,e,f,g,h,i,j))
+GL_FUNC_VOID(OpenGL,true,glTexParameterfv,(GLenum a,GLenum b,const GLfloat *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexParameteri,(GLenum a,GLenum b,GLint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexSubImage2D,(GLenum a,GLint b,GLint c,GLint d,GLsizei e,GLsizei f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC_VOID(OpenGL,true,glUniform1f,(GLint a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform1i,(GLint a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform1iARB,(GLint a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform4fv,(GLint a,GLsizei b,const GLfloat *c),(a,b,c))
+GL_FUNC(OpenGL,true,GLboolean,glUnmapBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glUseProgram,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glVertex3f,(GLfloat a,GLfloat b,GLfloat c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glVertexAttribPointer,(GLuint a,GLint b,GLenum c,GLboolean d,GLsizei e,const GLvoid *f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glViewport,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glEnableClientState,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDisableClientState,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glClientActiveTexture,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glVertexPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glTexCoordPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glProgramEnvParameters4fvEXT,(GLenum a,GLuint b,GLsizei c,const GLfloat *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glColor4sv,(const GLshort *a),(a))
+GL_FUNC_VOID(OpenGL,true,glStencilOpSeparate,(GLenum a,GLenum b,GLenum c,GLenum d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glStencilFuncSeparate,(GLenum a,GLenum b,GLint c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glGetTexLevelParameteriv,(GLenum a,GLint b,GLenum c,GLint *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glColor4f,(GLfloat a,GLfloat b,GLfloat c,GLfloat d),(a,b,c,d))
+GL_EXT(GL_EXT_framebuffer_object,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindFramebufferEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindRenderbufferEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC(GL_EXT_framebuffer_object,false,GLenum,glCheckFramebufferStatusEXT,(GLenum a),(a))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteRenderbuffersEXT,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferRenderbufferEXT,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture2DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture3DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenFramebuffersEXT,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenRenderbuffersEXT,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteFramebuffersEXT,(GLsizei a,const GLuint *b),(a,b))
+GL_EXT(GL_EXT_framebuffer_blit,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_blit,false,glBlitFramebufferEXT,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j))
+GL_EXT(GL_EXT_framebuffer_multisample,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_multisample,false,glRenderbufferStorageMultisampleEXT,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e))
+GL_EXT(GL_APPLE_fence,-1,-1)
+GL_FUNC(GL_APPLE_fence,false,GLboolean,glTestFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glSetFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glFinishFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glDeleteFencesAPPLE,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_APPLE_fence,false,glGenFencesAPPLE,(GLsizei a,GLuint *b),(a,b))
+GL_EXT(GL_NV_fence,-1,-1)
+GL_FUNC(GL_NV_fence,false,GLboolean,glTestFenceNV,(GLuint a),(a))
+GL_FUNC_VOID(GL_NV_fence,false,glSetFenceNV,(GLuint a,GLenum b),(a,b))
+GL_FUNC_VOID(GL_NV_fence,false,glFinishFenceNV,(GLuint a),(a))
+GL_FUNC_VOID(GL_NV_fence,false,glDeleteFencesNV,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_NV_fence,false,glGenFencesNV,(GLsizei a,GLuint *b),(a,b))
+GL_EXT(GL_ARB_sync,3,2)
+#ifdef HAVE_GL_ARB_SYNC
+GL_FUNC_VOID(GL_ARB_sync,false,glGetSynciv,(GLsync a, GLenum b, GLsizei c, GLsizei *d, GLint *e),(a,b,c,d,e))
+GL_FUNC(GL_ARB_sync,false,GLenum,glClientWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_sync,false,glWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_sync,false,glDeleteSync,(GLsync a),(a))
+GL_FUNC(GL_ARB_sync,false,GLsync,glFenceSync,(GLenum a, GLbitfield b),(a,b))
+#endif
+GL_EXT(GL_EXT_draw_buffers2,-1,-1)
+GL_FUNC_VOID(GL_EXT_draw_buffers2,true,glColorMaskIndexedEXT,(GLuint a,GLboolean b,GLboolean c,GLboolean d,GLboolean e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,true,glEnableIndexedEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,true,glDisableIndexedEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,true,glGetBooleanIndexedvEXT,(GLenum a,GLuint b,GLboolean *c),(a,b,c))
+GL_EXT(GL_EXT_bindable_uniform,-1,-1)
+GL_FUNC_VOID(GL_EXT_bindable_uniform,false,glUniformBufferEXT,(GLuint a,GLint b,GLuint c),(a,b,c))
+GL_FUNC(GL_EXT_bindable_uniform,false,int,glGetUniformBufferSizeEXT,(GLenum a, GLenum b),(a,b))
+GL_FUNC(GL_EXT_bindable_uniform,false,GLintptr,glGetUniformOffsetEXT,(GLenum a, GLenum b),(a,b))
+GL_EXT(GL_APPLE_flush_buffer_range,-1,-1)
+GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glBufferParameteriAPPLE,(GLenum a,GLenum b,GLint c),(a,b,c))
+GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glFlushMappedBufferRangeAPPLE,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c))
+GL_EXT(GL_ARB_map_buffer_range,-1,-1)
+GL_FUNC(GL_ARB_map_buffer_range,false,void*,glMapBufferRange,(GLenum a,GLintptr b,GLsizeiptr c,GLbitfield d),(a,b,c,d))
+GL_FUNC_VOID(GL_ARB_map_buffer_range,false,glFlushMappedBufferRange,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c))
+GL_EXT(GL_ARB_vertex_buffer_object,-1,-1)
+GL_FUNC_VOID(GL_ARB_vertex_buffer_object,true,glBufferSubData,(GLenum a,GLintptr b,GLsizeiptr c,const GLvoid *d),(a,b,c,d))
+GL_EXT(GL_ARB_occlusion_query,-1,-1)
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glBeginQueryARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glEndQueryARB,(GLenum a),(a))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectivARB,(GLuint a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectuivARB,(GLuint a,GLenum b,GLuint *c),(a,b,c))
+GL_EXT(GL_APPLE_texture_range,-1,-1)
+GL_FUNC_VOID(GL_APPLE_texture_range,false,glTextureRangeAPPLE,(GLenum a,GLsizei b,void *c),(a,b,c))
+GL_FUNC_VOID(GL_APPLE_texture_range,false,glGetTexParameterPointervAPPLE,(GLenum a,GLenum b,void* *c),(a,b,c))
+GL_EXT(GL_APPLE_client_storage,-1,-1)
+GL_EXT(GL_ARB_uniform_buffer,-1,-1)
+GL_EXT(GL_ARB_vertex_array_bgra,-1,-1)
+GL_EXT(GL_EXT_vertex_array_bgra,-1,-1)
+GL_EXT(GL_ARB_framebuffer_object,3,0)
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindFramebuffer,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindRenderbuffer,(GLenum a,GLuint b),(a,b))
+GL_FUNC(GL_ARB_framebuffer_object,false,GLenum,glCheckFramebufferStatus,(GLenum a),(a))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteRenderbuffers,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferRenderbuffer,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture2D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture3D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenFramebuffers,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenRenderbuffers,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteFramebuffers,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBlitFramebuffer,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glRenderbufferStorageMultisample,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e))
+GL_EXT(GL_GREMEDY_string_marker,-1,-1)
+GL_FUNC_VOID(GL_GREMEDY_string_marker,false,glStringMarkerGREMEDY,(GLsizei a,const void *b),(a,b))
+GL_EXT(GL_ARB_debug_output,-1,-1)
+GL_FUNC_VOID(GL_ARB_debug_output,false,glDebugMessageCallbackARB,(void (APIENTRY *a)(GLenum, GLenum , GLuint , GLenum , GLsizei , const GLchar* , GLvoid*) ,void* b),(a,b))
+GL_FUNC_VOID(GL_ARB_debug_output,false,glDebugMessageControlARB,(GLenum a, GLenum b, GLenum c, GLsizei d, const GLuint* e, GLboolean f),(a,b,c,d,e,f))
+GL_EXT(GL_EXT_direct_state_access,-1,-1)
+GL_FUNC_VOID(GL_EXT_direct_state_access,false,glBindMultiTextureEXT,(GLenum a,GLuint b, GLuint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glGenSamplers,(GLuint a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteSamplers,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBindSampler,(GLuint a, GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glSamplerParameteri,(GLuint a, GLenum b, GLint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glSamplerParameterf,(GLuint a, GLenum b, GLfloat c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glSamplerParameterfv,(GLuint a, GLenum b, const GLfloat *c),(a,b,c))
+GL_EXT(GL_NV_bindless_texture,-1,-1)
+GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureHandleNV, (GLuint texture), (texture))
+GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureSamplerHandleNV, (GLuint texture, GLuint sampler), (texture, sampler))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glMakeTextureHandleResidentNV, (GLuint64 handle), (handle))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glMakeTextureHandleNonResidentNV, (GLuint64 handle), (handle))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glUniformHandleui64NV, (GLint location, GLuint64 value), (location, value))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glUniformHandleui64vNV, (int location, GLsizei count, const GLuint64 *value), (location count, value))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glProgramUniformHandleui64NV, (GLuint program, GLint location, GLuint64 value), (program, location, value))
+GL_FUNC_VOID(GL_NV_bindless_texture, false, glProgramUniformHandleui64vNV, (GLuint program, GLint location, GLsizei count, const GLuint64 *values), (program, location, count, values))
+GL_FUNC(GL_NV_bindless_texture, false, GLboolean, glIsTextureHandleResidentNV, (GLuint64 handle), (handle))
+GL_FUNC_VOID(OpenGL,true,glGenQueries,(GLsizei n, GLuint *ids), (n, ids))
+GL_FUNC_VOID(OpenGL,true,glDeleteQueries,(GLsizei n, const GLuint *ids),(n, ids))
+GL_FUNC_VOID(OpenGL,true,glBeginQuery,(GLenum target, GLuint id), (target, id))
+GL_FUNC_VOID(OpenGL,true,glEndQuery,(GLenum target), (target))
+GL_FUNC_VOID(OpenGL,true,glQueryCounter,(GLuint id, GLenum target), (id, target))
+GL_FUNC_VOID(OpenGL,true,glGetQueryObjectiv,(GLuint id, GLenum pname, GLint *params), (id, pname, params))
+GL_FUNC_VOID(OpenGL,true,glGetQueryObjectui64v,(GLuint id, GLenum pname, GLuint64 *params), (id, pname, params))
+GL_FUNC_VOID(OpenGL,true,glCopyBufferSubData,(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size),(readtarget, writetarget, readoffset, writeoffset, size))
+GL_EXT(GL_AMD_pinned_memory,-1,-1)
+GL_EXT(GL_EXT_framebuffer_multisample_blit_scaled,-1,-1)
+GL_FUNC_VOID(OpenGL,true,glGenVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays))
+GL_FUNC_VOID(OpenGL,true,glDeleteVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays))
+GL_FUNC_VOID(OpenGL,true,glBindVertexArray,(GLuint a),(a))
+GL_EXT(GL_EXT_texture_sRGB_decode,-1,-1)
+GL_FUNC_VOID(OpenGL,true,glPushClientAttrib,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glPopClientAttrib,(void),())
+GL_EXT(GL_NVX_gpu_memory_info,-1,-1)
+GL_EXT(GL_ATI_meminfo,-1,-1)
+GL_EXT(GL_EXT_texture_compression_s3tc,-1,-1)
+GL_EXT(GL_EXT_texture_compression_dxt1,-1,-1)
+GL_EXT(GL_ANGLE_texture_compression_dxt3,-1,-1)
+GL_EXT(GL_ANGLE_texture_compression_dxt5,-1,-1)
+
+// This one is an OS extension. We'll add a little helper function to look for it.
+#ifdef _WIN32
+ GL_EXT(WGL_EXT_swap_control_tear,-1,-1)
+#else
+ GL_EXT(GLX_EXT_swap_control_tear,-1,-1)
+#endif
diff --git a/mp/src/public/togl/linuxwin/glmdebug.h b/mp/src/public/togl/linuxwin/glmdebug.h new file mode 100644 index 00000000..80df86f1 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmdebug.h @@ -0,0 +1,160 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef GLMDEBUG_H
+#define GLMDEBUG_H
+
+#include "tier0/platform.h"
+
+// include this anywhere you need to be able to compile-out code related specifically to GLM debugging.
+
+// we expect DEBUG to be driven by the build system so you can include this header anywhere.
+// when we come out, GLMDEBUG will be defined to a value - 0, 1, or 2
+// 0 means no GLM debugging is possible
+// 1 means it's possible and resulted from being a debug build
+// 2 means it's possible and resulted from being manually forced on for a release build
+
+#ifdef POSIX
+ #ifndef GLMDEBUG
+ #ifdef DEBUG
+ #define GLMDEBUG 1 // normally 1 here, testing
+ #else
+ // #define GLMDEBUG 2 // don't check this in enabled..
+ #endif
+
+ #ifndef GLMDEBUG
+ #define GLMDEBUG 0
+ #endif
+ #endif
+#else
+ #ifndef GLMDEBUG
+ #define GLMDEBUG 0
+ #endif
+#endif
+
+
+//===============================================================================
+// debug channels
+
+enum EGLMDebugChannel
+{
+ ePrintf,
+ eDebugger,
+ eGLProfiler
+};
+
+#if GLMDEBUG
+ // make all these prototypes disappear in non GLMDEBUG
+ void GLMDebugInitialize( bool forceReinit=false );
+
+ bool GLMDetectOGLP( void );
+ bool GLMDetectGDB( void );
+ uint GLMDetectAvailableChannels( void );
+
+ uint GLMDebugChannelMask( uint *newValue = NULL );
+ // note that GDB and OGLP can both come and go during run - forceCheck will allow that to be detected.
+ // mask returned is in form of 1<<n, n from EGLMDebugChannel
+#endif
+
+//===============================================================================
+// debug message flavors
+
+enum EGLMDebugFlavor
+{
+ eAllFlavors, // 0
+ eDebugDump, // 1 debug dump flavor -D-
+ eTenure, // 2 code tenures > <
+ eComment, // 3 one off messages ---
+ eMatrixData, // 4 matrix data -M-
+ eShaderData, // 5 shader data (params) -S-
+ eFrameBufData, // 6 FBO data (attachments) -F-
+ eDXStuff, // 7 dxabstract spew -X-
+ eAllocations, // 8 tracking allocs and frees -A-
+ eSlowness, // 9 slow things happening (srgb flips..) -Z-
+ eDefaultFlavor, // not specified (no marker)
+ eFlavorCount
+};
+uint GLMDebugFlavorMask( uint *newValue = NULL );
+
+// make all these prototypes disappear in non GLMDEBUG
+#if GLMDEBUG
+ // these are unconditional outputs, they don't interrogate the string
+ void GLMStringOut( const char *string );
+ void GLMStringOutIndented( const char *string, int indentColumns );
+
+ #ifdef TOGL_DLL_EXPORT
+ // these will look at the string to guess its flavor: <, >, ---, -M-, -S-
+ DLL_EXPORT void GLMPrintfVA( const char *fmt, va_list vargs );
+ DLL_EXPORT void GLMPrintf( const char *fmt, ... );
+ #else
+ DLL_IMPORT void GLMPrintfVA( const char *fmt, va_list vargs );
+ DLL_IMPORT void GLMPrintf( const char *fmt, ... );
+ #endif
+
+ // these take an explicit flavor with a default value
+ void GLMPrintStr( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor );
+
+ #define GLMPRINTTEXT_NUMBEREDLINES 0x80000000
+ void GLMPrintText( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor, uint options=0 ); // indent each newline
+
+ int GLMIncIndent( int indentDelta );
+ int GLMGetIndent( void );
+ void GLMSetIndent( int indent );
+
+#endif
+
+// helpful macro if you are in a position to call GLM functions directly (i.e. you live in materialsystem / shaderapidx9)
+#if GLMDEBUG
+ #define GLMPRINTF(args) GLMPrintf args
+ #define GLMPRINTSTR(args) GLMPrintStr args
+ #define GLMPRINTTEXT(args) GLMPrintText args
+#else
+ #define GLMPRINTF(args)
+ #define GLMPRINTSTR(args)
+ #define GLMPRINTTEXT(args)
+#endif
+
+
+//===============================================================================
+// knob twiddling
+#ifdef TOGL_DLL_EXPORT
+ DLL_EXPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value
+ DLL_EXPORT float GLMKnobToggle( char *knobname );
+#else
+ DLL_IMPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value
+ DLL_IMPORT float GLMKnobToggle( char *knobname );
+#endif
+
+//===============================================================================
+// other stuff
+
+#if GLMDEBUG
+void GLMTriggerDebuggerBreak();
+inline void GLMDebugger( void )
+{
+ if (GLMDebugChannelMask() & (1<<eDebugger))
+ {
+#ifdef OSX
+ asm {int 3 };
+#else
+ DebuggerBreak();
+#endif
+ }
+
+ if (GLMDebugChannelMask() & (1<<eGLProfiler))
+ {
+ GLMTriggerDebuggerBreak();
+ }
+}
+#else
+ #define GLMDebugger() do { } while(0)
+#endif
+
+// helpers for CGLSetOption - no op if no profiler
+void GLMProfilerClearTrace( void );
+void GLMProfilerEnableTrace( bool enable );
+
+// helpers for CGLSetParameter - no op if no profiler
+void GLMProfilerDumpState( void );
+
+void CheckGLError( int line );
+
+#endif // GLMDEBUG_H
diff --git a/mp/src/public/togl/linuxwin/glmdisplay.h b/mp/src/public/togl/linuxwin/glmdisplay.h new file mode 100644 index 00000000..6e83f8b8 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmdisplay.h @@ -0,0 +1,176 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmdisplay.h
+// display related stuff - used by both GLMgr and the CocoaMgr
+//
+//===============================================================================
+
+#ifndef GLMDISPLAY_H
+#define GLMDISPLAY_H
+
+#pragma once
+
+#ifdef OSX
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/CGLTypes.h>
+#include <OpenGL/CGLRenderers.h>
+#include <OpenGL/CGLCurrent.h>
+#include <ApplicationServices/ApplicationServices.h>
+#elif defined(DX_TO_GL_ABSTRACTION)
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include "tier0/platform.h"
+#else
+#error
+#endif
+
+typedef void _PseudoNSGLContext; // aka NSOpenGLContext
+typedef _PseudoNSGLContext *PseudoNSGLContextPtr;
+
+struct GLMDisplayModeInfoFields
+{
+ uint m_modePixelWidth;
+ uint m_modePixelHeight;
+ uint m_modeRefreshHz;
+ // are we even going to talk about bit depth... not yet
+};
+
+struct GLMDisplayInfoFields
+{
+#ifdef OSX
+ CGDirectDisplayID m_cgDisplayID;
+ CGOpenGLDisplayMask m_glDisplayMask; // result of CGDisplayIDToOpenGLDisplayMask on the cg_displayID.
+#endif
+ uint m_displayPixelWidth;
+ uint m_displayPixelHeight;
+};
+
+struct GLMRendererInfoFields
+{
+ /*properties of interest and their desired values.
+
+ kCGLRPFullScreen = 54, true
+ kCGLRPAccelerated = 73, true
+ kCGLRPWindow = 80, true
+
+ kCGLRPRendererID = 70, informational
+ kCGLRPDisplayMask = 84, informational
+ kCGLRPBufferModes = 100, informational
+ kCGLRPColorModes = 103, informational
+ kCGLRPAccumModes = 104, informational
+ kCGLRPDepthModes = 105, informational
+ kCGLRPStencilModes = 106, informational
+ kCGLRPMaxAuxBuffers = 107, informational
+ kCGLRPMaxSampleBuffers = 108, informational
+ kCGLRPMaxSamples = 109, informational
+ kCGLRPSampleModes = 110, informational
+ kCGLRPSampleAlpha = 111, informational
+ kCGLRPVideoMemory = 120, informational
+ kCGLRPTextureMemory = 121, informational
+ kCGLRPRendererCount = 128 number of renderers in the CGLRendererInfoObj under examination
+
+ kCGLRPOffScreen = 53, D/C
+ kCGLRPRobust = 75, FALSE or D/C - aka we're asking for no-fallback
+ kCGLRPBackingStore = 76, D/C
+ kCGLRPMPSafe = 78, D/C
+ kCGLRPMultiScreen = 81, D/C
+ kCGLRPCompliant = 83, D/C
+ */
+
+
+ //--------------------------- info we have from CGL renderer queries, IOKit, Gestalt
+ //--------------------------- these are set up in the displayDB by CocoaMgr
+ GLint m_fullscreen;
+ GLint m_accelerated;
+ GLint m_windowed;
+
+ GLint m_rendererID;
+ GLint m_displayMask;
+ GLint m_bufferModes;
+ GLint m_colorModes;
+ GLint m_accumModes;
+ GLint m_depthModes;
+ GLint m_stencilModes;
+
+ GLint m_maxAuxBuffers;
+ GLint m_maxSampleBuffers;
+ GLint m_maxSamples;
+ GLint m_sampleModes;
+ GLint m_sampleAlpha;
+
+ GLint m_vidMemory;
+ GLint m_texMemory;
+
+ uint m_pciVendorID;
+ uint m_pciDeviceID;
+ char m_pciModelString[64];
+ char m_driverInfoString[64];
+
+ //--------------------------- OS version related - set up by CocoaMgr
+
+ // OS version found
+ uint m_osComboVersion; // 0x00XXYYZZ : XX major, YY minor, ZZ minor minor : 10.6.3 --> 0x000A0603. 10.5.8 --> 0x000A0508.
+
+ //--------------------------- shorthands - also set up by CocoaMgr - driven by vendorid / deviceid
+
+ bool m_ati;
+ bool m_atiR5xx;
+ bool m_atiR6xx;
+ bool m_atiR7xx;
+ bool m_atiR8xx;
+ bool m_atiNewer;
+
+ bool m_intel;
+ bool m_intel95x;
+ bool m_intel3100;
+ bool m_intelNewer;
+
+ bool m_nv;
+ bool m_nvG7x;
+ bool m_nvG8x;
+ bool m_nvNewer;
+
+ //--------------------------- context query results - left blank in the display DB - but valid in a GLMContext (call ctx->Caps() to get a const ref)
+
+ // booleans
+ bool m_hasGammaWrites; // aka glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) / glEnable(GL_FRAMEBUFFER_SRGB_EXT)
+ bool m_hasMixedAttachmentSizes; // aka ARB_fbo in 10.6.3 - test for min OS vers, then exported ext string
+ bool m_hasBGRA; // aka GL_BGRA vertex attribs in 10.6.3 - - test for min OS vers, then exported ext string
+ bool m_hasNewFullscreenMode; // aka 10.6.x "big window" fullscreen mode
+ bool m_hasNativeClipVertexMode; // aka GLSL gl_ClipVertex does not fall back to SW- OS version and folklore-based
+ bool m_hasOcclusionQuery; // occlusion query: do you speak it ?!
+ bool m_hasFramebufferBlit; // framebuffer blit: know what I'm sayin?!
+ bool m_hasPerfPackage1; // means new MTGL, fast OQ, fast uniform upload, NV can resolve flipped (late summer 2010 post 10.6.4 update)
+
+ // counts
+ int m_maxAniso; // aniso limit - context query
+
+ // other exts
+ bool m_hasBindableUniforms;
+ int m_maxVertexBindableUniforms;
+ int m_maxFragmentBindableUniforms;
+ int m_maxBindableUniformSize;
+
+ bool m_hasUniformBuffers;
+
+ // runtime options that aren't negotiable once set
+ bool m_hasDualShaders; // must supply CLI arg "-glmdualshaders" or we go GLSL only
+
+ //--------------------------- " can'ts " - specific problems that need to be worked around
+
+ bool m_cantBlitReliably; // Intel chipsets have problems blitting sRGB sometimes
+ bool m_cantAttachSRGB; // NV G8x on 10.5.8 can't have srgb tex on FBO color - separate issue from hasGammaWrites
+ bool m_cantResolveFlipped; // happens on NV in 10.6.4 and prior - console variable "gl_can_resolve_flipped" can overrule
+ bool m_cantResolveScaled; // happens everywhere per GL spec but may be relaxed some day - console variable "gl_can_resolve_scaled" can overrule
+ bool m_costlyGammaFlips; // this means that sRGB sampling state affects shader code gen, resulting in state-dependent code regen
+
+
+ //--------------------------- " bads " - known bad drivers
+ bool m_badDriver1064NV; // this is the bad NVIDIA driver on 10.6.4 - stutter, tex corruption, black screen issues
+};
+
+
+
+#endif
diff --git a/mp/src/public/togl/linuxwin/glmdisplaydb.h b/mp/src/public/togl/linuxwin/glmdisplaydb.h new file mode 100644 index 00000000..7f78f910 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmdisplaydb.h @@ -0,0 +1,92 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef GLMDISPLAYDB_H
+#define GLMDISPLAYDB_H
+
+#include "tier1/utlvector.h"
+
+//===============================================================================
+// modes, displays, and renderers
+//===============================================================================
+
+// GLMDisplayModeInfoFields is in glmdisplay.h
+
+class GLMDisplayMode
+{
+public:
+ GLMDisplayModeInfoFields m_info;
+
+ GLMDisplayMode( uint width, uint height, uint refreshHz );
+ GLMDisplayMode() { };
+ ~GLMDisplayMode( void );
+
+ void Init( uint width, uint height, uint refreshHz );
+ void Dump( int which );
+};
+
+//===============================================================================
+
+// GLMDisplayInfoFields is in glmdisplay.h
+
+class GLMDisplayInfo
+{
+public:
+ GLMDisplayInfoFields m_info;
+ CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes
+
+ GLMDisplayInfo( void );
+ ~GLMDisplayInfo( void );
+
+ void PopulateModes( void );
+
+ void Dump( int which );
+};
+
+//===============================================================================
+
+// GLMRendererInfoFields is in glmdisplay.h
+
+class GLMRendererInfo
+{
+public:
+ GLMRendererInfoFields m_info;
+ GLMDisplayInfo *m_display;
+
+ GLMRendererInfo ();
+ ~GLMRendererInfo ( void );
+
+ void Init( GLMRendererInfoFields *info );
+ void PopulateDisplays();
+ void Dump( int which );
+};
+
+//===============================================================================
+
+class GLMDisplayDB
+{
+public:
+ GLMRendererInfo m_renderer;
+
+ GLMDisplayDB ( void );
+ ~GLMDisplayDB ( void );
+
+ virtual void PopulateRenderers( void );
+ virtual void PopulateFakeAdapters( uint realRendererIndex ); // fake adapters = one real adapter times however many displays are on it
+ virtual void Populate( void );
+
+ // The info-get functions return false on success.
+ virtual int GetFakeAdapterCount( void );
+ virtual bool GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut );
+
+ virtual int GetRendererCount( void );
+ virtual bool GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut );
+
+ virtual int GetDisplayCount( int rendererIndex );
+ virtual bool GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut );
+
+ virtual int GetModeCount( int rendererIndex, int displayIndex );
+ virtual bool GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut );
+
+ virtual void Dump( void );
+};
+
+#endif // GLMDISPLAYDB_H
diff --git a/mp/src/public/togl/linuxwin/glmgr.h b/mp/src/public/togl/linuxwin/glmgr.h new file mode 100644 index 00000000..cc828636 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmgr.h @@ -0,0 +1,2259 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgr.h
+// singleton class, common basis for managing GL contexts
+// responsible for tracking adapters and contexts
+//
+//===============================================================================
+
+#ifndef GLMGR_H
+#define GLMGR_H
+
+#pragma once
+
+#include "glbase.h"
+#include "glentrypoints.h"
+#include "glmdebug.h"
+#include "glmdisplay.h"
+#include "glmgrext.h"
+#include "glmgrbasics.h"
+#include "cglmtex.h"
+#include "cglmfbo.h"
+#include "cglmprogram.h"
+#include "cglmbuffer.h"
+#include "cglmquery.h"
+
+#include "tier0/vprof_telemetry.h"
+#include "materialsystem/IShader.h"
+#include "dxabstract_types.h"
+#include "tier0/icommandline.h"
+
+//===============================================================================
+
+#define GLM_OPENGL_VENDOR_ID 1
+#define GLM_OPENGL_DEFAULT_DEVICE_ID 1
+#define GLM_OPENGL_LOW_PERF_DEVICE_ID 2
+
+extern void GLMDebugPrintf( const char *pMsg, ... );
+
+extern uint g_nTotalDrawsOrClears, g_nTotalVBLockBytes, g_nTotalIBLockBytes;
+
+#if GL_TELEMETRY_GPU_ZONES
+struct TelemetryGPUStats_t
+{
+ uint m_nTotalBufferLocksAndUnlocks;
+ uint m_nTotalTexLocksAndUnlocks;
+ uint m_nTotalBlit2;
+ uint m_nTotalResolveTex;
+ uint m_nTotalPresent;
+
+ inline void Clear() { memset( this, 0, sizeof( *this ) ); }
+ inline uint GetTotal() const { return m_nTotalBufferLocksAndUnlocks + m_nTotalTexLocksAndUnlocks + m_nTotalBlit2 + m_nTotalResolveTex + m_nTotalPresent; }
+};
+extern TelemetryGPUStats_t g_TelemetryGPUStats;
+#endif
+
+struct GLMRect;
+typedef void *PseudoGLContextPtr;
+
+// parrot the D3D present parameters, more or less... "adapter" translates into "active display index" per the m_activeDisplayCount below.
+class GLMDisplayParams
+{
+ public:
+
+ // presumption, these indices are in sync with the current display DB that GLMgr has handy
+ //int m_rendererIndex; // index of renderer (-1 if root context)
+ //int m_displayIndex; // index of display in renderer - for FS
+ //int m_modeIndex; // index of mode in display - for FS
+
+ void *m_focusWindow; // (VD3DHWND aka WindowRef) - what window does this context display into
+
+ bool m_fsEnable; // fullscreen on or not
+ bool m_vsyncEnable; // vsync on or not
+
+ // height and width have to match the display mode info if full screen.
+
+ uint m_backBufferWidth; // pixel width (aka screen h-resolution if full screen)
+ uint m_backBufferHeight; // pixel height (aka screen v-resolution if full screen)
+ D3DFORMAT m_backBufferFormat; // pixel format
+ uint m_multiSampleCount; // 0 means no MSAA, 2 means 2x MSAA, etc
+ // uint m_multiSampleQuality; // no MSAA quality control yet
+
+ bool m_enableAutoDepthStencil; // generally set to 'TRUE' per CShaderDeviceDx8::SetPresentParameters
+ D3DFORMAT m_autoDepthStencilFormat;
+
+ uint m_fsRefreshHz; // if full screen, this refresh rate (likely 0 for LCD's)
+
+ //uint m_rootRendererID; // only used if m_rendererIndex is -1.
+ //uint m_rootDisplayMask; // only used if m_rendererIndex is -1.
+
+ bool m_mtgl; // enable multi threaded GL driver
+};
+
+//===============================================================================
+
+class GLMgr
+{
+public:
+
+ //===========================================================================
+ // class methods - singleton
+ static void NewGLMgr( void ); // instantiate singleton..
+ static GLMgr *aGLMgr( void ); // return singleton..
+ static void DelGLMgr( void ); // tear down singleton..
+
+ //===========================================================================
+ // plain methods
+
+ #if 0 // turned all these off while new approach is coded
+ void RefreshDisplayDB( void ); // blow away old display DB, make a new one
+ GLMDisplayDB *GetDisplayDB( void ); // get a ptr to the one GLMgr keeps. only valid til next refresh.
+
+ // eligible renderers will be ranked by desirability starting at index 0 within the db
+ // within each renderer, eligible displays will be ranked some kind of desirability (area? dist from menu bar?)
+ // within each display, eligible modes will be ranked by descending areas
+
+ // calls supplying indices are implicitly making reference to the current DB
+ bool CaptureDisplay( int rendIndex, int displayIndex, bool captureAll ); // capture one display or all displays
+ void ReleaseDisplays( void ); // release all captures
+
+ int GetDisplayMode( int rendIndex, int displayIndex ); // retrieve current display res (returns modeIndex)
+ void SetDisplayMode( GLMDisplayParams *params ); // set the display res (only useful for FS)
+ #endif
+
+ GLMContext *NewContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params ); // this will have to change
+ void DelContext( GLMContext *context );
+
+ // with usage of CGLMacro.h we could dispense with the "current context" thing
+ // and just declare a member variable of GLMContext, allowing each glXXX call to be routed directly
+ // to the correct context
+ void SetCurrentContext( GLMContext *context ); // make current in calling thread only
+ GLMContext *GetCurrentContext( void );
+
+protected:
+ friend class GLMContext;
+
+ GLMgr();
+ ~GLMgr();
+};
+
+
+//===========================================================================//
+
+// helper function to do enable or disable in one step
+FORCEINLINE void glSetEnable( GLenum which, bool enable )
+{
+ if (enable)
+ gGL->glEnable(which);
+ else
+ gGL->glDisable(which);
+}
+
+// helper function for int vs enum clarity
+FORCEINLINE void glGetEnumv( GLenum which, GLenum *dst )
+{
+ gGL->glGetIntegerv( which, (int*)dst );
+}
+
+//===========================================================================//
+//
+// types to support the GLMContext
+//
+//===========================================================================//
+
+// Each state set/get path we are providing caching for, needs its own struct and a comparison operator.
+// we also provide an enum of how many such types there are, handy for building dirty masks etc.
+
+// shorthand macros
+#define EQ(fff) ( (src.fff) == (fff) )
+
+//rasterizer
+struct GLAlphaTestEnable_t { GLint enable; inline bool operator==(const GLAlphaTestEnable_t& src) const { return EQ(enable); } };
+struct GLAlphaTestFunc_t { GLenum func; GLclampf ref; inline bool operator==(const GLAlphaTestFunc_t& src) const { return EQ(func) && EQ(ref); } };
+struct GLCullFaceEnable_t { GLint enable; inline bool operator==(const GLCullFaceEnable_t& src) const { return EQ(enable); } };
+struct GLCullFrontFace_t { GLenum value; inline bool operator==(const GLCullFrontFace_t& src) const { return EQ(value); } };
+struct GLPolygonMode_t { GLenum values[2]; inline bool operator==(const GLPolygonMode_t& src) const { return EQ(values[0]) && EQ(values[1]); } };
+struct GLDepthBias_t { GLfloat factor; GLfloat units; inline bool operator==(const GLDepthBias_t& src) const { return EQ(factor) && EQ(units); } };
+struct GLScissorEnable_t { GLint enable; inline bool operator==(const GLScissorEnable_t& src) const { return EQ(enable); } };
+struct GLScissorBox_t { GLint x,y; GLsizei width, height; inline bool operator==(const GLScissorBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } };
+struct GLAlphaToCoverageEnable_t{ GLint enable; inline bool operator==(const GLAlphaToCoverageEnable_t& src) const { return EQ(enable); } };
+struct GLViewportBox_t { GLint x,y; GLsizei width, height; uint widthheight; inline bool operator==(const GLViewportBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } };
+struct GLViewportDepthRange_t { GLdouble flNear,flFar; inline bool operator==(const GLViewportDepthRange_t& src) const { return EQ(flNear) && EQ(flFar); } };
+struct GLClipPlaneEnable_t { GLint enable; inline bool operator==(const GLClipPlaneEnable_t& src) const { return EQ(enable); } };
+struct GLClipPlaneEquation_t { GLfloat x,y,z,w; inline bool operator==(const GLClipPlaneEquation_t& src) const { return EQ(x) && EQ(y) && EQ(z) && EQ(w); } };
+
+//blend
+struct GLColorMaskSingle_t { char r,g,b,a; inline bool operator==(const GLColorMaskSingle_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLColorMaskMultiple_t { char r,g,b,a; inline bool operator==(const GLColorMaskMultiple_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLBlendEnable_t { GLint enable; inline bool operator==(const GLBlendEnable_t& src) const { return EQ(enable); } };
+struct GLBlendFactor_t { GLenum srcfactor,dstfactor; inline bool operator==(const GLBlendFactor_t& src) const { return EQ(srcfactor) && EQ(dstfactor); } };
+struct GLBlendEquation_t { GLenum equation; inline bool operator==(const GLBlendEquation_t& src) const { return EQ(equation); } };
+struct GLBlendColor_t { GLfloat r,g,b,a; inline bool operator==(const GLBlendColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLBlendEnableSRGB_t { GLint enable; inline bool operator==(const GLBlendEnableSRGB_t& src) const { return EQ(enable); } };
+
+//depth
+struct GLDepthTestEnable_t { GLint enable; inline bool operator==(const GLDepthTestEnable_t& src) const { return EQ(enable); } };
+struct GLDepthFunc_t { GLenum func; inline bool operator==(const GLDepthFunc_t& src) const { return EQ(func); } };
+struct GLDepthMask_t { char mask; inline bool operator==(const GLDepthMask_t& src) const { return EQ(mask); } };
+
+//stencil
+struct GLStencilTestEnable_t { GLint enable; inline bool operator==(const GLStencilTestEnable_t& src) const { return EQ(enable); } };
+struct GLStencilFunc_t { GLenum frontfunc, backfunc; GLint ref; GLuint mask; inline bool operator==(const GLStencilFunc_t& src) const { return EQ(frontfunc) && EQ(backfunc) && EQ(ref) && EQ(mask); } };
+struct GLStencilOp_t { GLenum sfail; GLenum dpfail; GLenum dppass; inline bool operator==(const GLStencilOp_t& src) const { return EQ(sfail) && EQ(dpfail) && EQ(dppass); } };
+struct GLStencilWriteMask_t { GLint mask; inline bool operator==(const GLStencilWriteMask_t& src) const { return EQ(mask); } };
+
+//clearing
+struct GLClearColor_t { GLfloat r,g,b,a; inline bool operator==(const GLClearColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLClearDepth_t { GLdouble d; inline bool operator==(const GLClearDepth_t& src) const { return EQ(d); } };
+struct GLClearStencil_t { GLint s; inline bool operator==(const GLClearStencil_t& src) const { return EQ(s); } };
+
+#undef EQ
+
+enum EGLMStateBlockType
+{
+ kGLAlphaTestEnable,
+ kGLAlphaTestFunc,
+
+ kGLCullFaceEnable,
+ kGLCullFrontFace,
+
+ kGLPolygonMode,
+
+ kGLDepthBias,
+
+ kGLScissorEnable,
+ kGLScissorBox,
+
+ kGLViewportBox,
+ kGLViewportDepthRange,
+
+ kGLClipPlaneEnable,
+ kGLClipPlaneEquation,
+
+ kGLColorMaskSingle,
+ kGLColorMaskMultiple,
+
+ kGLBlendEnable,
+ kGLBlendFactor,
+ kGLBlendEquation,
+ kGLBlendColor,
+ kGLBlendEnableSRGB,
+
+ kGLDepthTestEnable,
+ kGLDepthFunc,
+ kGLDepthMask,
+
+ kGLStencilTestEnable,
+ kGLStencilFunc,
+ kGLStencilOp,
+ kGLStencilWriteMask,
+
+ kGLClearColor,
+ kGLClearDepth,
+ kGLClearStencil,
+
+ kGLAlphaToCoverageEnable,
+
+ kGLMStateBlockLimit
+};
+
+//===========================================================================//
+
+// templated functions representing GL R/W bottlenecks
+// one set of set/get/getdefault is instantiated for each of the GL*** types above.
+
+// use these from the non array state objects
+template<typename T> void GLContextSet( T *src );
+template<typename T> void GLContextGet( T *dst );
+template<typename T> void GLContextGetDefault( T *dst );
+
+// use these from the array state objects
+template<typename T> void GLContextSetIndexed( T *src, int index );
+template<typename T> void GLContextGetIndexed( T *dst, int index );
+template<typename T> void GLContextGetDefaultIndexed( T *dst, int index );
+
+//===============================================================================
+// template specializations for each type of state
+
+// --- GLAlphaTestEnable ---
+FORCEINLINE void GLContextSet( GLAlphaTestEnable_t *src )
+{
+ glSetEnable( GL_ALPHA_TEST, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLAlphaTestEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_ALPHA_TEST );
+}
+
+FORCEINLINE void GLContextGetDefault( GLAlphaTestEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+// --- GLAlphaTestFunc ---
+FORCEINLINE void GLContextSet( GLAlphaTestFunc_t *src )
+{
+ gGL->glAlphaFunc( src->func, src->ref );
+}
+
+FORCEINLINE void GLContextGet( GLAlphaTestFunc_t *dst )
+{
+ glGetEnumv( GL_ALPHA_TEST_FUNC, &dst->func );
+ gGL->glGetFloatv( GL_ALPHA_TEST_REF, &dst->ref );
+}
+
+FORCEINLINE void GLContextGetDefault( GLAlphaTestFunc_t *dst )
+{
+ dst->func = GL_ALWAYS;
+ dst->ref = 0.0f;
+}
+
+// --- GLAlphaToCoverageEnable ---
+FORCEINLINE void GLContextSet( GLAlphaToCoverageEnable_t *src )
+{
+ glSetEnable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLAlphaToCoverageEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
+}
+
+FORCEINLINE void GLContextGetDefault( GLAlphaToCoverageEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+// --- GLCullFaceEnable ---
+FORCEINLINE void GLContextSet( GLCullFaceEnable_t *src )
+{
+ glSetEnable( GL_CULL_FACE, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLCullFaceEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_CULL_FACE );
+}
+
+FORCEINLINE void GLContextGetDefault( GLCullFaceEnable_t *dst )
+{
+ dst->enable = GL_TRUE;
+}
+
+
+// --- GLCullFrontFace ---
+FORCEINLINE void GLContextSet( GLCullFrontFace_t *src )
+{
+ gGL->glFrontFace( src->value ); // legal values are GL_CW or GL_CCW
+}
+
+FORCEINLINE void GLContextGet( GLCullFrontFace_t *dst )
+{
+ glGetEnumv( GL_FRONT_FACE, &dst->value );
+}
+
+FORCEINLINE void GLContextGetDefault( GLCullFrontFace_t *dst )
+{
+ dst->value = GL_CCW;
+}
+
+
+// --- GLPolygonMode ---
+FORCEINLINE void GLContextSet( GLPolygonMode_t *src )
+{
+ gGL->glPolygonMode( GL_FRONT, src->values[0] );
+ gGL->glPolygonMode( GL_BACK, src->values[1] );
+}
+
+FORCEINLINE void GLContextGet( GLPolygonMode_t *dst )
+{
+ glGetEnumv( GL_POLYGON_MODE, &dst->values[0] );
+
+}
+
+FORCEINLINE void GLContextGetDefault( GLPolygonMode_t *dst )
+{
+ dst->values[0] = dst->values[1] = GL_FILL;
+}
+
+
+// --- GLDepthBias ---
+// note the implicit enable / disable.
+// if you set non zero values, it is enabled, otherwise not.
+FORCEINLINE void GLContextSet( GLDepthBias_t *src )
+{
+ bool enable = (src->factor != 0.0f) || (src->units != 0.0f);
+
+ glSetEnable( GL_POLYGON_OFFSET_FILL, enable );
+ gGL->glPolygonOffset( src->factor, src->units );
+}
+
+FORCEINLINE void GLContextGet( GLDepthBias_t *dst )
+{
+ gGL->glGetFloatv ( GL_POLYGON_OFFSET_FACTOR, &dst->factor );
+ gGL->glGetFloatv ( GL_POLYGON_OFFSET_UNITS, &dst->units );
+}
+
+FORCEINLINE void GLContextGetDefault( GLDepthBias_t *dst )
+{
+ dst->factor = 0.0;
+ dst->units = 0.0;
+}
+
+
+// --- GLScissorEnable ---
+FORCEINLINE void GLContextSet( GLScissorEnable_t *src )
+{
+ glSetEnable( GL_SCISSOR_TEST, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLScissorEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_SCISSOR_TEST );
+}
+
+FORCEINLINE void GLContextGetDefault( GLScissorEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+
+// --- GLScissorBox ---
+FORCEINLINE void GLContextSet( GLScissorBox_t *src )
+{
+ gGL->glScissor ( src->x, src->y, src->width, src->height );
+}
+
+FORCEINLINE void GLContextGet( GLScissorBox_t *dst )
+{
+ gGL->glGetIntegerv ( GL_SCISSOR_BOX, &dst->x );
+}
+
+FORCEINLINE void GLContextGetDefault( GLScissorBox_t *dst )
+{
+ // hmmmm, good question? we can't really know a good answer so we pick a silly one
+ // and the client better come back with a better answer later.
+ dst->x = dst->y = 0;
+ dst->width = dst->height = 16;
+}
+
+
+// --- GLViewportBox ---
+
+FORCEINLINE void GLContextSet( GLViewportBox_t *src )
+{
+ Assert( src->width == (int)( src->widthheight & 0xFFFF ) );
+ Assert( src->height == (int)( src->widthheight >> 16 ) );
+ gGL->glViewport (src->x, src->y, src->width, src->height );
+}
+
+FORCEINLINE void GLContextGet( GLViewportBox_t *dst )
+{
+ gGL->glGetIntegerv ( GL_VIEWPORT, &dst->x );
+ dst->widthheight = dst->width | ( dst->height << 16 );
+}
+
+FORCEINLINE void GLContextGetDefault( GLViewportBox_t *dst )
+{
+ // as with the scissor box, we don't know yet, so pick a silly one and change it later
+ dst->x = dst->y = 0;
+ dst->width = dst->height = 16;
+ dst->widthheight = dst->width | ( dst->height << 16 );
+}
+
+
+// --- GLViewportDepthRange ---
+FORCEINLINE void GLContextSet( GLViewportDepthRange_t *src )
+{
+ gGL->glDepthRange ( src->flNear, src->flFar );
+}
+
+FORCEINLINE void GLContextGet( GLViewportDepthRange_t *dst )
+{
+ gGL->glGetDoublev ( GL_DEPTH_RANGE, &dst->flNear );
+}
+
+FORCEINLINE void GLContextGetDefault( GLViewportDepthRange_t *dst )
+{
+ dst->flNear = 0.0;
+ dst->flFar = 1.0;
+}
+
+// --- GLClipPlaneEnable ---
+FORCEINLINE void GLContextSetIndexed( GLClipPlaneEnable_t *src, int index )
+{
+#if GLMDEBUG
+ if (CommandLine()->FindParm("-caps_noclipplanes"))
+ {
+ if (GLMKnob("caps-key",NULL) > 0.0)
+ {
+ // caps ON means NO clipping
+ src->enable = false;
+ }
+ }
+#endif
+ glSetEnable( GL_CLIP_PLANE0 + index, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGetIndexed( GLClipPlaneEnable_t *dst, int index )
+{
+ dst->enable = gGL->glIsEnabled( GL_CLIP_PLANE0 + index );
+}
+
+FORCEINLINE void GLContextGetDefaultIndexed( GLClipPlaneEnable_t *dst, int index )
+{
+ dst->enable = 0;
+}
+
+
+
+// --- GLClipPlaneEquation ---
+FORCEINLINE void GLContextSetIndexed( GLClipPlaneEquation_t *src, int index )
+{
+ // shove into glGlipPlane
+ GLdouble coeffs[4] = { src->x, src->y, src->z, src->w };
+
+ gGL->glClipPlane( GL_CLIP_PLANE0 + index, coeffs );
+}
+
+FORCEINLINE void GLContextGetIndexed( GLClipPlaneEquation_t *dst, int index )
+{
+ DebuggerBreak(); // do this later
+ // glClipPlane( GL_CLIP_PLANE0 + index, coeffs );
+ // GLdouble coeffs[4] = { src->x, src->y, src->z, src->w };
+}
+
+FORCEINLINE void GLContextGetDefaultIndexed( GLClipPlaneEquation_t *dst, int index )
+{
+ dst->x = 1.0;
+ dst->y = 0.0;
+ dst->z = 0.0;
+ dst->w = 0.0;
+}
+
+
+// --- GLColorMaskSingle ---
+FORCEINLINE void GLContextSet( GLColorMaskSingle_t *src )
+{
+ gGL->glColorMask( src->r, src->g, src->b, src->a );
+}
+
+FORCEINLINE void GLContextGet( GLColorMaskSingle_t *dst )
+{
+ gGL->glGetBooleanv( GL_COLOR_WRITEMASK, (GLboolean*)&dst->r);
+}
+
+FORCEINLINE void GLContextGetDefault( GLColorMaskSingle_t *dst )
+{
+ dst->r = dst->g = dst->b = dst->a = 1;
+}
+
+
+// --- GLColorMaskMultiple ---
+FORCEINLINE void GLContextSetIndexed( GLColorMaskMultiple_t *src, int index )
+{
+ gGL->glColorMaskIndexedEXT ( index, src->r, src->g, src->b, src->a );
+}
+
+FORCEINLINE void GLContextGetIndexed( GLColorMaskMultiple_t *dst, int index )
+{
+ gGL->glGetBooleanIndexedvEXT ( GL_COLOR_WRITEMASK, index, (GLboolean*)&dst->r );
+}
+
+FORCEINLINE void GLContextGetDefaultIndexed( GLColorMaskMultiple_t *dst, int index )
+{
+ dst->r = dst->g = dst->b = dst->a = 1;
+}
+
+
+// --- GLBlendEnable ---
+FORCEINLINE void GLContextSet( GLBlendEnable_t *src )
+{
+ glSetEnable( GL_BLEND, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLBlendEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_BLEND );
+}
+
+FORCEINLINE void GLContextGetDefault( GLBlendEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+
+// --- GLBlendFactor ---
+FORCEINLINE void GLContextSet( GLBlendFactor_t *src )
+{
+ gGL->glBlendFunc ( src->srcfactor, src->dstfactor );
+}
+
+FORCEINLINE void GLContextGet( GLBlendFactor_t *dst )
+{
+ glGetEnumv ( GL_BLEND_SRC, &dst->srcfactor );
+ glGetEnumv ( GL_BLEND_DST, &dst->dstfactor );
+}
+
+FORCEINLINE void GLContextGetDefault( GLBlendFactor_t *dst )
+{
+ dst->srcfactor = GL_ONE;
+ dst->dstfactor = GL_ZERO;
+}
+
+
+// --- GLBlendEquation ---
+FORCEINLINE void GLContextSet( GLBlendEquation_t *src )
+{
+ gGL->glBlendEquation ( src->equation );
+}
+
+FORCEINLINE void GLContextGet( GLBlendEquation_t *dst )
+{
+ glGetEnumv ( GL_BLEND_EQUATION, &dst->equation );
+}
+
+FORCEINLINE void GLContextGetDefault( GLBlendEquation_t *dst )
+{
+ dst->equation = GL_FUNC_ADD;
+}
+
+
+// --- GLBlendColor ---
+FORCEINLINE void GLContextSet( GLBlendColor_t *src )
+{
+ gGL->glBlendColor ( src->r, src->g, src->b, src->a );
+}
+
+FORCEINLINE void GLContextGet( GLBlendColor_t *dst )
+{
+ gGL->glGetFloatv ( GL_BLEND_COLOR, &dst->r );
+}
+
+FORCEINLINE void GLContextGetDefault( GLBlendColor_t *dst )
+{
+ //solid white
+ dst->r = dst->g = dst->b = dst->a = 1.0;
+}
+
+
+// --- GLBlendEnableSRGB ---
+
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+
+FORCEINLINE void GLContextSet( GLBlendEnableSRGB_t *src )
+{
+#if GLMDEBUG
+ // just check in debug... this is too expensive to look at on MTGL
+ if (src->enable)
+ {
+ GLboolean srgb_capable = false;
+ gGL->glGetBooleanv( GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable);
+
+ if (src->enable && !srgb_capable)
+ {
+ GLMPRINTF(("-Z- srgb-state-set FBO conflict: attempt to enable SRGB on non SRGB capable FBO config"));
+ }
+ }
+#endif
+ // this query is not useful unless you have the ARB_framebuffer_srgb ext.
+ //GLint encoding = 0;
+ //pfnglGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding );
+
+ glSetEnable( GL_FRAMEBUFFER_SRGB_EXT, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLBlendEnableSRGB_t *dst )
+{
+ //dst->enable = glIsEnabled( GL_FRAMEBUFFER_SRGB_EXT );
+ dst->enable = true; // wtf ?
+}
+
+FORCEINLINE void GLContextGetDefault( GLBlendEnableSRGB_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+
+// --- GLDepthTestEnable ---
+FORCEINLINE void GLContextSet( GLDepthTestEnable_t *src )
+{
+ glSetEnable( GL_DEPTH_TEST, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLDepthTestEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_DEPTH_TEST );
+}
+
+FORCEINLINE void GLContextGetDefault( GLDepthTestEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+
+// --- GLDepthFunc ---
+FORCEINLINE void GLContextSet( GLDepthFunc_t *src )
+{
+ gGL->glDepthFunc ( src->func );
+}
+
+FORCEINLINE void GLContextGet( GLDepthFunc_t *dst )
+{
+ glGetEnumv ( GL_DEPTH_FUNC, &dst->func );
+}
+
+FORCEINLINE void GLContextGetDefault( GLDepthFunc_t *dst )
+{
+ dst->func = GL_GEQUAL;
+}
+
+
+// --- GLDepthMask ---
+FORCEINLINE void GLContextSet( GLDepthMask_t *src )
+{
+ gGL->glDepthMask ( src->mask );
+}
+
+FORCEINLINE void GLContextGet( GLDepthMask_t *dst )
+{
+ gGL->glGetBooleanv ( GL_DEPTH_WRITEMASK, (GLboolean*)&dst->mask );
+}
+
+FORCEINLINE void GLContextGetDefault( GLDepthMask_t *dst )
+{
+ dst->mask = GL_TRUE;
+}
+
+
+// --- GLStencilTestEnable ---
+FORCEINLINE void GLContextSet( GLStencilTestEnable_t *src )
+{
+ glSetEnable( GL_STENCIL_TEST, src->enable != 0 );
+}
+
+FORCEINLINE void GLContextGet( GLStencilTestEnable_t *dst )
+{
+ dst->enable = gGL->glIsEnabled( GL_STENCIL_TEST );
+}
+
+FORCEINLINE void GLContextGetDefault( GLStencilTestEnable_t *dst )
+{
+ dst->enable = GL_FALSE;
+}
+
+
+// --- GLStencilFunc ---
+FORCEINLINE void GLContextSet( GLStencilFunc_t *src )
+{
+ if (src->frontfunc == src->backfunc)
+ gGL->glStencilFuncSeparate( GL_FRONT_AND_BACK, src->frontfunc, src->ref, src->mask);
+ else
+ {
+ gGL->glStencilFuncSeparate( GL_FRONT, src->frontfunc, src->ref, src->mask);
+ gGL->glStencilFuncSeparate( GL_BACK, src->backfunc, src->ref, src->mask);
+ }
+}
+
+FORCEINLINE void GLContextGet( GLStencilFunc_t *dst )
+{
+ glGetEnumv ( GL_STENCIL_FUNC, &dst->frontfunc );
+ glGetEnumv ( GL_STENCIL_BACK_FUNC, &dst->backfunc );
+ gGL->glGetIntegerv ( GL_STENCIL_REF, &dst->ref );
+ gGL->glGetIntegerv ( GL_STENCIL_VALUE_MASK, (GLint*)&dst->mask );
+}
+
+FORCEINLINE void GLContextGetDefault( GLStencilFunc_t *dst )
+{
+ dst->frontfunc = GL_ALWAYS;
+ dst->backfunc = GL_ALWAYS;
+ dst->ref = 0;
+ dst->mask = 0xFFFFFFFF;
+}
+
+
+// --- GLStencilOp --- indexed 0=front, 1=back
+
+FORCEINLINE void GLContextSetIndexed( GLStencilOp_t *src, int index )
+{
+ GLenum face = (index==0) ? GL_FRONT : GL_BACK;
+ gGL->glStencilOpSeparate( face, src->sfail, src->dpfail, src->dppass );
+}
+
+FORCEINLINE void GLContextGetIndexed( GLStencilOp_t *dst, int index )
+{
+ glGetEnumv ( (index==0) ? GL_STENCIL_FAIL : GL_STENCIL_BACK_FAIL, &dst->sfail );
+ glGetEnumv ( (index==0) ? GL_STENCIL_PASS_DEPTH_FAIL : GL_STENCIL_BACK_PASS_DEPTH_FAIL, &dst->dpfail );
+ glGetEnumv ( (index==0) ? GL_STENCIL_PASS_DEPTH_PASS : GL_STENCIL_BACK_PASS_DEPTH_PASS, &dst->dppass );
+}
+
+FORCEINLINE void GLContextGetDefaultIndexed( GLStencilOp_t *dst, int index )
+{
+ dst->sfail = dst->dpfail = dst->dppass = GL_KEEP;
+}
+
+
+// --- GLStencilWriteMask ---
+FORCEINLINE void GLContextSet( GLStencilWriteMask_t *src )
+{
+ gGL->glStencilMask( src->mask );
+}
+
+FORCEINLINE void GLContextGet( GLStencilWriteMask_t *dst )
+{
+ gGL->glGetIntegerv ( GL_STENCIL_WRITEMASK, &dst->mask );
+}
+
+FORCEINLINE void GLContextGetDefault( GLStencilWriteMask_t *dst )
+{
+ dst->mask = 0xFFFFFFFF;
+}
+
+
+// --- GLClearColor ---
+FORCEINLINE void GLContextSet( GLClearColor_t *src )
+{
+ gGL->glClearColor( src->r, src->g, src->b, src->a );
+}
+
+FORCEINLINE void GLContextGet( GLClearColor_t *dst )
+{
+ gGL->glGetFloatv ( GL_COLOR_CLEAR_VALUE, &dst->r );
+}
+
+FORCEINLINE void GLContextGetDefault( GLClearColor_t *dst )
+{
+ dst->r = dst->g = dst->b = 0.5;
+ dst->a = 1.0;
+}
+
+
+// --- GLClearDepth ---
+FORCEINLINE void GLContextSet( GLClearDepth_t *src )
+{
+ gGL->glClearDepth ( src->d );
+}
+
+FORCEINLINE void GLContextGet( GLClearDepth_t *dst )
+{
+ gGL->glGetDoublev ( GL_DEPTH_CLEAR_VALUE, &dst->d );
+}
+
+FORCEINLINE void GLContextGetDefault( GLClearDepth_t *dst )
+{
+ dst->d = 1.0;
+}
+
+
+// --- GLClearStencil ---
+FORCEINLINE void GLContextSet( GLClearStencil_t *src )
+{
+ gGL->glClearStencil( src->s );
+}
+
+FORCEINLINE void GLContextGet( GLClearStencil_t *dst )
+{
+ gGL->glGetIntegerv ( GL_STENCIL_CLEAR_VALUE, &dst->s );
+}
+
+FORCEINLINE void GLContextGetDefault( GLClearStencil_t *dst )
+{
+ dst->s = 0;
+}
+
+//===========================================================================//
+
+// caching state object template. One of these is instantiated in the context per unique struct type above
+template<typename T> class GLState
+{
+ public:
+ inline GLState()
+ {
+ memset( &data, 0, sizeof(data) );
+ Default();
+ }
+
+ FORCEINLINE void Flush()
+ {
+ // immediately blast out the state - it makes no sense to delta it or do anything fancy because shaderapi, dxabstract, and OpenGL itself does this for us (and OpenGL calls with multithreaded drivers are very cheap)
+ GLContextSet( &data );
+ }
+
+ // write: client src into cache
+ // common case is both false. dirty is calculated, context write is deferred.
+ FORCEINLINE void Write( const T *src )
+ {
+ data = *src;
+ Flush();
+ }
+
+ // default: write default value to cache, optionally write through
+ inline void Default( bool noDefer=false )
+ {
+ GLContextGetDefault( &data ); // read default values directly to our cache copy
+ Flush();
+ }
+
+ // read: sel = 0 for cache, 1 for context
+ inline void Read( T *dst, int sel )
+ {
+ if (sel==0)
+ *dst = data;
+ else
+ GLContextGet( dst );
+ }
+
+ // check: verify that context equals cache, return true if mismatched or if illegal values seen
+ inline bool Check ( void )
+ {
+ T temp;
+ bool result;
+
+ GLContextGet( &temp );
+ result = !(temp == data);
+ return result;
+ }
+
+ FORCEINLINE const T &GetData() const { return data; }
+
+ protected:
+ T data;
+};
+
+// caching state object template - with multiple values behind it that are indexed
+template<typename T, int COUNT> class GLStateArray
+{
+ public:
+ inline GLStateArray()
+ {
+ memset( &data, 0, sizeof(data) );
+ Default();
+ }
+
+ // write cache->context if dirty or forced.
+ FORCEINLINE void FlushIndex( int index )
+ {
+ // immediately blast out the state - it makes no sense to delta it or do anything fancy because shaderapi, dxabstract, and OpenGL itself does this for us (and OpenGL calls with multithreaded drivers are very cheap)
+ GLContextSetIndexed( &data[index], index );
+ };
+
+ // write: client src into cache
+ // common case is both false. dirty is calculated, context write is deferred.
+ FORCEINLINE void WriteIndex( T *src, int index )
+ {
+ data[index] = *src;
+ FlushIndex( index ); // dirty becomes false
+ };
+
+ // write all slots in the array
+ FORCEINLINE void Flush()
+ {
+ for( int i=0; i < COUNT; i++)
+ {
+ FlushIndex( i );
+ }
+ }
+
+ // default: write default value to cache, optionally write through
+ inline void DefaultIndex( int index )
+ {
+ GLContextGetDefaultIndexed( &data[index], index ); // read default values directly to our cache copy
+ Flush();
+ };
+
+ inline void Default( void )
+ {
+ for( int i=0; i<COUNT; i++)
+ {
+ DefaultIndex( i );
+ }
+ }
+
+ // read: sel = 0 for cache, 1 for context
+ inline void ReadIndex( T *dst, int index, int sel )
+ {
+ if (sel==0)
+ *dst = data[index];
+ else
+ GLContextGetIndexed( dst, index );
+ };
+
+ // check: verify that context equals cache, return true if mismatched or if illegal values seen
+ inline bool CheckIndex( int index )
+ {
+ T temp;
+ bool result;
+
+ GLContextGetIndexed( &temp, index );
+ result = !(temp == data[index]);
+
+ return result;
+ };
+
+ inline bool Check( void )
+ {
+ //T temp;
+ bool result = false;
+
+ for( int i=0; i<COUNT; i++)
+ {
+ result |= CheckIndex( i );
+ }
+
+ return result;
+ };
+
+ protected:
+ T data[COUNT];
+};
+
+
+//===========================================================================//
+
+
+
+struct GLMTexSampler
+{
+ CGLMTex *m_pBoundTex; // tex which is actually bound now
+ GLMTexSamplingParams m_samp; // current 2D sampler state
+};
+
+// GLMContext will maintain one of these structures inside the context to represent the current state.
+// Client can supply a new one when it wants to change the setup.
+//FIXME GLMContext can do the work to migrate from old setup to new setup as efficiently as possible (but it doesn't yet)
+
+struct GLMVertexSetup
+{
+ uint m_attrMask; // which attrs are enabled (1<<n) mask where n is a GLMVertexAttributeIndex.
+
+ GLMVertexAttributeDesc m_attrs[ kGLMVertexAttributeIndexMax ];
+
+ // copied in from dxabstract, not strictly needed for operation, helps debugging
+ unsigned char m_vtxAttribMap[16];
+
+ /* high nibble is usage per _D3DDECLUSAGE
+ typedef enum _D3DDECLUSAGE
+ {
+ D3DDECLUSAGE_POSITION = 0,
+ D3DDECLUSAGE_BLENDWEIGHT = 1,
+ D3DDECLUSAGE_BLENDINDICES = 2,
+ D3DDECLUSAGE_NORMAL = 3,
+ D3DDECLUSAGE_PSIZE = 4,
+ D3DDECLUSAGE_TEXCOORD = 5,
+ D3DDECLUSAGE_TANGENT = 6,
+ D3DDECLUSAGE_BINORMAL = 7,
+ D3DDECLUSAGE_TESSFACTOR = 8,
+ D3DDECLUSAGE_PLUGH = 9, // mystery value
+ D3DDECLUSAGE_COLOR = 10,
+ D3DDECLUSAGE_FOG = 11,
+ D3DDECLUSAGE_DEPTH = 12,
+ D3DDECLUSAGE_SAMPLE = 13,
+ } D3DDECLUSAGE;
+
+ low nibble is usageindex (i.e. POSITION0, POSITION1, etc)
+ array position is attrib number.
+ */
+};
+
+//===========================================================================//
+
+//FIXME magic numbers here
+
+#define kGLMProgramParamFloat4Limit 256
+#define kGLMProgramParamBoolLimit 16
+#define kGLMProgramParamInt4Limit 16
+
+#define kGLMVertexProgramParamFloat4Limit 256
+#define kGLMFragmentProgramParamFloat4Limit 32
+
+struct GLMProgramParamsF
+{
+ float m_values[kGLMProgramParamFloat4Limit][4]; // float4's 256 of them
+
+ int m_firstDirtySlotNonBone;
+ int m_dirtySlotHighWaterNonBone; // index of slot past highest dirty non-bone register (assume 0 for base of range)
+
+ int m_dirtySlotHighWaterBone; // index of slot past highest dirty bone register (0=first bone reg, which is DXABSTRACT_VS_FIRST_BONE_SLOT)
+};
+
+struct GLMProgramParamsB
+{
+ int m_values[kGLMProgramParamBoolLimit]; // bools, 4 of them
+ uint m_dirtySlotCount;
+};
+
+struct GLMProgramParamsI
+{
+ int m_values[kGLMProgramParamInt4Limit][4]; // int4s, 16 of them
+ uint m_dirtySlotCount;
+};
+
+enum EGLMParamWriteMode
+{
+ eParamWriteAllSlots, // glUniform4fv of the maximum size (not recommended if shader is down-sizing the decl)
+ eParamWriteShaderSlots, // glUniform4fv of the active slot count ("highwater")
+ eParamWriteShaderSlotsOptional, // glUniform4fv of the active slot count ("highwater") - but only if at least one has been written - it's optional
+ eParamWriteDirtySlotRange // glUniform4fv of the 0-N range where N is highest dirty slot
+};
+
+enum EGLMAttribWriteMode
+{
+ eAttribWriteAll,
+ eAttribWriteDirty
+};
+
+//===========================================================================//
+
+#if GLMDEBUG
+enum EGLMDebugCallSite
+{
+ eBeginFrame, // inside begin frame func - frame number has been inc'd, batch number should be -1
+ eClear, // inside clear func
+ eDrawElements, // inside repeat loop, prior to draw call - batch numberhas been inc'd
+ eEndFrame, // end frame
+ ePresent // before showing pixels
+};
+
+// caller should zero one of these out and fill in the m_caller before invoking the hook
+struct GLMDebugHookInfo
+{
+ // info from the caller to the debug hook
+ EGLMDebugCallSite m_caller;
+
+
+ // state the hook uses to keep track of progress within a single run of the caller
+ int m_iteration; // which call to the hook is this. if it's zero, it precedes any action in the caller.
+
+
+ // bools used to communicate between caller and hook
+ bool m_loop; // hook tells caller to loop around again (don't exit)
+ bool m_holding; // current mood of hook, are we holding on this batch (i.e. rerun)
+
+ // specific info for a draw call
+ GLenum m_drawMode;
+ GLuint m_drawStart;
+ GLuint m_drawEnd;
+ GLsizei m_drawCount;
+ GLenum m_drawType;
+ const GLvoid *m_drawIndices;
+};
+#endif
+
+//===========================================================================//
+
+class CFlushDrawStatesStats
+{
+public:
+ CFlushDrawStatesStats()
+ {
+ Clear();
+ }
+
+ void Clear()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+
+ uint m_nTotalBatchFlushes;
+ uint m_nTotalProgramPairChanges;
+
+ uint m_nNumChangedSamplers;
+ uint m_nNumSamplingParamsChanged;
+ uint m_nIndexBufferChanged;
+ uint m_nVertexBufferChanged;
+
+ uint m_nFirstVSConstant;
+ uint m_nNumVSConstants;
+ uint m_nNumVSBoneConstants;
+ uint m_nFirstPSConstant;
+ uint m_nNumPSConstants;
+ uint m_nNewPS;
+ uint m_nNewVS;
+};
+
+//===========================================================================//
+
+#ifndef GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
+#define GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 0x9160
+#endif
+
+#define GLMGR_PINNED_MEMORY_BUFFER_SIZE ( 6 * 1024 * 1024 )
+
+class CPinnedMemoryBuffer
+{
+ CPinnedMemoryBuffer( const CPinnedMemoryBuffer & );
+ CPinnedMemoryBuffer & operator= ( const CPinnedMemoryBuffer & );
+
+public:
+ CPinnedMemoryBuffer() : m_pRawBuf( NULL ), m_pBuf( NULL ), m_nSize( 0 ), m_nOfs( 0 ), m_nBufferObj( 0 ), m_nSyncObj( 0 )
+ {
+ }
+
+ ~CPinnedMemoryBuffer()
+ {
+ Deinit();
+ }
+
+ bool Init( uint nSize )
+ {
+ Deinit();
+
+ // Guarantee 64KB alignment
+ m_pRawBuf = malloc( nSize + 65535 );
+ m_pBuf = reinterpret_cast<void *>((reinterpret_cast<uint64>(m_pRawBuf) + 65535) & (~65535));
+ m_nSize = nSize;
+ m_nOfs = 0;
+
+ gGL->glGenBuffersARB( 1, &m_nBufferObj );
+ gGL->glBindBufferARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nBufferObj );
+
+ gGL->glBufferDataARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nSize, m_pBuf, GL_STREAM_COPY );
+
+ return true;
+ }
+
+ void Deinit()
+ {
+ if ( !m_pRawBuf )
+ return;
+
+ BlockUntilNotBusy();
+
+ gGL->glBindBufferARB(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, m_nBufferObj );
+
+ gGL->glBufferDataARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0, (void*)NULL, GL_STREAM_COPY );
+
+ gGL->glBindBufferARB( GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0 );
+
+ gGL->glDeleteBuffersARB( 1, &m_nBufferObj );
+ m_nBufferObj = 0;
+
+ free( m_pRawBuf );
+ m_pRawBuf = NULL;
+ m_pBuf = NULL;
+
+ m_nSize = 0;
+ m_nOfs = 0;
+ }
+
+ inline uint GetSize() const { return m_nSize; }
+ inline uint GetOfs() const { return m_nOfs; }
+ inline uint GetBytesRemaining() const { return m_nSize - m_nOfs; }
+ inline void *GetPtr() const { return m_pBuf; }
+ inline GLuint GetHandle() const { return m_nBufferObj; }
+
+ void InsertFence()
+ {
+ if ( m_nSyncObj )
+ {
+ gGL->glDeleteSync( m_nSyncObj );
+ }
+
+ m_nSyncObj = gGL->glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 );
+ }
+
+ void BlockUntilNotBusy()
+ {
+ if ( m_nSyncObj )
+ {
+ gGL->glClientWaitSync( m_nSyncObj, GL_SYNC_FLUSH_COMMANDS_BIT, 3000000000000ULL );
+
+ gGL->glDeleteSync( m_nSyncObj );
+
+ m_nSyncObj = 0;
+ }
+ m_nOfs = 0;
+ }
+
+ void Append( uint nSize )
+ {
+ m_nOfs += nSize;
+ Assert( m_nOfs <= m_nSize );
+ }
+
+private:
+ void *m_pRawBuf;
+ void *m_pBuf;
+ uint m_nSize;
+ uint m_nOfs;
+
+ GLuint m_nBufferObj;
+
+ GLsync m_nSyncObj;
+};
+
+//===========================================================================//
+
+class GLMContext
+{
+ public:
+ // set/check current context (perq for many other calls)
+ void MakeCurrent( bool bRenderThread = false );
+ void ReleaseCurrent( bool bRenderThread = false );
+
+ // CheckCurrent has been removed (it no longer compiled on Linux). To minimize churn I'm leaving
+ // the inline NOP version.
+ // DO NOT change this to non-inlined. It's called all over the place from very hot codepaths.
+ FORCEINLINE void CheckCurrent( void ) { }
+
+ void PopulateCaps( void ); // fill out later portions of renderer info record which need context queries
+ void DumpCaps( void ); // printf all the caps info (you can call this in release too)
+ const GLMRendererInfoFields& Caps( void ); // peek at the caps record
+
+ // state cache/mirror
+ void SetDefaultStates( void );
+ void ForceFlushStates();
+
+ void VerifyStates( void );
+
+ // textures
+ // Lock and Unlock reqs go directly to the tex object
+ CGLMTex *NewTex( GLMTexLayoutKey *key, const char *debugLabel=NULL );
+ void DelTex( CGLMTex *tex );
+
+ // options for Blit (replacement for ResolveTex and BlitTex)
+ // pass NULL for dstTex if you want to target GL_BACK with the blit. You get y-flip with that, don't change the dstrect yourself.
+ void Blit2( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, uint filter );
+
+ // tex blit (via FBO blit)
+ void BlitTex( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, uint filter, bool useBlitFB = true );
+
+ // MSAA resolve - we do this in GLMContext because it has to do a bunch of FBO/blit gymnastics
+ void ResolveTex( CGLMTex *tex, bool forceDirty=false );
+
+ // texture pre-load (residency forcing) - normally done one-time but you can force it
+ void PreloadTex( CGLMTex *tex, bool force=false );
+
+ // samplers
+ FORCEINLINE void SetSamplerTex( int sampler, CGLMTex *tex );
+
+ FORCEINLINE void SetSamplerDirty( int sampler );
+ FORCEINLINE void SetSamplerMinFilter( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerMagFilter( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerMipFilter( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerAddressU( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerAddressV( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerAddressW( int sampler, GLenum Value );
+ FORCEINLINE void SetSamplerStates( int sampler, GLenum AddressU, GLenum AddressV, GLenum AddressW, GLenum minFilter, GLenum magFilter, GLenum mipFilter );
+ FORCEINLINE void SetSamplerBorderColor( int sampler, DWORD Value );
+ FORCEINLINE void SetSamplerMipMapLODBias( int sampler, DWORD Value );
+ FORCEINLINE void SetSamplerMaxMipLevel( int sampler, DWORD Value );
+ FORCEINLINE void SetSamplerMaxAnisotropy( int sampler, DWORD Value );
+ FORCEINLINE void SetSamplerSRGBTexture( int sampler, DWORD Value );
+ FORCEINLINE void SetShadowFilter( int sampler, DWORD Value );
+
+ // render targets (FBO's)
+ CGLMFBO *NewFBO( void );
+ void DelFBO( CGLMFBO *fbo );
+
+ // programs
+ CGLMProgram *NewProgram( EGLMProgramType type, char *progString, const char *pShaderName );
+ void DelProgram( CGLMProgram *pProg );
+ void NullProgram( void ); // de-ac all shader state
+
+ FORCEINLINE void SetVertexProgram( CGLMProgram *pProg );
+ FORCEINLINE void SetFragmentProgram( CGLMProgram *pProg );
+ FORCEINLINE void SetProgram( EGLMProgramType nProgType, CGLMProgram *pProg ) { m_drawingProgram[nProgType] = pProg; m_bDirtyPrograms = true; }
+
+ void SetDrawingLang( EGLMProgramLang lang, bool immediate=false ); // choose ARB or GLSL. immediate=false defers lang change to top of frame
+
+ void LinkShaderPair( CGLMProgram *vp, CGLMProgram *fp ); // ensure this combo has been linked and is in the GLSL pair cache
+ void ClearShaderPairCache( void ); // call this to shoot down all the linked pairs
+ void QueryShaderPair( int index, GLMShaderPairInfo *infoOut ); // this lets you query the shader pair cache for saving its state
+
+ // buffers
+ // Lock and Unlock reqs go directly to the buffer object
+ CGLMBuffer *NewBuffer( EGLMBufferType type, uint size, uint options );
+ void DelBuffer( CGLMBuffer *buff );
+
+ FORCEINLINE void SetIndexBuffer( CGLMBuffer *buff ) { BindIndexBufferToCtx( buff ); }
+
+ // FIXME: Remove this, it's no longer used
+ FORCEINLINE void SetVertexAttributes( GLMVertexSetup *setup )
+ {
+ // we now just latch the vert setup and then execute on it at flushdrawstatestime if shaders are enabled.
+ if ( setup )
+ {
+ m_drawVertexSetup = *setup;
+ }
+ else
+ {
+ memset( &m_drawVertexSetup, 0, sizeof( m_drawVertexSetup ) );
+ }
+ }
+
+ // note, no API is exposed for setting a single attribute source.
+ // come prepared with a complete block of attributes to use.
+
+ // Queries
+ CGLMQuery *NewQuery( GLMQueryParams *params );
+ void DelQuery( CGLMQuery *query );
+
+ // "slot" means a vec4-sized thing
+ // these write into .env parameter space
+ FORCEINLINE void SetProgramParametersF( EGLMProgramType type, uint baseSlot, float *slotData, uint slotCount );
+ FORCEINLINE void SetProgramParametersB( EGLMProgramType type, uint baseSlot, int *slotData, uint boolCount ); // take "BOOL" aka int
+ FORCEINLINE void SetProgramParametersI( EGLMProgramType type, uint baseSlot, int *slotData, uint slotCount ); // take int4s
+
+ // state sync
+ // If lazyUnbinding is true, unbound samplers will not actually be unbound to the GL device.
+ FORCEINLINE void FlushDrawStates( uint nStartIndex, uint nEndIndex, uint nBaseVertex ); // pushes all drawing state - samplers, tex, programs, etc.
+ void FlushDrawStatesNoShaders();
+
+ // drawing
+ FORCEINLINE void DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf );
+ void DrawRangeElementsNonInline( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf );
+
+ void CheckNative( void );
+
+ // clearing
+ void Clear( bool color, unsigned long colorValue, bool depth, float depthValue, bool stencil, unsigned int stencilValue, GLScissorBox_t *rect = NULL );
+
+ // display
+ //void SetVSyncEnable( bool vsyncOn );
+ //void SetFullScreen( bool fsOn, int screenIndex ); // will be latched for next BeginFrame
+ //void ActivateFullScreen( bool fsOn, int screenIndex ); // will be called by BeginFrame
+ bool SetDisplayParams( GLMDisplayParams *params ); // either the first time setup, or a change to new setup
+
+ void Present( CGLMTex *tex ); // somewhat hardwired for the time being
+
+ // Called when IDirect3DDevice9::Reset() is called.
+ void Reset();
+
+ // writers for the state block inputs
+
+ FORCEINLINE void WriteAlphaTestEnable( GLAlphaTestEnable_t *src ) { m_AlphaTestEnable.Write( src ); }
+ FORCEINLINE void WriteAlphaTestFunc( GLAlphaTestFunc_t *src ) { m_AlphaTestFunc.Write( src ); }
+ FORCEINLINE void WriteAlphaToCoverageEnable( GLAlphaToCoverageEnable_t *src ) { m_AlphaToCoverageEnable.Write( src ); }
+ FORCEINLINE void WriteCullFaceEnable( GLCullFaceEnable_t *src ) { m_CullFaceEnable.Write( src ); }
+ FORCEINLINE void WriteCullFrontFace( GLCullFrontFace_t *src ) { m_CullFrontFace.Write( src ); }
+ FORCEINLINE void WritePolygonMode( GLPolygonMode_t *src ) { m_PolygonMode.Write( src ); }
+ FORCEINLINE void WriteDepthBias( GLDepthBias_t *src ) { m_DepthBias.Write( src ); }
+ FORCEINLINE void WriteClipPlaneEnable( GLClipPlaneEnable_t *src, int which ) { m_ClipPlaneEnable.WriteIndex( src, which ); }
+ FORCEINLINE void WriteClipPlaneEquation( GLClipPlaneEquation_t *src, int which ) { m_ClipPlaneEquation.WriteIndex( src, which ); }
+ FORCEINLINE void WriteScissorEnable( GLScissorEnable_t *src ) { m_ScissorEnable.Write( src ); }
+ FORCEINLINE void WriteScissorBox( GLScissorBox_t *src ) { m_ScissorBox.Write( src ); }
+ FORCEINLINE void WriteViewportBox( GLViewportBox_t *src ) { m_ViewportBox.Write( src ); }
+ FORCEINLINE void WriteViewportDepthRange( GLViewportDepthRange_t *src ) { m_ViewportDepthRange.Write( src ); }
+ FORCEINLINE void WriteColorMaskSingle( GLColorMaskSingle_t *src ) { m_ColorMaskSingle.Write( src ); }
+ FORCEINLINE void WriteColorMaskMultiple( GLColorMaskMultiple_t *src, int which ) { m_ColorMaskMultiple.WriteIndex( src, which ); }
+ FORCEINLINE void WriteBlendEnable( GLBlendEnable_t *src ) { m_BlendEnable.Write( src ); }
+ FORCEINLINE void WriteBlendFactor( GLBlendFactor_t *src ) { m_BlendFactor.Write( src ); }
+ FORCEINLINE void WriteBlendEquation( GLBlendEquation_t *src ) { m_BlendEquation.Write( src ); }
+ FORCEINLINE void WriteBlendColor( GLBlendColor_t *src ) { m_BlendColor.Write( src ); }
+
+ FORCEINLINE void WriteBlendEnableSRGB( GLBlendEnableSRGB_t *src )
+ {
+ if (m_caps.m_hasGammaWrites) // only if caps allow do we actually push it through to the extension
+ {
+ m_BlendEnableSRGB.Write( src );
+ }
+ else
+ {
+ m_FakeBlendEnableSRGB = src->enable != 0;
+ }
+ // note however that we're still tracking what this mode should be, so FlushDrawStates can look at it and adjust the pixel shader
+ // if fake SRGB mode is in place (m_caps.m_hasGammaWrites is false)
+ }
+
+ FORCEINLINE void WriteDepthTestEnable( GLDepthTestEnable_t *src ) { m_DepthTestEnable.Write( src ); }
+ FORCEINLINE void WriteDepthFunc( GLDepthFunc_t *src ) { m_DepthFunc.Write( src ); }
+ FORCEINLINE void WriteDepthMask( GLDepthMask_t *src ) { m_DepthMask.Write( src ); }
+ FORCEINLINE void WriteStencilTestEnable( GLStencilTestEnable_t *src ) { m_StencilTestEnable.Write( src ); }
+ FORCEINLINE void WriteStencilFunc( GLStencilFunc_t *src ) { m_StencilFunc.Write( src ); }
+ FORCEINLINE void WriteStencilOp( GLStencilOp_t *src, int which ) { m_StencilOp.WriteIndex( src, which ); }
+ FORCEINLINE void WriteStencilWriteMask( GLStencilWriteMask_t *src ) { m_StencilWriteMask.Write( src ); }
+ FORCEINLINE void WriteClearColor( GLClearColor_t *src ) { m_ClearColor.Write( src ); }
+ FORCEINLINE void WriteClearDepth( GLClearDepth_t *src ) { m_ClearDepth.Write( src ); }
+ FORCEINLINE void WriteClearStencil( GLClearStencil_t *src ) { m_ClearStencil.Write( src ); }
+
+ // debug stuff
+ void BeginFrame( void );
+ void EndFrame( void );
+
+ // new interactive debug stuff
+#if GLMDEBUG
+ void DebugDump( GLMDebugHookInfo *info, uint options, uint vertDumpMode );
+ void DebugHook( GLMDebugHookInfo *info );
+ void DebugPresent( void );
+ void DebugClear( void );
+#endif
+
+ FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants );
+
+ FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
+
+ protected:
+ friend class GLMgr; // only GLMgr can make GLMContext objects
+ friend class GLMRendererInfo; // only GLMgr can make GLMContext objects
+ friend class CGLMTex; // tex needs to be able to do binds
+ friend class CGLMFBO; // fbo needs to be able to do binds
+ friend class CGLMProgram;
+ friend class CGLMShaderPair;
+ friend class CGLMShaderPairCache;
+ friend class CGLMBuffer;
+ friend class CGLMBufferSpanManager;
+ friend class GLMTester; // tester class needs access back into GLMContext
+
+ friend struct IDirect3D9;
+ friend struct IDirect3DDevice9;
+ friend struct IDirect3DQuery9;
+
+ // methods------------------------------------------
+
+ // old GLMContext( GLint displayMask, GLint rendererID, PseudoNSGLContextPtr nsglShareCtx );
+ GLMContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params );
+ ~GLMContext();
+
+ FORCEINLINE GLuint FindSamplerObject( const GLMTexSamplingParams &desiredParams );
+
+ FORCEINLINE void SetBufAndVertexAttribPointer( uint nIndex, GLuint nGLName, GLuint stride, GLuint datatype, GLboolean normalized, GLuint nCompCount, const void *pBuf, uint nRevision )
+ {
+ VertexAttribs_t &curAttribs = m_boundVertexAttribs[nIndex];
+ if ( nGLName != m_nBoundGLBuffer[kGLMVertexBuffer] )
+ {
+ m_nBoundGLBuffer[kGLMVertexBuffer] = nGLName;
+ gGL->glBindBufferARB( GL_ARRAY_BUFFER_ARB, nGLName );
+ }
+ else if ( ( curAttribs.m_pPtr == pBuf ) &&
+ ( curAttribs.m_revision == nRevision ) &&
+ ( curAttribs.m_stride == stride ) &&
+ ( curAttribs.m_datatype == datatype ) &&
+ ( curAttribs.m_normalized == normalized ) &&
+ ( curAttribs.m_nCompCount == nCompCount ) )
+ {
+ return;
+ }
+
+ curAttribs.m_nCompCount = nCompCount;
+ curAttribs.m_datatype = datatype;
+ curAttribs.m_normalized = normalized;
+ curAttribs.m_stride = stride;
+ curAttribs.m_pPtr = pBuf;
+ curAttribs.m_revision = nRevision;
+
+ gGL->glVertexAttribPointer( nIndex, nCompCount, datatype, normalized, stride, pBuf );
+ }
+
+ struct CurAttribs_t
+ {
+ uint m_nTotalBufferRevision;
+ IDirect3DVertexDeclaration9 *m_pVertDecl;
+ D3DStreamDesc m_streams[ D3D_MAX_STREAMS ];
+ uint64 m_vtxAttribMap[2];
+ };
+
+ CurAttribs_t m_CurAttribs;
+
+ FORCEINLINE void ClearCurAttribs()
+ {
+ m_CurAttribs.m_nTotalBufferRevision = 0;
+ m_CurAttribs.m_pVertDecl = NULL;
+ memset( m_CurAttribs.m_streams, 0, sizeof( m_CurAttribs.m_streams ) );
+ m_CurAttribs.m_vtxAttribMap[0] = 0xBBBBBBBBBBBBBBBBULL;
+ m_CurAttribs.m_vtxAttribMap[1] = 0xBBBBBBBBBBBBBBBBULL;
+ }
+
+ FORCEINLINE void ReleasedShader() { NullProgram(); }
+
+ // textures
+ FORCEINLINE void SelectTMU( int tmu )
+ {
+ if ( tmu != m_activeTexture )
+ {
+ gGL->glActiveTexture( GL_TEXTURE0 + tmu );
+ m_activeTexture = tmu;
+ }
+ }
+
+ void BindTexToTMU( CGLMTex *tex, int tmu );
+
+ // render targets / FBO's
+ void BindFBOToCtx( CGLMFBO *fbo, GLenum bindPoint = GL_FRAMEBUFFER_EXT ); // you can also choose GL_READ_FRAMEBUFFER_EXT / GL_DRAW_FRAMEBUFFER_EXT
+
+ // buffers
+ FORCEINLINE void BindGLBufferToCtx( GLenum nGLBufType, GLuint nGLName, bool bForce = false )
+ {
+ Assert( ( nGLBufType == GL_ARRAY_BUFFER_ARB ) || ( nGLBufType == GL_ELEMENT_ARRAY_BUFFER_ARB ) );
+
+ const uint nIndex = ( nGLBufType == GL_ARRAY_BUFFER_ARB ) ? kGLMVertexBuffer : kGLMIndexBuffer;
+ if ( ( bForce ) || ( m_nBoundGLBuffer[nIndex] != nGLName ) )
+ {
+ m_nBoundGLBuffer[nIndex] = nGLName;
+ gGL->glBindBufferARB( nGLBufType, nGLName );
+ }
+ }
+
+ void BindBufferToCtx( EGLMBufferType type, CGLMBuffer *buff, bool force = false ); // does not twiddle any enables.
+
+ FORCEINLINE void BindIndexBufferToCtx( CGLMBuffer *buff );
+ FORCEINLINE void BindVertexBufferToCtx( CGLMBuffer *buff );
+
+ CPinnedMemoryBuffer *GetCurPinnedMemoryBuffer( ) { return &m_PinnedMemoryBuffers[m_nCurPinnedMemoryBuffer]; }
+
+ // members------------------------------------------
+
+ // context
+ DWORD m_nCurOwnerThreadId;
+ uint m_nThreadOwnershipReleaseCounter;
+
+ bool m_bUseSamplerObjects;
+ bool m_bPreferMapBufferRange;
+
+ IDirect3DDevice9 *m_pDevice;
+ GLMRendererInfoFields m_caps;
+
+ bool m_displayParamsValid; // is there a param block copied in yet
+ GLMDisplayParams m_displayParams; // last known display config, either via constructor, or by SetDisplayParams...
+
+#ifdef OSX
+ CGLPixelFormatAttribute m_pixelFormatAttribs[100]; // more than enough
+ PseudoNSGLContextPtr m_nsctx;
+ CGLContextObj m_ctx;
+#elif defined( USE_SDL )
+ int m_pixelFormatAttribs[100]; // more than enough
+ PseudoNSGLContextPtr m_nsctx;
+ void * m_ctx;
+#endif
+ bool m_oneCtxEnable; // true if we use the window's context directly instead of making a second one shared against it
+
+ bool m_bUseBoneUniformBuffers; // if true, we use two uniform buffers for vertex shader constants vs. one
+
+ // texture form table
+ CGLMTexLayoutTable *m_texLayoutTable;
+
+ // context state mirrors
+
+ GLState<GLAlphaTestEnable_t> m_AlphaTestEnable;
+
+ GLState<GLAlphaTestFunc_t> m_AlphaTestFunc;
+
+ GLState<GLCullFaceEnable_t> m_CullFaceEnable;
+ GLState<GLCullFrontFace_t> m_CullFrontFace;
+ GLState<GLPolygonMode_t> m_PolygonMode;
+
+ GLState<GLDepthBias_t> m_DepthBias;
+
+ GLStateArray<GLClipPlaneEnable_t,kGLMUserClipPlanes> m_ClipPlaneEnable;
+ GLStateArray<GLClipPlaneEquation_t,kGLMUserClipPlanes> m_ClipPlaneEquation; // dxabstract puts them directly into param slot 253(0) and 254(1)
+
+ GLState<GLScissorEnable_t> m_ScissorEnable;
+ GLState<GLScissorBox_t> m_ScissorBox;
+
+ GLState<GLAlphaToCoverageEnable_t> m_AlphaToCoverageEnable;
+
+ GLState<GLViewportBox_t> m_ViewportBox;
+ GLState<GLViewportDepthRange_t> m_ViewportDepthRange;
+
+ GLState<GLColorMaskSingle_t> m_ColorMaskSingle;
+ GLStateArray<GLColorMaskMultiple_t,8> m_ColorMaskMultiple; // need an official constant for the color buffers limit
+
+ GLState<GLBlendEnable_t> m_BlendEnable;
+ GLState<GLBlendFactor_t> m_BlendFactor;
+ GLState<GLBlendEquation_t> m_BlendEquation;
+ GLState<GLBlendColor_t> m_BlendColor;
+ GLState<GLBlendEnableSRGB_t> m_BlendEnableSRGB; // write to this one to transmit intent to write SRGB encoded pixels to drawing FB
+ bool m_FakeBlendEnableSRGB; // writes to above will be shunted here if fake SRGB is in effect.
+
+ GLState<GLDepthTestEnable_t> m_DepthTestEnable;
+ GLState<GLDepthFunc_t> m_DepthFunc;
+ GLState<GLDepthMask_t> m_DepthMask;
+
+ GLState<GLStencilTestEnable_t> m_StencilTestEnable; // global stencil test enable
+ GLState<GLStencilFunc_t> m_StencilFunc; // holds front and back stencil funcs
+ GLStateArray<GLStencilOp_t,2> m_StencilOp; // indexed: 0=front 1=back
+ GLState<GLStencilWriteMask_t> m_StencilWriteMask;
+
+ GLState<GLClearColor_t> m_ClearColor;
+ GLState<GLClearDepth_t> m_ClearDepth;
+ GLState<GLClearStencil_t> m_ClearStencil;
+
+ // texture bindings and sampler setup
+ int m_activeTexture; // mirror for glActiveTexture
+ GLMTexSampler m_samplers[GLM_SAMPLER_COUNT];
+
+ uint8 m_nDirtySamplerFlags[GLM_SAMPLER_COUNT]; // 0 if the sampler is dirty, 1 if not
+ uint32 m_nNumDirtySamplers; // # of unique dirty sampler indices in m_nDirtySamplers
+ uint8 m_nDirtySamplers[GLM_SAMPLER_COUNT + 1]; // dirty sampler indices
+
+ void MarkAllSamplersDirty();
+
+ struct SamplerHashEntry
+ {
+ GLuint m_samplerObject;
+ GLMTexSamplingParams m_params;
+ };
+
+ enum
+ {
+ cSamplerObjectHashBits = 9, cSamplerObjectHashSize = 1 << cSamplerObjectHashBits
+ };
+ SamplerHashEntry m_samplerObjectHash[cSamplerObjectHashSize];
+ uint m_nSamplerObjectHashNumEntries;
+
+ // texture lock tracking - CGLMTex objects share usage of this
+ CUtlVector< GLMTexLockDesc > m_texLocks;
+
+ // render target binding - check before draw
+ // similar to tex sampler mechanism, we track "bound" from "chosen for drawing" separately,
+ // so binding for creation/setup need not disrupt any notion of what will be used at draw time
+
+ CGLMFBO *m_boundDrawFBO; // FBO on GL_DRAW_FRAMEBUFFER bind point
+ CGLMFBO *m_boundReadFBO; // FBO on GL_READ_FRAMEBUFFER bind point
+ // ^ both are set if you bind to GL_FRAMEBUFFER_EXT
+
+ CGLMFBO *m_drawingFBO; // what FBO should be bound at draw time (to both read/draw bp's).
+
+ CGLMFBO *m_blitReadFBO;
+ CGLMFBO *m_blitDrawFBO; // scratch FBO's for framebuffer blit
+
+ CGLMFBO *m_scratchFBO[ kGLMScratchFBOCount ]; // general purpose FBO's for internal use
+
+ CUtlVector< CGLMFBO* > m_fboTable; // each live FBO goes in the table
+
+ // program bindings
+ EGLMProgramLang m_drawingLangAtFrameStart; // selector for start of frame (spills into m_drawingLang)
+ EGLMProgramLang m_drawingLang; // selector for which language we desire to draw with on the next batch
+ CGLMProgram *m_drawingProgram[ kGLMNumProgramTypes ];
+ bool m_bDirtyPrograms;
+
+ GLMProgramParamsF m_programParamsF[ kGLMNumProgramTypes ];
+ GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used
+ GLMProgramParamsI m_programParamsI[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used
+ EGLMParamWriteMode m_paramWriteMode;
+
+ CGLMProgram *m_pNullFragmentProgram; // write opaque black. Activate when caller asks for null FP
+
+ CGLMProgram *m_preloadTexVertexProgram; // programs to help preload textures (dummies)
+ CGLMProgram *m_preload2DTexFragmentProgram;
+ CGLMProgram *m_preload3DTexFragmentProgram;
+ CGLMProgram *m_preloadCubeTexFragmentProgram;
+
+ CGLMShaderPairCache *m_pairCache; // GLSL only
+ CGLMShaderPair *m_pBoundPair; // GLSL only
+
+ FORCEINLINE void NewLinkedProgram() { ClearCurAttribs(); }
+
+ //uint m_boundPairRevision; // GLSL only
+ //GLhandleARB m_boundPairProgram; // GLSL only
+
+ // buffer bindings
+ GLuint m_nBoundGLBuffer[kGLMNumBufferTypes];
+
+ struct VertexAttribs_t
+ {
+ GLuint m_nCompCount;
+ GLenum m_datatype;
+ GLboolean m_normalized;
+ GLuint m_stride;
+ const void *m_pPtr;
+ uint m_revision;
+ };
+
+ VertexAttribs_t m_boundVertexAttribs[ kGLMVertexAttributeIndexMax ]; // tracked per attrib for dupe-set-absorb
+ uint m_lastKnownVertexAttribMask; // tracked for dupe-enable-absorb
+ int m_nNumSetVertexAttributes;
+
+ // FIXME: Remove this, it's no longer used
+ GLMVertexSetup m_drawVertexSetup;
+
+ EGLMAttribWriteMode m_attribWriteMode;
+
+ bool m_slowCheckEnable; // turn this on or no native checking is done ("-glmassertslow" or "-glmsspewslow")
+ bool m_slowAssertEnable; // turn this on to assert on a non-native batch "-glmassertslow"
+ bool m_slowSpewEnable; // turn this on to log non-native batches to stdout "-glmspewslow"
+ bool m_checkglErrorsAfterEveryBatch; // turn this on to check for GL errors after each batch (slow) ("-glcheckerrors")
+
+ // debug font texture
+ CGLMTex *m_debugFontTex; // might be NULL unless you call GenDebugFontTex
+ CGLMBuffer *m_debugFontIndices; // up to 1024 indices (256 chars times 4)
+ CGLMBuffer *m_debugFontVertices; // up to 1024 verts
+
+ // batch/frame debugging support
+ int m_debugFrameIndex; // init to -1. Increment at BeginFrame
+
+ int m_nMaxUsedVertexProgramConstantsHint;
+
+ uint32 m_dwRenderThreadId;
+ volatile bool m_bIsThreading;
+
+ uint m_nCurFrame;
+ uint m_nBatchCounter;
+
+ enum { cNumPinnedMemoryBuffers = 4 };
+ CPinnedMemoryBuffer m_PinnedMemoryBuffers[cNumPinnedMemoryBuffers];
+ uint m_nCurPinnedMemoryBuffer;
+
+ void SaveColorMaskAndSetToDefault();
+ void RestoreSavedColorMask();
+ GLColorMaskSingle_t m_SavedColorMask;
+
+#if GLMDEBUG
+ // interactive (DebugHook) debug support
+
+ // using these you can implement frame advance, batch single step, and batch rewind (let it run til next frame and hold on prev batch #)
+ int m_holdFrameBegin; // -1 if no hold req'd, otherwise # of frame to hold at (at beginframe time)
+ int m_holdFrameEnd; // -1 if no hold req'd, otherwise # of frame to hold at (at endframe time)
+
+ int m_holdBatch,m_holdBatchFrame; // -1 if no hold, else # of batch&frame to hold at (both must be set)
+ // these can be expired/cleared to -1 if the frame passes without a hit
+ // may be desirable to re-pause in that event, as user was expecting a hold to occur
+
+ bool m_debugDelayEnable; // allow sleep delay
+ uint m_debugDelay; // sleep time per hook call in microseconds (for usleep())
+
+ // pre-draw global toggles / options
+ bool m_autoClearColor,m_autoClearDepth,m_autoClearStencil;
+ float m_autoClearColorValues[4];
+
+ // debug knobs
+ int m_selKnobIndex;
+ float m_selKnobMinValue,m_selKnobMaxValue,m_selKnobIncrement;
+#endif
+
+#if GL_BATCH_PERF_ANALYSIS
+ uint m_nTotalVSUniformCalls;
+ uint m_nTotalVSUniformBoneCalls;
+ uint m_nTotalVSUniformsSet;
+ uint m_nTotalVSUniformsBoneSet;
+ uint m_nTotalPSUniformCalls;
+ uint m_nTotalPSUniformsSet;
+
+ CFlushDrawStatesStats m_FlushStats;
+#endif
+};
+
+FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf )
+{
+#if GL_ENABLE_INDEX_VERIFICATION
+ DrawRangeElementsNonInline( mode, start, end, count, type, indices, baseVertex, pIndexBuf );
+#else
+
+#if GLMDEBUG
+ GLM_FUNC;
+#else
+ //tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s %d-%d count:%d mode:%d type:%d", __FUNCTION__, start, end, count, mode, type );
+#endif
+
+ ++m_nBatchCounter;
+
+ SetIndexBuffer( pIndexBuf );
+
+ void *indicesActual = (void*)indices;
+
+ if ( pIndexBuf->m_bPseudo )
+ {
+ // you have to pass actual address, not offset
+ indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf );
+ }
+
+#if GLMDEBUG
+ bool hasVP = m_drawingProgram[ kGLMVertexProgram ] != NULL;
+ bool hasFP = m_drawingProgram[ kGLMFragmentProgram ] != NULL;
+
+ // init debug hook information
+ GLMDebugHookInfo info;
+ memset( &info, 0, sizeof(info) );
+ info.m_caller = eDrawElements;
+
+ // relay parameters we're operating under
+ info.m_drawMode = mode;
+ info.m_drawStart = start;
+ info.m_drawEnd = end;
+ info.m_drawCount = count;
+ info.m_drawType = type;
+ info.m_drawIndices = indices;
+
+ do
+ {
+ // obey global options re pre-draw clear
+ if ( m_autoClearColor || m_autoClearDepth || m_autoClearStencil )
+ {
+ GLMPRINTF(("-- DrawRangeElements auto clear" ));
+ this->DebugClear();
+ }
+
+ // always sync with editable shader text prior to draw
+#if GLMDEBUG
+ //FIXME disengage this path if context is in GLSL mode..
+ // it will need fixes to get the shader pair re-linked etc if edits happen anyway.
+
+ if (m_drawingProgram[ kGLMVertexProgram ])
+ {
+ m_drawingProgram[ kGLMVertexProgram ]->SyncWithEditable();
+ }
+ else
+ {
+ AssertOnce(!"drawing with no vertex program bound");
+ }
+
+
+ if (m_drawingProgram[ kGLMFragmentProgram ])
+ {
+ m_drawingProgram[ kGLMFragmentProgram ]->SyncWithEditable();
+ }
+ else
+ {
+ AssertOnce(!"drawing with no fragment program bound");
+ }
+#endif
+ // do the drawing
+ if (hasVP && hasFP)
+ {
+ gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex );
+
+ if ( m_slowCheckEnable )
+ {
+ CheckNative();
+ }
+ }
+ this->DebugHook( &info );
+
+ } while ( info.m_loop );
+#else
+ Assert( m_drawingLang == kGLMGLSL );
+
+ if ( m_pBoundPair )
+ {
+ gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex );
+
+#if GLMDEBUG
+ if ( m_slowCheckEnable )
+ {
+ CheckNative();
+ }
+#endif
+ }
+#endif
+
+#endif // GL_ENABLE_INDEX_VERIFICATION
+}
+
+FORCEINLINE void GLMContext::SetVertexProgram( CGLMProgram *pProg )
+{
+ m_drawingProgram[kGLMVertexProgram] = pProg;
+ m_bDirtyPrograms = true;
+}
+
+FORCEINLINE void GLMContext::SetFragmentProgram( CGLMProgram *pProg )
+{
+ m_drawingProgram[kGLMFragmentProgram] = pProg ? pProg : m_pNullFragmentProgram;
+ m_bDirtyPrograms = true;
+}
+
+// "slot" means a vec4-sized thing
+// these write into .env parameter space
+FORCEINLINE void GLMContext::SetProgramParametersF( EGLMProgramType type, uint baseSlot, float *slotData, uint slotCount )
+{
+#if GLMDEBUG
+ GLM_FUNC;
+#endif
+
+ Assert( baseSlot < kGLMProgramParamFloat4Limit );
+ Assert( baseSlot+slotCount <= kGLMProgramParamFloat4Limit );
+
+#if GLMDEBUG
+ GLMPRINTF(("-S-GLMContext::SetProgramParametersF %s slots %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + slotCount - 1 ));
+ for( uint i=0; i<slotCount; i++ )
+ {
+ GLMPRINTF(( "-S- %03d: [ %7.4f %7.4f %7.4f %7.4f ]",
+ baseSlot+i,
+ slotData[i*4], slotData[i*4+1], slotData[i*4+2], slotData[i*4+3]
+ ));
+ }
+#endif
+
+ memcpy( &m_programParamsF[type].m_values[baseSlot][0], slotData, (4 * sizeof(float)) * slotCount );
+
+ if ( ( type == kGLMVertexProgram ) && ( m_bUseBoneUniformBuffers ) )
+ {
+ if ( ( baseSlot + slotCount ) > DXABSTRACT_VS_FIRST_BONE_SLOT )
+ {
+ if ( baseSlot < DXABSTRACT_VS_FIRST_BONE_SLOT )
+ {
+ // The register set crosses between the constant buffers - should only happen at startup during init.
+ m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, (int)baseSlot );
+ m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, (int)MIN( baseSlot + slotCount, DXABSTRACT_VS_FIRST_BONE_SLOT ) );
+ baseSlot = DXABSTRACT_VS_FIRST_BONE_SLOT;
+ }
+
+ int nNumActualBones = ( baseSlot + slotCount ) - DXABSTRACT_VS_FIRST_BONE_SLOT;
+ m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone, nNumActualBones );
+ }
+ else
+ {
+ m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, (int)baseSlot );
+ m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, (int)(baseSlot + slotCount) );
+ }
+ }
+ else
+ {
+ m_programParamsF[type].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[type].m_dirtySlotHighWaterNonBone, (int)(baseSlot + slotCount) );
+ m_programParamsF[type].m_firstDirtySlotNonBone = MIN( m_programParamsF[type].m_firstDirtySlotNonBone, (int)baseSlot );
+ }
+}
+
+FORCEINLINE void GLMContext::SetProgramParametersB( EGLMProgramType type, uint baseSlot, int *slotData, uint boolCount )
+{
+#if GLMDEBUG
+ GLM_FUNC;
+#endif
+
+ Assert( m_drawingLang == kGLMGLSL );
+ Assert( type==kGLMVertexProgram );
+
+ Assert( baseSlot < kGLMProgramParamBoolLimit );
+ Assert( baseSlot+boolCount <= kGLMProgramParamBoolLimit );
+
+#if GLMDEBUG
+ GLMPRINTF(("-S-GLMContext::SetProgramParametersB %s bools %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + boolCount - 1 ));
+ for( uint i=0; i<boolCount; i++ )
+ {
+ GLMPRINTF(( "-S- %03d: %d (bool)",
+ baseSlot+i,
+ slotData[i]
+ ));
+ }
+#endif
+
+ memcpy( &m_programParamsB[type].m_values[baseSlot], slotData, sizeof(int) * boolCount );
+
+ if ( (baseSlot+boolCount) > m_programParamsB[type].m_dirtySlotCount)
+ m_programParamsB[type].m_dirtySlotCount = baseSlot+boolCount;
+}
+
+FORCEINLINE void GLMContext::SetProgramParametersI( EGLMProgramType type, uint baseSlot, int *slotData, uint slotCount ) // groups of 4 ints...
+{
+#if GLMDEBUG
+ GLM_FUNC;
+#endif
+
+ Assert( m_drawingLang == kGLMGLSL );
+ Assert( type==kGLMVertexProgram );
+
+ Assert( baseSlot < kGLMProgramParamInt4Limit );
+ Assert( baseSlot+slotCount <= kGLMProgramParamInt4Limit );
+
+#if GLMDEBUG
+ GLMPRINTF(("-S-GLMContext::SetProgramParametersI %s slots %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + slotCount - 1 ));
+ for( uint i=0; i<slotCount; i++ )
+ {
+ GLMPRINTF(( "-S- %03d: %d %d %d %d (int4)",
+ baseSlot+i,
+ slotData[i*4],slotData[i*4+1],slotData[i*4+2],slotData[i*4+3]
+ ));
+ }
+#endif
+
+ memcpy( &m_programParamsI[type].m_values[baseSlot][0], slotData, (4*sizeof(int)) * slotCount );
+
+ if ( (baseSlot + slotCount) > m_programParamsI[type].m_dirtySlotCount)
+ {
+ m_programParamsI[type].m_dirtySlotCount = baseSlot + slotCount;
+ }
+}
+
+FORCEINLINE void GLMContext::SetSamplerDirty( int sampler )
+{
+ Assert( sampler < GLM_SAMPLER_COUNT );
+ m_nDirtySamplers[m_nNumDirtySamplers] = sampler;
+ m_nNumDirtySamplers += m_nDirtySamplerFlags[sampler];
+ m_nDirtySamplerFlags[sampler] = 0;
+}
+
+FORCEINLINE void GLMContext::SetSamplerTex( int sampler, CGLMTex *tex )
+{
+ Assert( sampler < GLM_SAMPLER_COUNT );
+ m_samplers[sampler].m_pBoundTex = tex;
+ if ( tex )
+ {
+ if ( !gGL->m_bHave_GL_EXT_direct_state_access )
+ {
+ if ( sampler != m_activeTexture )
+ {
+ gGL->glActiveTexture( GL_TEXTURE0 + sampler );
+ m_activeTexture = sampler;
+ }
+
+ gGL->glBindTexture( tex->m_texGLTarget, tex->m_texName );
+ }
+ else
+ {
+ gGL->glBindMultiTextureEXT( GL_TEXTURE0 + sampler, tex->m_texGLTarget, tex->m_texName );
+ }
+ }
+
+ if ( !m_bUseSamplerObjects )
+ {
+ SetSamplerDirty( sampler );
+ }
+}
+
+FORCEINLINE void GLMContext::SetSamplerMinFilter( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_minFilter = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerMagFilter( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_magFilter = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerMipFilter( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_mipFilter = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerAddressU( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ m_samplers[sampler].m_samp.m_packed.m_addressU = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerAddressV( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ m_samplers[sampler].m_samp.m_packed.m_addressV = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerAddressW( int sampler, GLenum Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ m_samplers[sampler].m_samp.m_packed.m_addressW = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerStates( int sampler, GLenum AddressU, GLenum AddressV, GLenum AddressW, GLenum minFilter, GLenum magFilter, GLenum mipFilter )
+{
+ Assert( AddressU < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ Assert( AddressV < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ Assert( AddressW < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) );
+ Assert( minFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS ) );
+ Assert( magFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS ) );
+ Assert( mipFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS ) );
+
+ GLMTexSamplingParams ¶ms = m_samplers[sampler].m_samp;
+ params.m_packed.m_addressU = AddressU;
+ params.m_packed.m_addressV = AddressV;
+ params.m_packed.m_addressW = AddressW;
+ params.m_packed.m_minFilter = minFilter;
+ params.m_packed.m_magFilter = magFilter;
+ params.m_packed.m_mipFilter = mipFilter;
+}
+
+FORCEINLINE void GLMContext::SetSamplerBorderColor( int sampler, DWORD Value )
+{
+ m_samplers[sampler].m_samp.m_borderColor = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerMipMapLODBias( int sampler, DWORD Value )
+{
+ // not currently supported
+}
+
+FORCEINLINE void GLMContext::SetSamplerMaxMipLevel( int sampler, DWORD Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_minLOD = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerMaxAnisotropy( int sampler, DWORD Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_maxAniso = Value;
+}
+
+FORCEINLINE void GLMContext::SetSamplerSRGBTexture( int sampler, DWORD Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_srgb = Value;
+}
+
+FORCEINLINE void GLMContext::SetShadowFilter( int sampler, DWORD Value )
+{
+ Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS ) );
+ m_samplers[sampler].m_samp.m_packed.m_compareMode = Value;
+}
+
+FORCEINLINE void GLMContext::BindIndexBufferToCtx( CGLMBuffer *buff )
+{
+ GLMPRINTF(( "--- GLMContext::BindIndexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 ));
+
+ Assert( !buff || ( buff->m_buffGLTarget == GL_ELEMENT_ARRAY_BUFFER_ARB ) );
+
+ GLuint nGLName = buff ? buff->m_nHandle : 0;
+
+ if ( m_nBoundGLBuffer[ kGLMIndexBuffer] == nGLName )
+ return;
+
+ m_nBoundGLBuffer[ kGLMIndexBuffer] = nGLName;
+ gGL->glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, nGLName );
+}
+
+FORCEINLINE void GLMContext::BindVertexBufferToCtx( CGLMBuffer *buff )
+{
+ GLMPRINTF(( "--- GLMContext::BindVertexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 ));
+
+ Assert( !buff || ( buff->m_buffGLTarget == GL_ARRAY_BUFFER_ARB ) );
+
+ GLuint nGLName = buff ? buff->m_nHandle : 0;
+
+ if ( m_nBoundGLBuffer[ kGLMVertexBuffer] == nGLName )
+ return;
+
+ m_nBoundGLBuffer[ kGLMVertexBuffer] = nGLName;
+ gGL->glBindBufferARB( GL_ARRAY_BUFFER_ARB, nGLName );
+}
+
+FORCEINLINE void GLMContext::SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants )
+{
+ static bool bUseMaxVertexShadeConstantHints = !CommandLine()->CheckParm("-disablemaxvertexshaderconstanthints");
+ if ( bUseMaxVertexShadeConstantHints )
+ {
+ m_nMaxUsedVertexProgramConstantsHint = nMaxConstants;
+ }
+}
+
+struct GLMTestParams
+{
+ GLMContext *m_ctx;
+ int *m_testList; // -1 termed
+
+ bool m_glErrToDebugger;
+ bool m_glErrToConsole;
+
+ bool m_intlErrToDebugger;
+ bool m_intlErrToConsole;
+
+ int m_frameCount; // how many frames to test.
+};
+
+class CShowPixelsParams
+{
+public:
+ GLuint m_srcTexName;
+ int m_width,m_height;
+ bool m_vsyncEnable;
+ bool m_fsEnable; // want receiving view to be full screen. for now, just target the main screen. extend later.
+ bool m_useBlit; // use FBO blit - sending context says it is available.
+ bool m_noBlit; // the back buffer has already been populated by the caller (perhaps via direct MSAA resolve from multisampled RT tex)
+ bool m_onlySyncView; // react to full/windowed state change only, do not present bits
+};
+
+#define kMaxCrawlFrames 100
+#define kMaxCrawlText (kMaxCrawlFrames * 256)
+class CStackCrawlParams
+{
+ public:
+ uint m_frameLimit; // input: max frames to retrieve
+ uint m_frameCount; // output: frames found
+ void *m_crawl[kMaxCrawlFrames]; // call site addresses
+ char *m_crawlNames[kMaxCrawlFrames]; // pointers into text following, one per decoded name
+ char m_crawlText[kMaxCrawlText];
+};
+
+#endif // GLMGR_H
diff --git a/mp/src/public/togl/linuxwin/glmgrbasics.h b/mp/src/public/togl/linuxwin/glmgrbasics.h new file mode 100644 index 00000000..1897ebca --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmgrbasics.h @@ -0,0 +1,308 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgrbasics.h
+// types, common headers, forward declarations, utilities
+//
+//===============================================================================
+
+#ifndef GLMBASICS_H
+#define GLMBASICS_H
+
+#pragma once
+
+#ifdef OSX
+ #include <OpenGL/OpenGL.h>
+ #include <OpenGL/gl.h>
+ #include <OpenGL/glext.h>
+ #include <OpenGL/CGLTypes.h>
+ #include <OpenGL/CGLRenderers.h>
+ #include <OpenGL/CGLCurrent.h>
+ #include <OpenGL/CGLProfiler.h>
+ #include <ApplicationServices/ApplicationServices.h>
+#elif defined(DX_TO_GL_ABSTRACTION)
+ #include <GL/gl.h>
+ #include <GL/glext.h>
+#else
+ #error
+#endif
+
+#include "tier0/platform.h"
+
+#include "bitmap/imageformat.h"
+#include "bitvec.h"
+#include "tier1/checksum_md5.h"
+#include "tier1/utlvector.h"
+#include "tier1/convar.h"
+
+#include <sys/stat.h>
+
+#include "dxabstract_types.h"
+
+struct GLMRect;
+typedef void *PseudoGLContextPtr;
+
+// types
+
+ // 3-d integer box (used for texture lock/unlock etc)
+struct GLMRegion
+{
+ int xmin,xmax;
+ int ymin,ymax;
+ int zmin,zmax;
+};
+
+struct GLMRect // follows GL convention - if coming from the D3D rect you will need to fiddle the Y's
+{
+ int xmin; // left
+ int ymin; // bottom
+ int xmax; // right
+ int ymax; // top
+};
+
+// macros
+
+//#define GLMassert(x) assert(x)
+
+// forward decls
+class GLMgr; // singleton
+class GLMContext; // GL context
+class CGLMContextTester; // testing class
+class CGLMTex;
+class CGLMFBO;
+class CGLMProgram;
+class CGLMBuffer;
+
+
+// utilities
+
+typedef enum
+{
+ // D3D codes
+ eD3D_DEVTYPE,
+ eD3D_FORMAT,
+ eD3D_RTYPE,
+ eD3D_USAGE,
+ eD3D_RSTATE, // render state
+ eD3D_SIO, // D3D shader bytecode
+ eD3D_VTXDECLUSAGE,
+
+ // CGL codes
+ eCGL_RENDID,
+
+ // OpenGL error codes
+ eGL_ERROR,
+
+ // OpenGL enums
+ eGL_ENUM,
+ eGL_RENDERER
+
+} GLMThing_t;
+
+// these will look at the string to guess its flavor: <, >, ---, -M-, -S-
+#ifdef TOGL_DLL_EXPORT
+ DLL_EXPORT const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const
+#else
+ DLL_IMPORT const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const
+#endif
+
+const char* GLMDecodeMask( GLMThing_t type, unsigned long value ); // decode a bitmask
+
+FORCEINLINE void GLMStop( void ) { DXABSTRACT_BREAK_ON_ERROR(); }
+
+void GLMEnableTrace( bool on );
+
+//===============================================================================
+// output functions
+
+// expose these in release now
+// Mimic PIX events so we can decorate debug spew
+DLL_EXPORT void GLMBeginPIXEvent( const char *str );
+DLL_EXPORT void GLMEndPIXEvent( void );
+
+class CScopedGLMPIXEvent
+{
+ CScopedGLMPIXEvent( const CScopedGLMPIXEvent & );
+ CScopedGLMPIXEvent& operator= ( const CScopedGLMPIXEvent & );
+public:
+ inline CScopedGLMPIXEvent( const char *pName ) { GLMBeginPIXEvent( pName ); }
+ inline ~CScopedGLMPIXEvent() { GLMEndPIXEvent( ); }
+};
+
+#if GLMDEBUG
+
+
+//===============================================================================
+// classes
+
+// helper class making function tracking easier to wire up
+
+class GLMFuncLogger
+{
+ public:
+
+ // simple function log
+ GLMFuncLogger( const char *funcName )
+ {
+ m_funcName = funcName;
+ m_earlyOut = false;
+
+ GLMPrintf( ">%s", m_funcName );
+ };
+
+ // more advanced version lets you pass args (i.e. called parameters or anything else of interest)
+ // no macro for this one, since no easy way to pass through the args as well as the funcname
+ GLMFuncLogger( const char *funcName, char *fmt, ... )
+ {
+ m_funcName = funcName;
+ m_earlyOut = false;
+
+ // this acts like GLMPrintf here
+ // all the indent policy is down in GLMPrintfVA
+ // which means we need to inject a ">" at the front of the format string to make this work... sigh.
+
+ char modifiedFmt[2000];
+ modifiedFmt[0] = '>';
+ strcpy( modifiedFmt+1, fmt );
+
+ va_list vargs;
+ va_start(vargs, fmt);
+ GLMPrintfVA( modifiedFmt, vargs );
+ va_end( vargs );
+ }
+
+ ~GLMFuncLogger( )
+ {
+ if (m_earlyOut)
+ {
+ GLMPrintf( "<%s (early out)", m_funcName );
+ }
+ else
+ {
+ GLMPrintf( "<%s", m_funcName );
+ }
+ };
+
+ void EarlyOut( void )
+ {
+ m_earlyOut = true;
+ };
+
+ const char *m_funcName; // set at construction time
+ bool m_earlyOut;
+};
+
+// handy macro to go with the function tracking class
+#define GLM_FUNC GLMFuncLogger _logger_ ( __FUNCTION__ )
+#else
+#define GLM_FUNC tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "%s", __FUNCTION__ )
+#endif
+
+
+// class to keep an in-memory mirror of a file which may be getting edited during run
+class CGLMFileMirror
+{
+public:
+ CGLMFileMirror( char *fullpath ); // just associates mirror with file. if file exists it will be read.
+ //if non existent it will be created with size zero
+ ~CGLMFileMirror( );
+
+ bool HasData( void ); // see if data avail
+ void GetData( char **dataPtr, uint *dataSizePtr ); // read it out
+ void SetData( char *data, uint dataSize ); // put data in (and write it to disk)
+ bool PollForChanges( void ); // check disk copy. If different, read it back in and return true.
+
+ void UpdateStatInfo( void ); // make sure stat info is current for our file
+ void ReadFile( void );
+ void WriteFile( void );
+
+ void OpenInEditor( bool foreground=false ); // pass TRUE if you would like the editor to pop to foreground
+
+ /// how about a "wait for change" method..
+
+ char *m_path; // fullpath to file
+ bool m_exists;
+ struct stat m_stat; // stat results for the file (last time checked)
+
+ char *m_data; // content of file
+ uint m_size; // length of content
+
+};
+
+// class based on the file mirror, that makes it easy to edit them outside the app.
+
+// it receives an initial block of text from the engine, and hashes it. ("orig")
+// it munges it by duplicating all the text after the "!!" line, and appending it in commented form. ("munged")
+// a mirror file is activated, using a filename based on the hash from the orig text.
+// if there is already content on disk matching that filename, use that content *unless* the 'blitz' parameter is set.
+// (i.e. engine is instructing this subsystem to wipe out any old/modified variants of the text)
+
+
+class CGLMEditableTextItem
+{
+public:
+ CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix = NULL ); // create a text blob from text source, optional filename suffix
+ ~CGLMEditableTextItem( );
+
+ bool HasData( void );
+ bool PollForChanges( void ); // return true if stale i.e. you need to get a new edition
+ void GetCurrentText( char **textOut, uint *sizeOut ); // query for read access to the active blob (could be the original, could be external edited copy)
+ void OpenInEditor( bool foreground=false ); // call user attention to this text
+
+ // internal methods
+ void GenHashOfOrigText( void );
+ void GenBaseNameAndFullPath( char *prefix, char *suffix );
+ void GenMungedText( bool fromMirror );
+
+ // members
+ // orig
+ uint m_origSize;
+ char *m_origText; // what was submitted
+ unsigned char m_origDigest[MD5_DIGEST_LENGTH]; // digest of what was submitted
+
+ // munged
+ uint m_mungedSize;
+ char *m_mungedText; // re-processed edition, initial content submission to the file mirror
+
+ // mirror
+ char *m_mirrorBaseName; // generated from the hash of the orig text, plus the label / prefix
+ char *m_mirrorFullPath; // base name
+ CGLMFileMirror *m_mirror; // file mirror itself. holds "official" copy for GetCurrentText to return.
+};
+
+
+// debug font
+extern unsigned char g_glmDebugFontMap[16384];
+
+// class for cracking multi-part text blobs
+// sections are demarcated by beginning-of-line markers submitted in a table by the caller
+
+struct GLMTextSection
+{
+ int m_markerIndex; // based on table of markers passed in to constructor
+ uint m_textOffset; // where is the text - offset
+ int m_textLength; // how big is the section
+};
+
+class CGLMTextSectioner
+{
+public:
+ CGLMTextSectioner( char *text, int textSize, const char **markers ); // constructor finds all the sections
+ ~CGLMTextSectioner( );
+
+ int Count( void ); // how many sections found
+ void GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut );
+ // find section, size, what marker
+ // note that more than one section can be marked similarly.
+ // so policy isn't made here, you walk the sections and decide what to do if there are dupes.
+
+ //members
+
+ //section table
+ CUtlVector< GLMTextSection > m_sectionTable;
+};
+
+void GLMGPUTimestampManagerInit();
+void GLMGPUTimestampManagerDeinit();
+void GLMGPUTimestampManagerTick();
+
+#endif // GLMBASICS_H
diff --git a/mp/src/public/togl/linuxwin/glmgrext.h b/mp/src/public/togl/linuxwin/glmgrext.h new file mode 100644 index 00000000..810d4055 --- /dev/null +++ b/mp/src/public/togl/linuxwin/glmgrext.h @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgrext.h
+// helper file for extension testing and runtime importing of entry points
+//
+//===============================================================================
+
+#pragma once
+
+#ifdef OSX
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#elif defined(DX_TO_GL_ABSTRACTION)
+#include <GL/gl.h>
+#include <GL/glext.h>
+#else
+#error
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+ #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+ #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef ARB_texture_rg
+ #define GL_COMPRESSED_RED 0x8225
+ #define GL_COMPRESSED_RG 0x8226
+ #define GL_RG 0x8227
+ #define GL_RG_INTEGER 0x8228
+ #define GL_R8 0x8229
+ #define GL_R16 0x822A
+ #define GL_RG8 0x822B
+ #define GL_RG16 0x822C
+ #define GL_R16F 0x822D
+ #define GL_R32F 0x822E
+ #define GL_RG16F 0x822F
+ #define GL_RG32F 0x8230
+ #define GL_R8I 0x8231
+ #define GL_R8UI 0x8232
+ #define GL_R16I 0x8233
+ #define GL_R16UI 0x8234
+ #define GL_R32I 0x8235
+ #define GL_R32UI 0x8236
+ #define GL_RG8I 0x8237
+ #define GL_RG8UI 0x8238
+ #define GL_RG16I 0x8239
+ #define GL_RG16UI 0x823A
+ #define GL_RG32I 0x823B
+ #define GL_RG32UI 0x823C
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+ #define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#endif
+
+// unpublished extension enums (thus the "X")
+
+// from EXT_framebuffer_multisample_blit_scaled..
+#define XGL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define XGL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+
+#ifndef GL_TEXTURE_MINIMIZE_STORAGE_APPLE
+#define GL_TEXTURE_MINIMIZE_STORAGE_APPLE 0x85B6
+#endif
+
+#ifndef GL_ALL_COMPLETED_NV
+#define GL_ALL_COMPLETED_NV 0x84F2
+#endif
+
+#ifndef GL_MAP_READ_BIT
+#define GL_MAP_READ_BIT 0x0001
+#endif
+
+#ifndef GL_MAP_WRITE_BIT
+#define GL_MAP_WRITE_BIT 0x0002
+#endif
+
+#ifndef GL_MAP_INVALIDATE_RANGE_BIT
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#endif
+
+#ifndef GL_MAP_INVALIDATE_BUFFER_BIT
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#endif
+
+#ifndef GL_MAP_FLUSH_EXPLICIT_BIT
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#endif
+
+#ifndef GL_MAP_UNSYNCHRONIZED_BIT
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#endif
+
diff --git a/mp/src/public/togl/osx/cglmbuffer.h b/mp/src/public/togl/osx/cglmbuffer.h new file mode 100644 index 00000000..0e40f474 --- /dev/null +++ b/mp/src/public/togl/osx/cglmbuffer.h @@ -0,0 +1,99 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmprogram.h
+// GLMgr buffers (index / vertex)
+// ... maybe add PBO later as well
+//===============================================================================
+
+#ifndef CGLMBUFFER_H
+#define CGLMBUFFER_H
+
+#pragma once
+
+// ext links
+
+// http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt
+
+//===============================================================================
+
+// tokens not in the SDK headers
+
+//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT
+// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9
+//#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+
+enum EGLMBufferType
+{
+ kGLMVertexBuffer,
+ kGLMIndexBuffer,
+ kGLMUniformBuffer, // for bindable uniform
+ kGLMPixelBuffer, // for PBO
+
+ kGLMNumBufferTypes
+};
+
+ // pass this in "options" to constructor to make a dynamic buffer
+#define GLMBufferOptionDynamic 0x00000001
+
+struct GLMBuffLockParams
+{
+ uint m_offset;
+ uint m_size;
+ bool m_nonblocking;
+ bool m_discard;
+};
+
+class CGLMBuffer
+{
+
+public:
+ void Lock( GLMBuffLockParams *params, char **addressOut );
+ void Unlock( void );
+
+//protected:
+ friend class GLMContext; // only GLMContext can make CGLMBuffer objects
+ friend class GLMTester;
+ friend class IDirect3D9;
+ friend class IDirect3DDevice9;
+
+ CGLMBuffer ( GLMContext *ctx, EGLMBufferType type, uint size, uint options );
+ ~CGLMBuffer ( );
+
+ void SetModes ( bool asyncMap, bool explicitFlush, bool force = false );
+ void FlushRange ( uint offset, uint size );
+
+ GLMContext *m_ctx; // link back to parent context
+ EGLMBufferType m_type;
+ uint m_size;
+ GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB
+ GLuint m_name; // name of this program in the context
+ uint m_revision; // bump anytime the size changes or buffer is orphaned
+ bool m_enableAsyncMap; // mirror of the buffer state
+ bool m_enableExplicitFlush; // mirror of the buffer state
+
+ bool m_bound; // true if bound to context
+ bool m_mapped; // is it currently mapped
+ uint m_dirtyMinOffset; // when equal, range is empty
+ uint m_dirtyMaxOffset;
+
+ float *m_lastMappedAddress;
+
+ // --------------------- pseudo-VBO support below here (explicitly for dynamic index buffers)
+ bool m_pseudo; // true if the m_name is 0, and the backing is plain RAM
+
+ // in pseudo mode, there is just one RAM buffer that acts as the backing.
+ // expectation is that this mode would only be used for dynamic indices.
+ // since indices have to be consumed (copied to command stream) prior to return from a drawing call,
+ // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op.
+
+ char *m_pseudoBuf; // storage for pseudo buffer
+};
+
+
+#endif
\ No newline at end of file diff --git a/mp/src/public/togl/osx/cglmfbo.h b/mp/src/public/togl/osx/cglmfbo.h new file mode 100644 index 00000000..ab889af2 --- /dev/null +++ b/mp/src/public/togl/osx/cglmfbo.h @@ -0,0 +1,91 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmfbo.h
+// GLMgr FBO's (render targets)
+//
+//===============================================================================
+
+#ifndef CGLMFBO_H
+#define CGLMFBO_H
+
+#pragma once
+
+#include "togl/rendermechanism.h"
+
+// good FBO references / recaps
+// http://www.songho.ca/opengl/gl_fbo.html
+// http://www.gamedev.net/reference/articles/article2331.asp
+
+// ext links
+
+// http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
+// http://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt
+
+//===============================================================================
+
+// tokens not in the SDK headers
+
+#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT
+ #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9
+#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+
+// implicitly 16 maximum color attachments possible
+enum EGLMFBOAttachment {
+ kAttColor0, kAttColor1, kAttColor2, kAttColor3,
+ kAttColor4, kAttColor5, kAttColor6, kAttColor7,
+ kAttColor8, kAttColor9, kAttColor10, kAttColor11,
+ kAttColor12, kAttColor13, kAttColor14, kAttColor15,
+ kAttDepth, kAttStencil, kAttDepthStencil,
+ kAttCount
+};
+
+struct GLMFBOTexAttachParams
+{
+ CGLMTex *m_tex;
+ int m_face; // keep zero if not cube map
+ int m_mip; // keep zero if notmip mapped
+ int m_zslice; // keep zero if not a 3D tex
+};
+
+class CGLMFBO
+{
+
+public:
+
+protected:
+ friend class GLMContext; // only GLMContext can make CGLMFBO objects
+ friend class GLMTester;
+ friend class CGLMTex;
+
+ friend class IDirect3D9;
+ friend class IDirect3DDevice9;
+
+ CGLMFBO( GLMContext *ctx );
+ ~CGLMFBO( );
+
+ void TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT );
+ void TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT );
+ // you can also pass GL_READ_FRAMEBUFFER_EXT or GL_DRAW_FRAMEBUFFER_EXT to selectively bind the receiving FBO to one or the other.
+
+ void TexScrub( CGLMTex *tex );
+ // search and destroy any attachment for the named texture
+
+ bool IsReady( void ); // aka FBO completeness check - ready to draw
+
+ GLMContext *m_ctx; // link back to parent context
+
+ GLuint m_name; // name of this FBO in the context
+
+ GLMFBOTexAttachParams m_attach[ kAttCount ]; // indexed by EGLMFBOAttachment
+
+ int m_sizeX,m_sizeY;
+};
+
+
+#endif
diff --git a/mp/src/public/togl/osx/cglmprogram.h b/mp/src/public/togl/osx/cglmprogram.h new file mode 100644 index 00000000..8d702c42 --- /dev/null +++ b/mp/src/public/togl/osx/cglmprogram.h @@ -0,0 +1,291 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmprogram.h
+// GLMgr programs (ARBVP/ARBfp)
+//
+//===============================================================================
+
+#ifndef CGLMPROGRAM_H
+#define CGLMPROGRAM_H
+
+#include <sys/stat.h>
+
+#pragma once
+
+// good ARB program references
+// http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html
+// http://petewarden.com/notes/archives/2005/06/fragment_progra_3.html
+
+// ext links
+
+// http://www.opengl.org/registry/specs/ARB/vertex_program.txt
+// http://www.opengl.org/registry/specs/ARB/fragment_program.txt
+// http://www.opengl.org/registry/specs/EXT/gpu_program_parameters.txt
+
+
+//===============================================================================
+
+// tokens not in the SDK headers
+
+//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT
+// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9
+//#endif
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class CGLMShaderPair;
+class CGLMShaderPairCache;
+
+// CGLMProgram can contain two flavors of the same program, one in assembler, one in GLSL.
+// these flavors are pretty different in terms of the API's that are used to activate them -
+// for example, assembler programs can just get bound to the context, whereas GLSL programs
+// have to be linked. To some extent we try to hide that detail inside GLM.
+
+// for now, make CGLMProgram a container, it does not set policy or hold a preference as to which
+// flavor you want to use. GLMContext has to handle that.
+
+enum EGLMProgramType
+{
+ kGLMVertexProgram,
+ kGLMFragmentProgram,
+
+ kGLMNumProgramTypes
+};
+
+enum EGLMProgramLang
+{
+ kGLMARB,
+ kGLMGLSL,
+
+ kGLMNumProgramLangs
+};
+
+struct GLMShaderDesc
+{
+ union
+ {
+ GLuint arb; // ARB program object name
+ GLhandleARB glsl; // GLSL shader object handle (void*)
+ } m_object;
+
+ // these can change if shader text is edited
+ bool m_textPresent; // is this flavor(lang) of text present in the buffer?
+ int m_textOffset; // where is it
+ int m_textLength; // how big
+
+ bool m_compiled; // has this text been through a compile attempt
+ bool m_valid; // and if so, was the compile successful
+
+ int m_slowMark; // has it been flagged during a non native draw batch before. increment every time it's slow.
+
+ int m_highWater; // vount of vec4's in the major uniform array ("vc" on vs, "pc" on ps)
+ // written by dxabstract.... gross!
+};
+
+GLenum GLMProgTypeToARBEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target
+GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target
+
+class CGLMProgram
+{
+public:
+ friend class CGLMShaderPairCache;
+ friend class CGLMShaderPair;
+ friend class GLMContext; // only GLMContext can make CGLMProgram objects
+ friend class GLMTester;
+ friend class IDirect3D9;
+ friend class IDirect3DDevice9;
+
+ //===============================
+
+ // constructor is very light, it just makes one empty program object per flavor.
+ CGLMProgram( GLMContext *ctx, EGLMProgramType type );
+ ~CGLMProgram( );
+
+ void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program
+
+ bool CompileActiveSources ( void ); // compile only the flavors that were provided.
+ bool Compile ( EGLMProgramLang lang );
+ bool CheckValidity ( EGLMProgramLang lang );
+
+ void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that
+
+ void GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut );
+ void GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ); // mmmmmmmm-nnnnnnnn-filename
+
+#if GLMDEBUG
+ bool PollForChanges( void ); // check mirror for changes.
+ void ReloadStringFromEditable( void ); // populate m_string from editable item (react to change)
+ bool SyncWithEditable( void );
+#endif
+
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ EGLMProgramType m_type; // vertex or pixel
+
+ uint m_serial; // serial number for hashing
+
+ char *m_text; // copy of text passed into constructor. Can change if editable shaders is enabled.
+ // note - it can contain multiple flavors, so use CGLMTextSectioner to scan it and locate them
+#if GLMDEBUG
+ CGLMEditableTextItem *m_editable; // editable text item for debugging
+#endif
+
+ GLMShaderDesc m_descs[ kGLMNumProgramLangs ];
+
+ uint m_samplerMask; // (1<<n) mask of sampler active locs, if this is a fragment shader (dxabstract sets this field)
+};
+
+//===============================================================================
+
+struct GLMShaderPairInfo
+{
+ int m_status; // -1 means req'd index was out of bounds (loop stop..) 0 means not present. 1 means present/active.
+
+ char m_vsName[ 128 ];
+ int m_vsStaticIndex;
+ int m_vsDynamicIndex;
+
+ char m_psName[ 128 ];
+ int m_psStaticIndex;
+ int m_psDynamicIndex;
+};
+
+
+class CGLMShaderPair // a container for a linked GLSL shader pair, and metadata obtained post-link
+{
+
+public:
+
+ friend class CGLMProgram;
+ friend class GLMContext;
+ friend class CGLMShaderPairCache;
+
+ //===============================
+
+ // constructor just sets up a GLSL program object and leaves it empty.
+ CGLMShaderPair( GLMContext *ctx );
+ ~CGLMShaderPair( );
+
+ bool SetProgramPair ( CGLMProgram *vp, CGLMProgram *fp );
+ // true result means successful link and query
+
+ bool RefreshProgramPair ( void );
+ // re-link and re-query the uniforms
+
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ CGLMProgram *m_vertexProg;
+ CGLMProgram *m_fragmentProg;
+
+ GLhandleARB m_program; // linked program object
+
+ // need meta data for attribs / samplers / params
+ // actually we only need it for samplers and params.
+ // attributes are hardwired.
+
+ // vertex stage uniforms
+ GLint m_locVertexParams; // "vc" per dx9asmtogl2 convention
+ GLint m_locVertexInteger0; // "i0"
+ GLint m_locVertexBool0; // "b0"
+ GLint m_locVertexBool1; // "b1"
+ GLint m_locVertexBool2; // "b2"
+ GLint m_locVertexBool3; // "b3"
+
+ // fragment stage uniforms
+ GLint m_locFragmentParams; // "pc" per dx9asmtogl2 convention
+ GLint m_locFragmentFakeSRGBEnable; // "flSRGBWrite" - set to 1.0 to effect sRGB encoding on output
+ float m_fakeSRGBEnableValue; // shadow to avoid redundant sets of the m_locFragmentFakeSRGBEnable uniform
+ // init it to -1.0 at link or relink, so it will trip on any legit incoming value (0.0 or 1.0)
+
+ GLint m_locSamplers[ 16 ]; // "sampler0 ... sampler1..."
+
+ // other stuff
+ bool m_valid; // true on successful link
+ bool m_samplersFixed; // set on first draw (can't write the uniforms until the program is in use, and we don't want to mess with cur program inside cglmprogram)
+ uint m_revision; // if this pair is relinked, bump this number.
+};
+
+//===============================================================================
+
+// N-row, M-way associative cache with LRU per row.
+// still needs some metric dump ability and some parameter tuning.
+// extra credit would be to make an auto-tuner.
+
+struct CGLMPairCacheEntry
+{
+ long long m_lastMark; // a mark of zero means an empty entry
+ CGLMProgram *m_vertexProg;
+ CGLMProgram *m_fragmentProg;
+ uint m_extraKeyBits;
+ CGLMShaderPair *m_pair;
+};
+
+class CGLMShaderPairCache // cache for linked GLSL shader pairs
+{
+
+public:
+
+protected:
+ friend class CGLMShaderPair;
+ friend class CGLMProgram;
+ friend class GLMContext;
+
+ //===============================
+
+ CGLMShaderPairCache( GLMContext *ctx );
+ ~CGLMShaderPairCache( );
+
+ CGLMShaderPair *SelectShaderPair ( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits );
+ void QueryShaderPair ( int index, GLMShaderPairInfo *infoOut );
+
+ // shoot down linked pairs that use the program in the arg
+ // return true if any had to be skipped due to conflict with currently bound pair
+ bool PurgePairsWithShader( CGLMProgram *prog );
+
+ // purge everything (when would GLM know how to do this ? at context destroy time, but any other times?)
+ // return true if any had to be skipped due to conflict with currently bound pair
+ bool Purge ( void );
+
+ // stats
+ void DumpStats ( void );
+
+ //===============================
+
+ uint HashRowIndex ( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits );
+ CGLMPairCacheEntry* HashRowPtr ( uint hashRowIndex );
+ void HashRowProbe ( CGLMPairCacheEntry *row, CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int *hitwayOut, int *emptywayOut, int *oldestwayOut );
+ //===============================
+
+ // common stuff
+
+ GLMContext *m_ctx; // link back to parent context
+
+ long long m_mark;
+
+ uint m_rowsLg2;
+ uint m_rows;
+
+ uint m_waysLg2;
+ uint m_ways;
+
+ uint m_entryCount;
+
+ CGLMPairCacheEntry *m_entries; // array[ m_rows ][ m_ways ]
+
+ uint *m_evictions; // array[ m_rows ];
+ uint *m_hits; // array[ m_rows ];
+};
+
+
+#endif
\ No newline at end of file diff --git a/mp/src/public/togl/osx/cglmquery.h b/mp/src/public/togl/osx/cglmquery.h new file mode 100644 index 00000000..1f257ccf --- /dev/null +++ b/mp/src/public/togl/osx/cglmquery.h @@ -0,0 +1,85 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmquery.h
+// GLMgr queries
+//
+//===============================================================================
+
+#ifndef CGLMQUERY_H
+#define CGLMQUERY_H
+
+#pragma once
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class CGLMQuery;
+
+//===============================================================================
+
+enum EGLMQueryType
+{
+ EOcclusion,
+ EFence,
+ EGLMQueryCount
+};
+
+struct GLMQueryParams
+{
+ EGLMQueryType m_type;
+};
+
+class CGLMQuery
+{
+ // leave everything public til it's running
+public:
+ friend class GLMContext; // only GLMContext can make CGLMTex objects
+ friend class IDirect3DDevice9;
+ friend class IDirect3DQuery9;
+
+ GLMContext *m_ctx; // link back to parent context
+ GLMQueryParams m_params; // params created with
+
+ GLuint m_name; // name of the query object per se - could be fence, could be query object ... NOT USED WITH GL_ARB_sync!
+#ifdef HAVE_GL_ARB_SYNC
+ GLsync m_syncobj; // GL_ARB_sync object. NOT USED WITH GL_NV_fence or GL_APPLE_fence!
+#else
+ GLuint m_syncobj;
+#endif
+
+ bool m_started;
+ bool m_stopped;
+ bool m_done;
+
+ bool m_nullQuery; // was gl_nullqueries true at Start time - if so, continue to act like a null query through Stop/IsDone/Complete time
+ // restated - only Start should examine the convar.
+
+ CGLMQuery( GLMContext *ctx, GLMQueryParams *params );
+ ~CGLMQuery( );
+
+ // for an occlusion query:
+ // Start = BeginQuery query-start goes into stream
+ // Stop = EndQuery query-end goes into stream - a fence is also set so we can probe for completion
+ // IsDone = TestFence use the added fence to ask if query-end has passed (i.e. will Complete block?)
+ // Complete = GetQueryObjectuivARB(uint id, enum pname, uint *params) - extract the sample count
+
+ // for a fence query:
+ // Start = SetFence fence goes into command stream
+ // Stop = NOP fences are self finishing - no need to call Stop on a fence
+ // IsDone = TestFence ask if fence passed
+ // Complete = FinishFence
+
+ void Start ( void );
+ void Stop ( void );
+ bool IsDone ( void );
+ void Complete ( uint *result );
+
+ // accessors for the started/stopped state
+ bool IsStarted ( void );
+ bool IsStopped ( void );
+};
+
+
+#endif
diff --git a/mp/src/public/togl/osx/cglmtex.h b/mp/src/public/togl/osx/cglmtex.h new file mode 100644 index 00000000..a48995a0 --- /dev/null +++ b/mp/src/public/togl/osx/cglmtex.h @@ -0,0 +1,273 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// cglmtex.h
+// GLMgr textures
+//
+//===============================================================================
+
+#ifndef CGLMTEX_H
+#define CGLMTEX_H
+
+#pragma once
+
+#include "tier1/utlhash.h"
+#include "tier1/utlmap.h"
+
+//===============================================================================
+
+// forward declarations
+
+class GLMContext;
+class GLMTester;
+class CGLMTexLayoutTable;
+class CGLMTex;
+class CGLMFBO;
+
+class IDirect3DSurface9;
+
+//===============================================================================
+
+struct GLMTexFormatDesc
+{
+ char *m_formatSummary; // for debug visibility
+
+ D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h
+
+ GLenum m_glIntFormat; // GL internal format
+ GLenum m_glIntFormatSRGB; // internal format if SRGB flavor
+ GLenum m_glDataFormat; // GL data format
+ GLenum m_glDataType; // GL data type
+
+ int m_chunkSize; // 1 or 4 - 4 is used for compressed textures
+ int m_bytesPerSquareChunk; // how many bytes for the smallest quantum (m_chunkSize x m_chunkSize)
+ // this description lets us calculate size cleanly without conditional logic for compression
+};
+const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format );
+
+//===============================================================================
+
+// utility function for generating slabs of texels. mostly for test.
+typedef struct
+{
+ // in
+ D3DFORMAT m_format;
+ void *m_dest; // dest address
+ int m_chunkCount; // square chunk count (single texels or compressed blocks)
+ int m_byteCountLimit; // caller expectation of max number of bytes to write out
+ float r,g,b,a; // color desired
+
+ // out
+ int m_bytesWritten;
+} GLMGenTexelParams;
+
+// return true if successful
+bool GLMGenTexels( GLMGenTexelParams *params );
+
+
+//===============================================================================
+
+struct GLMTexLayoutSlice
+{
+ int m_xSize,m_ySize,m_zSize; //texel dimensions of this slice
+ int m_storageOffset; //where in the storage slab does this slice live
+ int m_storageSize; //how much storage does this slice occupy
+};
+
+enum EGLMTexFlags
+{
+ kGLMTexMipped = 0x01,
+ kGLMTexMippedAuto = 0x02,
+ kGLMTexRenderable = 0x04,
+ kGLMTexIsStencil = 0x08,
+ kGLMTexIsDepth = 0x10,
+ kGLMTexSRGB = 0x20,
+ kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D.
+ // actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could
+ // have mipmaps generated.
+};
+
+//===============================================================================
+
+struct GLMTexLayoutKey
+{
+ // input values: held const, these are the hash key for the form map
+ GLenum m_texGLTarget; // flavor of texture: GL_TEXTURE_2D, GL_TEXTURE_3D, GLTEXTURE_CUBE_MAP
+ D3DFORMAT m_texFormat; // D3D texel format
+ unsigned long m_texFlags; // mipped, autogen mips, render target, ... ?
+ unsigned long m_texSamples; // zero for a plain tex, 2/4/6/8 for "MSAA tex" (RBO backed)
+ int m_xSize,m_ySize,m_zSize; // size of base mip
+};
+
+bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b );
+
+#define GLM_TEX_MAX_MIPS 14
+#define GLM_TEX_MAX_FACES 6
+#define GLM_TEX_MAX_SLICES (GLM_TEX_MAX_MIPS * GLM_TEX_MAX_FACES)
+
+struct GLMTexLayout
+{
+ char *m_layoutSummary; // for debug visibility
+
+ // const inputs used for hashing
+ GLMTexLayoutKey m_key;
+
+ // refcount
+ int m_refCount;
+
+ // derived values:
+ GLMTexFormatDesc *m_format; // format specific info
+ int m_mipCount; // derived by starying at base size and working down towards 1x1
+ int m_faceCount; // 1 for 2d/3d, 6 for cubemap
+ int m_sliceCount; // product of faces and mips
+ int m_storageTotalSize; // size of storage slab required
+
+ // slice array
+ GLMTexLayoutSlice m_slices[0]; // dynamically allocated 2-d array [faces][mips]
+};
+
+
+class CGLMTexLayoutTable
+{
+public:
+ CGLMTexLayoutTable();
+
+ GLMTexLayout *NewLayoutRef( GLMTexLayoutKey *key ); // pass in a pointer to layout key - receive ptr to completed layout
+ void DelLayoutRef( GLMTexLayout *layout ); // pass in pointer to completed layout. refcount is dropped.
+
+ void DumpStats( void );
+protected:
+ CUtlMap< GLMTexLayoutKey, GLMTexLayout* > m_layoutMap;
+};
+
+//===============================================================================
+
+// a sampler specifies desired state for drawing on a given sampler index
+// this is the combination of a texture choice and a set of sampler parameters
+// see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx
+
+
+struct GLMTexSamplingParams
+{
+ GLenum m_addressModes[3]; // S, T, R
+ GLfloat m_borderColor[4]; // R,G,B,A
+
+ GLenum m_magFilter;
+ GLenum m_minFilter;
+
+ GLfloat m_mipmapBias;
+ GLint m_minMipLevel;
+ GLint m_maxMipLevel;
+ GLint m_maxAniso;
+ GLenum m_compareMode; // only used for depth and stencil type textures
+ bool m_srgb; // srgb texture read...
+};
+
+struct GLMTexLockParams
+{
+ // input params which identify the slice of interest
+ CGLMTex *m_tex;
+ int m_face;
+ int m_mip;
+
+ // identifies the region of the slice
+ GLMRegion m_region;
+
+ // tells GLM to force re-read of the texels back from GL
+ // i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale"
+ bool m_readback;
+};
+
+struct GLMTexLockDesc
+{
+ GLMTexLockParams m_req; // form of the lock request
+
+ bool m_active; // set true at lock time. cleared at unlock time.
+
+ int m_sliceIndex; // which slice in the layout
+ int m_sliceBaseOffset; // where is that in the texture data
+ int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested
+};
+
+//===============================================================================
+
+#define GLM_SAMPLER_COUNT 16
+
+typedef CBitVec<GLM_SAMPLER_COUNT> CTexBindMask;
+
+enum EGLMTexSliceFlag
+{
+ kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially
+ kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially
+ kSliceLocked = 0x04, // are one or more locks outstanding on this slice
+ kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects)
+};
+
+class CGLMTex
+{
+
+public:
+
+ void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut );
+ void Unlock( GLMTexLockParams *params );
+
+protected:
+ friend class GLMContext; // only GLMContext can make CGLMTex objects
+ friend class GLMTester;
+ friend class CGLMFBO;
+
+ friend class IDirect3DDevice9;
+ friend class IDirect3DBaseTexture9;
+ friend class IDirect3DTexture9;
+ friend class IDirect3DSurface9;
+ friend class IDirect3DCubeTexture9;
+ friend class IDirect3DVolumeTexture9;
+
+ CGLMTex( GLMContext *ctx, GLMTexLayout *layout, GLMTexSamplingParams *sampling, char *debugLabel = NULL );
+ ~CGLMTex( );
+
+ int CalcSliceIndex( int face, int mip );
+ void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut );
+
+ void ApplySamplingParams( GLMTexSamplingParams *params, bool noCheck=FALSE );
+
+ void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true );
+ void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false );
+ // last param lets us send NULL data ptr (only legal with uncompressed formats, beware)
+ // this helps out ResetSRGB.
+
+ void ResetSRGB( bool srgb, bool noDataWrite );
+ // re-specify texture format to match desired sRGB form
+ // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's
+
+ GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout)
+ int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
+ int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL.
+
+ GLMTexSamplingParams m_sampling; // mirror of sampling params currently embodied in the texture
+ // (consult this at draw time, in order to know if changes need to be made)
+
+ GLMContext *m_ctx; // link back to parent context
+
+ GLuint m_texName; // name of this texture in the context
+ bool m_texClientStorage; // was CS selecetd for texture
+ bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet
+
+ GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero)
+ bool m_rboDirty; // has RBO been drawn on - i.e. needs to be blitted back to texture if texture is going to be sampled from
+
+ CTexBindMask m_bindPoints; // true for each place in the parent ctx where currently
+ // bound (indexed via EGLMTexCtxBindingIndex)
+
+ int m_rtAttachCount; // how many RT's have this texture attached somewhere
+
+ char *m_backing; // backing storage if available
+
+ int m_lockCount; // lock reqs are stored in the GLMContext for tracking
+
+ CUtlVector<unsigned char> m_sliceFlags;
+
+ char *m_debugLabel; // strdup() of debugLabel passed in, or NULL
+};
+
+
+#endif
diff --git a/mp/src/public/togl/osx/dxabstract.h b/mp/src/public/togl/osx/dxabstract.h new file mode 100644 index 00000000..682676c7 --- /dev/null +++ b/mp/src/public/togl/osx/dxabstract.h @@ -0,0 +1,804 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+//
+//
+//==================================================================================================
+
+#ifndef DXABSTRACT_H
+#define DXABSTRACT_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "togl/rendermechanism.h"
+
+#include "materialsystem/ishader.h"
+
+// Uncomment this on Windows if you want to compile the Windows GL version.
+// #undef USE_ACTUAL_DX
+
+#ifdef USE_ACTUAL_DX
+
+#ifndef WIN32
+#error sorry man
+#endif
+#ifdef _X360
+#include "d3d9.h"
+#include "d3dx9.h"
+#else
+#include <windows.h>
+#include "../../dx9sdk/include/d3d9.h"
+#include "../../dx9sdk/include/d3dx9.h"
+#endif
+typedef HWND VD3DHWND;
+
+#else
+
+#ifdef WIN32
+#error Gl on win32?
+#endif
+
+#include "tier0/platform.h"
+
+#ifndef DX_TO_GL_ABSTRACTION
+#define DX_TO_GL_ABSTRACTION
+#endif
+
+#include "bitmap/imageformat.h"
+#include "togl/rendermechanism.h"
+
+#ifdef OSX
+extern "C" void Debugger(void);
+#endif
+
+// turn this on to get refcount logging from IUnknown
+#define IUNKNOWN_ALLOC_SPEW 0
+#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0
+
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// DEFINES
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+typedef void* VD3DHWND;
+typedef void* VD3DHANDLE;
+
+
+TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect );
+
+struct TOGL_CLASS IUnknown
+{
+ int m_refcount[2];
+ bool m_mark;
+
+ IUnknown( void )
+ {
+ m_refcount[0] = 1;
+ m_refcount[1] = 0;
+ m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1]));
+ }
+ #endif
+ };
+
+ virtual ~IUnknown( void )
+ {
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUdel (%08x) ",this ));
+ }
+ #endif
+ };
+
+ void AddRef( int which=0, char *comment = NULL )
+ {
+ Assert( which >= 0 );
+ Assert( which < 2 );
+ m_refcount[which]++;
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ;
+ if (!comment)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ }
+ #endif
+ };
+
+ ULONG __stdcall Release( int which=0, char *comment = NULL )
+ {
+ Assert( which >= 0 );
+ Assert( which < 2 );
+
+ //int oldrefcs[2] = { m_refcount[0], m_refcount[1] };
+ bool deleting = false;
+
+ m_refcount[which]--;
+ if ( (!m_refcount[0]) && (!m_refcount[1]) )
+ {
+ deleting = true;
+ }
+
+ #if IUNKNOWN_ALLOC_SPEW
+ if (m_mark)
+ {
+ GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":""));
+ if (!comment)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ }
+ #endif
+
+ if (deleting)
+ {
+ if (m_mark)
+ {
+ GLMPRINTF(("")) ; // place to hang a breakpoint
+ }
+ delete this;
+ return 0;
+ }
+ else
+ {
+ return m_refcount[0];
+ }
+ };
+
+ void SetMark( bool markValue, char *comment=NULL )
+ {
+ #if IUNKNOWN_ALLOC_SPEW
+ if (!m_mark && markValue) // leading edge detect
+ {
+ // print the same thing that the constructor would have printed if it had been marked from the beginning
+ // i.e. it's anticipated that callers asking for marking will do so right at create time
+ GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"..."));
+ }
+ #endif
+
+ m_mark = markValue;
+ }
+};
+
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// INTERFACES
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+struct TOGL_CLASS IDirect3DResource9 : public IUnknown
+{
+ IDirect3DDevice9 *m_device; // parent device
+ D3DRESOURCETYPE m_restype;
+
+ DWORD SetPriority(DWORD PriorityNew);
+};
+
+struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.."
+{
+ D3DSURFACE_DESC m_descZero; // desc of top level.
+ CGLMTex *m_tex; // a CGLMTex can represent all forms of tex
+ int m_srgbFlipCount;
+
+ virtual ~IDirect3DBaseTexture9();
+ D3DRESOURCETYPE GetType();
+ DWORD GetLevelCount();
+ HRESULT GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D"
+{
+ IDirect3DSurface9 *m_surfZero; // surf of top level.
+
+ virtual ~IDirect3DTexture9();
+
+ HRESULT LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
+ HRESULT UnlockRect(UINT Level);
+ HRESULT GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel);
+};
+
+struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map"
+{
+ IDirect3DSurface9 *m_surfZero[6]; // surfs of top level.
+
+ virtual ~IDirect3DCubeTexture9();
+
+ HRESULT GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface);
+ HRESULT GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D"
+{
+ IDirect3DSurface9 *m_surfZero; // surf of top level.
+ D3DVOLUME_DESC m_volDescZero; // volume desc top level
+
+ virtual ~IDirect3DVolumeTexture9();
+
+ HRESULT LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags);
+ HRESULT UnlockBox(UINT Level);
+ HRESULT GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc );
+};
+
+
+// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip.
+// no Create method, these are filled in by the various create surface methods.
+
+struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9
+{
+ virtual ~IDirect3DSurface9();
+
+ HRESULT LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
+ HRESULT UnlockRect();
+ HRESULT GetDesc(D3DSURFACE_DESC *pDesc);
+
+ D3DSURFACE_DESC m_desc;
+ CGLMTex *m_tex;
+ int m_face;
+ int m_mip;
+};
+
+
+
+struct TOGL_CLASS IDirect3D9 : public IUnknown
+{
+public:
+ virtual ~IDirect3D9();
+
+ UINT GetAdapterCount(); //cheese: returns 1
+
+ HRESULT GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps);
+ HRESULT GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier);
+ HRESULT CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat);
+ UINT GetAdapterModeCount (UINT Adapter,D3DFORMAT Format);
+ HRESULT EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode);
+ HRESULT CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed);
+ HRESULT GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode);
+ HRESULT CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat);
+ HRESULT CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels);
+
+ HRESULT CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface);
+};
+
+struct TOGL_CLASS IDirect3DSwapChain9 : public IUnknown
+{
+};
+
+
+
+ // typedef enum D3DDECLUSAGE
+ // {
+ // D3DDECLUSAGE_POSITION = 0,
+ // D3DDECLUSAGE_BLENDWEIGHT = 1,
+ // D3DDECLUSAGE_BLENDINDICES = 2,
+ // D3DDECLUSAGE_NORMAL = 3,
+ // D3DDECLUSAGE_PSIZE = 4,
+ // D3DDECLUSAGE_TEXCOORD = 5,
+ // D3DDECLUSAGE_TANGENT = 6,
+ // D3DDECLUSAGE_BINORMAL = 7,
+ // D3DDECLUSAGE_TESSFACTOR = 8,
+ // D3DDECLUSAGE_POSITIONT = 9,
+ // D3DDECLUSAGE_COLOR = 10,
+ // D3DDECLUSAGE_FOG = 11,
+ // D3DDECLUSAGE_DEPTH = 12,
+ // D3DDECLUSAGE_SAMPLE = 13,
+ // } D3DDECLUSAGE, *LPD3DDECLUSAGE;
+ // Constants
+ //
+ // D3DDECLUSAGE_POSITION
+ // Position data ranging from (-1,-1) to (1,1). Use D3DDECLUSAGE_POSITION with
+ // a usage index of 0 to specify untransformed position for fixed function
+ // vertex processing and the n-patch tessellator. Use D3DDECLUSAGE_POSITION
+ // with a usage index of 1 to specify untransformed position in the fixed
+ // function vertex shader for vertex tweening.
+ //
+ // D3DDECLUSAGE_BLENDWEIGHT
+ // Blending weight data. Use D3DDECLUSAGE_BLENDWEIGHT with a usage index of 0
+ // to specify the blend weights used in indexed and nonindexed vertex
+ // blending.
+ //
+ // D3DDECLUSAGE_BLENDINDICES
+ // Blending indices data. Use D3DDECLUSAGE_BLENDINDICES with a usage index of
+ // 0 to specify matrix indices for indexed paletted skinning.
+ //
+ // D3DDECLUSAGE_NORMAL
+ // Vertex normal data. Use D3DDECLUSAGE_NORMAL with a usage index of 0 to
+ // specify vertex normals for fixed function vertex processing and the n-patch
+ // tessellator. Use D3DDECLUSAGE_NORMAL with a usage index of 1 to specify
+ // vertex normals for fixed function vertex processing for vertex tweening.
+ //
+ // D3DDECLUSAGE_PSIZE
+ // Point size data. Use D3DDECLUSAGE_PSIZE with a usage index of 0 to specify
+ // the point-size attribute used by the setup engine of the rasterizer to
+ // expand a point into a quad for the point-sprite functionality.
+ //
+ // D3DDECLUSAGE_TEXCOORD
+ // Texture coordinate data. Use D3DDECLUSAGE_TEXCOORD, n to specify texture
+ // coordinates in fixed function vertex processing and in pixel shaders prior
+ // to ps_3_0. These can be used to pass user defined data.
+ //
+ // D3DDECLUSAGE_TANGENT
+ // Vertex tangent data.
+ //
+ // D3DDECLUSAGE_BINORMAL
+ // Vertex binormal data.
+ //
+ // D3DDECLUSAGE_TESSFACTOR
+ // Single positive floating point value. Use D3DDECLUSAGE_TESSFACTOR with a
+ // usage index of 0 to specify a tessellation factor used in the tessellation
+ // unit to control the rate of tessellation. For more information about the
+ // data type, see D3DDECLTYPE_FLOAT1.
+ //
+ // D3DDECLUSAGE_POSITIONT
+ // Vertex data contains transformed position data ranging from (0,0) to
+ // (viewport width, viewport height). Use D3DDECLUSAGE_POSITIONT with a usage
+ // index of 0 to specify transformed position. When a declaration containing
+ // this is set, the pipeline does not perform vertex processing.
+ //
+ // D3DDECLUSAGE_COLOR
+ // Vertex data contains diffuse or specular color. Use D3DDECLUSAGE_COLOR with
+ // a usage index of 0 to specify the diffuse color in the fixed function
+ // vertex shader and pixel shaders prior to ps_3_0. Use D3DDECLUSAGE_COLOR
+ // with a usage index of 1 to specify the specular color in the fixed function
+ // vertex shader and pixel shaders prior to ps_3_0.
+ //
+ // D3DDECLUSAGE_FOG
+ // Vertex data contains fog data. Use D3DDECLUSAGE_FOG with a usage index of 0
+ // to specify a fog blend value used after pixel shading finishes. This
+ // applies to pixel shaders prior to version ps_3_0.
+ //
+ // D3DDECLUSAGE_DEPTH
+ // Vertex data contains depth data.
+ //
+ // D3DDECLUSAGE_SAMPLE
+ // Vertex data contains sampler data. Use D3DDECLUSAGE_SAMPLE with a usage
+ // index of 0 to specify the displacement value to look up. It can be used
+ // only with D3DDECLUSAGE_LOOKUPPRESAMPLED or D3DDECLUSAGE_LOOKUP.
+
+ //note the form of the list terminator..
+
+ // #define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
+ // typedef struct _D3DVERTEXELEMENT9
+ // {
+ // WORD Stream; // Stream index
+ // WORD Offset; // Offset in the stream in bytes
+ // BYTE Type; // Data type
+ // BYTE Method; // Processing method
+ // BYTE Usage; // Semantics
+ // BYTE UsageIndex; // Semantic index
+ // } D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;
+
+#define MAX_D3DVERTEXELEMENTS 16
+
+struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown
+{
+//public:
+ uint m_elemCount;
+ D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ];
+
+ virtual ~IDirect3DVertexDeclaration9();
+};
+
+struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown
+{
+//public:
+ D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT
+ GLMContext *m_ctx;
+ CGLMQuery *m_query;
+
+ virtual ~IDirect3DQuery9();
+
+ HRESULT Issue(DWORD dwIssueFlags);
+ HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags);
+};
+
+struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown
+{
+//public:
+ GLMContext *m_ctx;
+ CGLMBuffer *m_vtxBuffer;
+ D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc
+
+ virtual ~IDirect3DVertexBuffer9();
+ HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
+ HRESULT Unlock();
+ HRESULT UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
+
+};
+
+struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown
+{
+//public:
+ GLMContext *m_ctx;
+ CGLMBuffer *m_idxBuffer;
+ D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc
+
+ virtual ~IDirect3DIndexBuffer9();
+
+ HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
+ HRESULT Unlock();
+ HRESULT UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
+ HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc);
+};
+
+struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown
+{
+//public:
+ CGLMProgram *m_pixProgram;
+ uint m_pixHighWater; // count of active constant slots referenced by shader.
+ uint m_pixSamplerMask; // (1<<n) mask of samplers referemnced by this pixel shader
+ // this can help FlushSamplers avoid SRGB flipping on textures not being referenced...
+
+ virtual ~IDirect3DPixelShader9();
+};
+
+struct TOGL_CLASS IDirect3DVertexShader9 : public IDirect3DResource9 //was IUnknown
+{
+//public:
+ CGLMProgram *m_vtxProgram;
+ uint m_vtxHighWater; // count of active constant slots referenced by shader.
+ unsigned char m_vtxAttribMap[16]; // high nibble is usage, low nibble is usageindex, array position is attrib number
+
+ virtual ~IDirect3DVertexShader9();
+
+};
+
+struct TOGL_CLASS ID3DXMatrixStack : public IUnknown
+{
+//public:
+ CUtlVector<D3DMATRIX> m_stack;
+ int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases.
+
+ HRESULT Create( void );
+
+ D3DXMATRIX* GetTop();
+ void Push();
+ void Pop();
+ void LoadIdentity();
+ void LoadMatrix( const D3DXMATRIX *pMat );
+ void MultMatrix( const D3DXMATRIX *pMat );
+ void MultMatrixLocal( const D3DXMATRIX *pMat );
+ HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z);
+
+ // Left multiply the current matrix with the computed rotation
+ // matrix, counterclockwise about the given axis with the given angle.
+ // (rotation is about the local origin of the object)
+ HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle);
+
+ // Left multiply the current matrix with the computed translation
+ // matrix. (transformation is about the local origin of the object)
+ HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z);
+};
+typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK;
+
+struct TOGL_CLASS IDirect3DDevice9 : public IUnknown
+{
+public:
+ // members
+
+ IDirect3DDevice9Params m_params; // mirror of the creation inputs
+
+ // D3D flavor stuff
+ IDirect3DSurface9 *m_rtSurfaces[16]; // current color RT surfaces. [0] is initially == m_defaultColorSurface
+ IDirect3DSurface9 *m_dsSurface; // current DS RT surface. can be changed!
+
+ IDirect3DSurface9 *m_defaultColorSurface; // default color surface.
+ IDirect3DSurface9 *m_defaultDepthStencilSurface; // queried by GetDepthStencilSurface.
+
+ IDirect3DVertexDeclaration9 *m_vertDecl; // Set by SetVertexDeclaration...
+ D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource..
+ D3DIndexDesc m_indices; // Set by SetIndices..
+
+ IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader...
+ IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader...
+
+ IDirect3DBaseTexture9 *m_textures[16]; // set by SetTexture... NULL if stage inactive
+ D3DSamplerDesc m_samplers[16]; // set by SetSamplerState..
+ // GLM flavor stuff
+ GLMContext *m_ctx;
+ CGLMFBO *m_drawableFBO; // this FBO should have all the attachments set to match m_rtSurfaces and m_dsSurface.
+
+ // GL state
+ struct
+ {
+ // render state buckets
+ GLAlphaTestEnable_t m_AlphaTestEnable;
+ GLAlphaTestFunc_t m_AlphaTestFunc;
+
+ GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable;
+
+ GLDepthTestEnable_t m_DepthTestEnable;
+ GLDepthMask_t m_DepthMask;
+ GLDepthFunc_t m_DepthFunc;
+
+ GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes];
+ GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes];
+
+ GLColorMaskSingle_t m_ColorMaskSingle;
+ GLColorMaskMultiple_t m_ColorMaskMultiple;
+
+ GLCullFaceEnable_t m_CullFaceEnable;
+ GLCullFrontFace_t m_CullFrontFace;
+ GLPolygonMode_t m_PolygonMode;
+ GLDepthBias_t m_DepthBias;
+ GLScissorEnable_t m_ScissorEnable;
+ GLScissorBox_t m_ScissorBox;
+ GLViewportBox_t m_ViewportBox;
+ GLViewportDepthRange_t m_ViewportDepthRange;
+
+ GLBlendEnable_t m_BlendEnable;
+ GLBlendFactor_t m_BlendFactor;
+ GLBlendEquation_t m_BlendEquation;
+ GLBlendColor_t m_BlendColor;
+ GLBlendEnableSRGB_t m_BlendEnableSRGB;
+
+ GLStencilTestEnable_t m_StencilTestEnable;
+ GLStencilFunc_t m_StencilFunc;
+ GLStencilOp_t m_StencilOp;
+ GLStencilWriteMask_t m_StencilWriteMask;
+
+ GLClearColor_t m_ClearColor;
+ GLClearDepth_t m_ClearDepth;
+ GLClearStencil_t m_ClearStencil;
+
+ bool m_FogEnable; // not really pushed to GL, just latched here
+
+ // samplers
+ GLMTexSamplingParams m_samplers[ 16 ];
+
+ // bindings...hmmm...
+
+ // dirty-bits
+ uint m_stateDirtyMask; // covers the state blocks, indexed by 1<<n, n = EGLMStateBlockType
+ uint m_samplerDirtyMask; // covers the samplers, indexed 1<<n, n = sampler index
+ } gl;
+
+ // methods
+
+public:
+ virtual ~IDirect3DDevice9();
+
+ // Create call invoked from IDirect3D9
+ HRESULT Create( IDirect3DDevice9Params *params );
+
+ //
+ // Basics
+ //
+ HRESULT Reset(D3DPRESENT_PARAMETERS* pPresentationParameters);
+ HRESULT SetViewport(CONST D3DVIEWPORT9* pViewport);
+ HRESULT GetViewport(D3DVIEWPORT9* pViewport);
+ HRESULT BeginScene();
+ HRESULT Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
+ HRESULT EndScene();
+ HRESULT Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
+
+ // textures
+ HRESULT CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+
+ HRESULT SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture);
+ HRESULT GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture);
+
+ // render targets, color and depthstencil, surfaces, blit
+ HRESULT CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
+ HRESULT SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget);
+ HRESULT GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget);
+
+ HRESULT CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
+
+ HRESULT CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
+ HRESULT SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil);
+ HRESULT GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface);
+
+ HRESULT GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface); // ? is anyone using this ?
+ HRESULT GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface);
+ HRESULT StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter);
+
+ // pixel shaders
+ HRESULT CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *debugLabel = NULL);
+ HRESULT SetPixelShader(IDirect3DPixelShader9* pShader);
+ HRESULT SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+ HRESULT SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
+ HRESULT SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
+
+ // vertex shaders
+ HRESULT CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader, const char *pShaderName, char *debugLabel = NULL);
+ HRESULT SetVertexShader(IDirect3DVertexShader9* pShader);
+ HRESULT SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
+ HRESULT SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
+ HRESULT SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
+
+ // POSIX only - preheating for a specific vertex/pixel shader pair - trigger GLSL link inside GLM
+ HRESULT LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps );
+ HRESULT QueryShaderPair( int index, GLMShaderPairInfo *infoOut );
+
+ // vertex buffers
+ HRESULT CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl);
+ HRESULT SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl);
+
+ HRESULT SetFVF(DWORD FVF); // we might not be using these ?
+ HRESULT GetFVF(DWORD* pFVF);
+
+ HRESULT CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle);
+ HRESULT SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
+
+ // index buffers
+ HRESULT CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle);
+ HRESULT SetIndices(IDirect3DIndexBuffer9* pIndexData);
+
+ // response to retired objects (when refcount goes to zero and they self-delete..)
+ void ReleasedTexture ( IDirect3DBaseTexture9 *baseTex ); // called from texture destructor - need to scrub samplers
+ void ReleasedSurface ( IDirect3DSurface9 *surface ); // called from any surface destructor - need to scrub RT table if an RT
+ void ReleasedPixelShader ( IDirect3DPixelShader9 *pixelShader ); // called from IDirect3DPixelShader9 destructor
+ void ReleasedVertexShader ( IDirect3DVertexShader9 *vertexShader ); // called from IDirect3DVertexShader9 destructor
+ void ReleasedVertexBuffer ( IDirect3DVertexBuffer9 *vertexBuffer ); // called from IDirect3DVertexBuffer9 destructor
+ void ReleasedIndexBuffer ( IDirect3DIndexBuffer9 *indexBuffer ); // called from IDirect3DIndexBuffer9 destructor
+ void ReleasedQuery ( IDirect3DQuery9 *query ); // called from IDirect3DQuery9 destructor
+
+ // State management.
+ HRESULT SetRenderStateInline(D3DRENDERSTATETYPE State,DWORD Value);
+ HRESULT SetRenderStateConstInline(D3DRENDERSTATETYPE State,DWORD Value);
+ HRESULT SetRenderState(D3DRENDERSTATETYPE State,DWORD Value);
+ HRESULT SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
+
+
+ // Flushing changes to GL
+ HRESULT FlushStates( uint mask );
+ HRESULT FlushSamplers( uint mask ); // push SetRenderState and SetSamplerState changes
+ HRESULT FlushIndexBindings( void ); // push index buffer (set index ptr)
+ HRESULT FlushVertexBindings( uint baseVertexIndex ); // push vertex streams (set attrib ptrs)
+ HRESULT FlushGLM( void );
+
+ // Draw.
+ HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount);
+ HRESULT DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount);
+ HRESULT DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride);
+
+ // misc
+ BOOL ShowCursor(BOOL bShow);
+ HRESULT ValidateDevice(DWORD* pNumPasses);
+ HRESULT SetMaterial(CONST D3DMATERIAL9* pMaterial);
+ HRESULT LightEnable(DWORD Index,BOOL Enable);
+ HRESULT SetScissorRect(CONST RECT* pRect);
+ HRESULT CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery);
+ HRESULT GetDeviceCaps(D3DCAPS9* pCaps);
+ HRESULT TestCooperativeLevel();
+ HRESULT EvictManagedResources();
+ HRESULT SetLight(DWORD Index,CONST D3DLIGHT9*);
+ void SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp);
+
+ void SaveGLState();
+ void RestoreGLState();
+
+ // Talk to JasonM about this one. It's tricky in GL.
+ HRESULT SetClipPlane(DWORD Index,CONST float* pPlane);
+
+ //
+ //
+ // **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+ //
+ //
+ HRESULT SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix);
+ HRESULT SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value);
+
+ void AcquireThreadOwnership( );
+ void ReleaseThreadOwnership( );
+ inline DWORD GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
+
+};
+
+struct ID3DXInclude
+{
+ virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) = 0;
+ virtual HRESULT Close(LPCVOID pData) = 0;
+};
+typedef ID3DXInclude* LPD3DXINCLUDE;
+
+
+struct TOGL_CLASS ID3DXBuffer : public IUnknown
+{
+ void* GetBufferPointer();
+ DWORD GetBufferSize();
+};
+
+typedef ID3DXBuffer* LPD3DXBUFFER;
+
+class TOGL_CLASS ID3DXConstantTable : public IUnknown
+{
+};
+typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE;
+
+
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// D3DX stuff.
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice );
+
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 );
+TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack);
+TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * );
+
+TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ pOut->x = pV1->x - pV2->x;
+ pOut->y = pV1->y - pV2->y;
+ pOut->z = pV1->z - pV2->z;
+ return pOut;
+}
+
+TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ D3DXVECTOR3 v;
+
+ v.x = pV1->y * pV2->z - pV1->z * pV2->y;
+ v.y = pV1->z * pV2->x - pV1->x * pV2->z;
+ v.z = pV1->x * pV2->y - pV1->y * pV2->x;
+
+ *pOut = v;
+ return pOut;
+}
+
+TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
+{
+ return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z;
+}
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP);
+
+TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM );
+
+
+TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
+
+// Build an ortho projection matrix. (right-handed)
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf );
+
+TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf );
+
+// Transform a plane by a matrix. The vector (a,b,c) must be normal.
+// M should be the inverse transpose of the transformation desired.
+TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM );
+
+TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion);
+
+TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions );
+
+TOGL_INTERFACE HRESULT D3DXCompileShader(
+ LPCSTR pSrcData,
+ UINT SrcDataLen,
+ CONST D3DXMACRO* pDefines,
+ LPD3DXINCLUDE pInclude,
+ LPCSTR pFunctionName,
+ LPCSTR pProfile,
+ DWORD Flags,
+ LPD3DXBUFFER* ppShader,
+ LPD3DXBUFFER* ppErrorMsgs,
+ LPD3DXCONSTANTTABLE* ppConstantTable);
+
+
+#endif // USE_ACTUAL_DX
+
+// fake D3D usage constant for SRGB tex creation
+#define D3DUSAGE_TEXTURE_SRGB (0x80000000L)
+
+#endif // DXABSTRACT_H
diff --git a/mp/src/public/togl/osx/dxabstract_types.h b/mp/src/public/togl/osx/dxabstract_types.h new file mode 100644 index 00000000..7df586cd --- /dev/null +++ b/mp/src/public/togl/osx/dxabstract_types.h @@ -0,0 +1,1710 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// dxabstract_types.h
+//
+//==================================================================================================
+#ifndef DXABSTRACT_TYPES_H
+#define DXABSTRACT_TYPES_H
+
+#pragma once
+
+#if GL_BATCH_PERF_ANALYSIS
+ class simple_bitmap;
+#endif
+
+struct IUnknown;
+struct IDirect3D9;
+struct IDirect3DDevice9;
+struct IDirect3DResource9;
+struct IDirect3DBaseTexture9;
+struct IDirect3DTexture9;
+struct IDirect3DCubeTexture9;
+struct IDirect3DVolumeTexture9;
+struct IDirect3DSurface9;
+struct IDirect3DVertexDeclaration9;
+struct IDirect3DQuery9;
+struct IDirect3DVertexBuffer9;
+struct IDirect3DIndexBuffer9;
+struct IDirect3DPixelShader9;
+struct IDirect3DVertexShader9;
+struct IDirect3DDevice9Params;
+
+class GLMContext;
+struct GLMRect;
+struct GLMShaderPairInfo;
+class CGLMBuffer;
+class CGLMQuery;
+class CGLMTex;
+class CGLMProgram;
+class CGLMFBO;
+
+#ifdef TOGL_DLL_EXPORT
+ #define TOGL_INTERFACE DLL_EXPORT
+ #define TOGL_OVERLOAD DLL_GLOBAL_EXPORT
+ #define TOGL_CLASS DLL_CLASS_EXPORT
+ #define TOGL_GLOBAL DLL_GLOBAL_EXPORT
+#else
+ #define TOGL_INTERFACE DLL_IMPORT
+ #define TOGL_OVERLOAD DLL_GLOBAL_IMPORT
+ #define TOGL_CLASS DLL_CLASS_IMPORT
+ #define TOGL_GLOBAL DLL_GLOBAL_IMPORT
+#endif
+
+#define TOGLMETHODCALLTYPE __stdcall
+//#define TOGLMETHODCALLTYPE
+
+#define DXABSTRACT_BREAK_ON_ERROR() DebuggerBreak()
+
+typedef void* VD3DHWND;
+typedef void* VD3DHANDLE;
+
+#define MAKEFOURCC(ch0, ch1, ch2, ch3) ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
+
+//
+//
+// Stuff that would be in windows.h
+//
+//
+#if !defined(_WINNT_)
+
+ typedef int INT;
+ typedef unsigned long ULONG;
+ typedef long LONG;
+ typedef float FLOAT;
+ typedef unsigned short WORD;
+ typedef long long LONGLONG;
+ typedef unsigned int UINT;
+ typedef long HRESULT;
+ typedef unsigned char BYTE;
+ #define CONST const
+
+ #if defined(POSIX)
+ typedef size_t ULONG_PTR;
+ #else
+ typedef unsigned long ULONG_PTR;
+ #endif
+
+ typedef ULONG_PTR SIZE_T;
+
+ typedef const char* LPCSTR;
+ typedef char* LPSTR;
+#ifndef OSX
+ typedef unsigned int DWORD;
+ typedef DWORD* LPDWORD;
+#endif
+
+
+ #define ZeroMemory RtlZeroMemory
+ #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
+
+ typedef union _LARGE_INTEGER
+ {
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+ } LARGE_INTEGER;
+
+ typedef struct _GUID
+ {
+ bool operator==( const struct _GUID &other ) const;
+
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+ } GUID;
+
+ typedef struct _RECT
+ {
+ int left;
+ int top;
+ int right;
+ int bottom;
+ } RECT;
+
+ typedef struct tagPOINT
+ {
+ LONG x;
+ LONG y;
+ } POINT, *PPOINT, *LPPOINT;
+
+ typedef struct _MEMORYSTATUS
+ {
+ DWORD dwLength;
+ SIZE_T dwTotalPhys;
+ } MEMORYSTATUS, *LPMEMORYSTATUS;
+
+ typedef DWORD COLORREF;
+ #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
+
+ #define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
+
+
+// Mac header files like to define these
+#ifdef S_FALSE
+#undef S_FALSE
+#endif
+#ifdef S_OK
+#undef S_OK
+#endif
+#ifdef E_FAIL
+#undef E_FAIL
+#endif
+#ifdef E_OUTOFMEMORY
+#undef E_OUTOFMEMORY
+#endif
+#ifdef FAILED
+#undef FAILED
+#endif
+#ifdef SUCCEEDED
+#undef SUCCEEDED
+#endif
+
+ #define S_FALSE ((HRESULT)0x00000001L)
+ #define S_OK 0
+ #define E_FAIL ((HRESULT)0x80004005L)
+ #define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+
+ #define FAILED(hr) ((HRESULT)(hr) < 0)
+ #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
+
+ struct RGNDATA
+ {
+ };
+
+ typedef const void* LPCVOID;
+#endif
+
+//-----------------------------------------------------------------------------
+
+typedef enum _D3DFORMAT D3DFORMAT;
+
+#define D3DSI_OPCODE_MASK 0x0000FFFF
+#define D3DSP_TEXTURETYPE_MASK 0x78000000
+
+#define D3DUSAGE_AUTOGENMIPMAP 0x00000400L
+#define D3DSP_DCL_USAGE_MASK 0x0000000f
+
+#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000
+#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16
+
+
+/* Flags to construct D3DRS_COLORWRITEENABLE */
+#define D3DCOLORWRITEENABLE_RED (1L<<0)
+#define D3DCOLORWRITEENABLE_GREEN (1L<<1)
+#define D3DCOLORWRITEENABLE_BLUE (1L<<2)
+#define D3DCOLORWRITEENABLE_ALPHA (1L<<3)
+
+#define D3DSGR_NO_CALIBRATION 0x00000000L
+
+#define D3DXINLINE inline
+
+#define D3D_SDK_VERSION 32
+
+#define _FACD3D 0x876
+#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code )
+
+#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150)
+#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152)
+#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154)
+#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153)
+#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156)
+#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087)
+#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380)
+#define D3D_OK S_OK
+
+#define D3DPRESENT_RATE_DEFAULT 0x00000000
+
+//
+// DevCaps
+//
+// we need to see who in Source land is interested in these values, as dxabstract is currently reporting zero for the whole Caps word
+#define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */
+#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */
+#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY 0x00000080L /* Device can use TL buffers from video memory */
+#define D3DDEVCAPS_TEXTURESYSTEMMEMORY 0x00000100L /* Device can texture from system memory */
+#define D3DDEVCAPS_TEXTUREVIDEOMEMORY 0x00000200L /* Device can texture from device memory */
+#define D3DDEVCAPS_DRAWPRIMTLVERTEX 0x00000400L /* Device can draw TLVERTEX primitives */
+#define D3DDEVCAPS_CANRENDERAFTERFLIP 0x00000800L /* Device can render without waiting for flip to complete */
+#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000L /* Device can texture from nonlocal video memory */
+#define D3DDEVCAPS_SEPARATETEXTUREMEMORIES 0x00004000L /* Device is texturing from separate memory pools */
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */
+#define D3DDEVCAPS_CANBLTSYSTONONLOCAL 0x00020000L /* Device supports a Tex Blt from system memory to non-local vidmem */
+#define D3DDEVCAPS_HWRASTERIZATION 0x00080000L /* Device has HW acceleration for rasterization */
+#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */
+#define D3DDEVCAPS_QUINTICRTPATCHES 0x00200000L /* Device supports quintic Beziers and BSplines */
+#define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */
+#define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */
+
+//
+// PrimitiveMiscCaps
+//
+#define D3DPMISCCAPS_MASKZ 0x00000002L
+#define D3DPMISCCAPS_CULLNONE 0x00000010L
+#define D3DPMISCCAPS_CULLCW 0x00000020L
+#define D3DPMISCCAPS_CULLCCW 0x00000040L
+#define D3DPMISCCAPS_COLORWRITEENABLE 0x00000080L
+#define D3DPMISCCAPS_CLIPPLANESCALEDPOINTS 0x00000100L /* Device correctly clips scaled points to clip planes */
+#define D3DPMISCCAPS_CLIPTLVERTS 0x00000200L /* device will clip post-transformed vertex primitives */
+#define D3DPMISCCAPS_TSSARGTEMP 0x00000400L /* device supports D3DTA_TEMP for temporary register */
+#define D3DPMISCCAPS_BLENDOP 0x00000800L /* device supports D3DRS_BLENDOP */
+#define D3DPMISCCAPS_NULLREFERENCE 0x00001000L /* Reference Device that doesnt render */
+#define D3DPMISCCAPS_PERSTAGECONSTANT 0x00008000L /* Device supports per-stage constants */
+#define D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 0x00040000L /* Device supports different bit depths for MRT */
+#define D3DPMISCCAPS_FOGVERTEXCLAMPED 0x00100000L /* Device clamps fog blend factor per vertex */
+
+// Flags field for Issue
+#define D3DISSUE_END (1 << 0) // Tells the runtime to issue the end of a query, changing it's state to "non-signaled".
+#define D3DISSUE_BEGIN (1 << 1) // Tells the runtime to issue the beginng of a query.
+
+
+#define D3DPRESENT_INTERVAL_ONE 0x00000001L
+#define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L
+
+/*
+ * Options for clearing
+ */
+#define D3DCLEAR_TARGET 0x00000001l /* Clear target surface */
+#define D3DCLEAR_ZBUFFER 0x00000002l /* Clear target z buffer */
+#define D3DCLEAR_STENCIL 0x00000004l /* Clear stencil planes */
+
+
+#define D3DENUM_WHQL_LEVEL 0x00000002L
+
+
+
+
+#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation
+ in programmable and fixed function pixel shaders */
+#define D3DDEVCAPS2_STREAMOFFSET 0x00000001L /* Device supports offsets in streams. Must be set by DX9 drivers */
+
+#define D3DDEVCAPS_PUREDEVICE 0x00100000L /* Device supports D3DCREATE_PUREDEVICE */
+
+#define D3DCREATE_PUREDEVICE 0x00000010L
+#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L
+#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L
+#define D3DCREATE_FPU_PRESERVE 0x00000002L
+#define D3DPRASTERCAPS_FOGRANGE 0x00010000L
+#define D3DPRASTERCAPS_FOGTABLE 0x00000100L
+#define D3DPRASTERCAPS_FOGVERTEX 0x00000080L
+#define D3DPRASTERCAPS_WFOG 0x00100000L
+#define D3DPRASTERCAPS_ZFOG 0x00200000L
+#define D3DPRASTERCAPS_MIPMAPLODBIAS 0x00002000L
+#define D3DPRASTERCAPS_WBUFFER 0x00040000L
+#define D3DPRASTERCAPS_ZTEST 0x00000010L
+
+//
+// Caps2
+//
+#define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L
+#define D3DPRASTERCAPS_SCISSORTEST 0x01000000L
+#define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */
+#define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */
+#define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */
+#define D3DCREATE_MULTITHREADED 0x00000004L
+#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L /* Device can support transformation and lighting in hardware and DRAWPRIMITIVES2EX must be also */
+#define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L
+#define D3DPTFILTERCAPS_MAGFANISOTROPIC 0x04000000L
+#define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */
+#define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */
+#define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L
+#define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */
+#define D3DTEXOPCAPS_ADD 0x00000040L
+#define D3DTEXOPCAPS_MODULATE2X 0x00000010L
+#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L
+#define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L
+#define D3DVTXPCAPS_TEXGEN_SPHEREMAP 0x00000100L /* device supports D3DTSS_TCI_SPHEREMAP */
+#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L
+
+// The following usages are valid only for querying CheckDeviceFormat
+#define D3DUSAGE_QUERY_SRGBREAD (0x00010000L)
+#define D3DUSAGE_QUERY_FILTER (0x00020000L)
+#define D3DUSAGE_QUERY_SRGBWRITE (0x00040000L)
+#define D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING (0x00080000L)
+#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L)
+
+/* Usages for Vertex/Index buffers */
+#define D3DUSAGE_WRITEONLY (0x00000008L)
+#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L)
+#define D3DUSAGE_DONOTCLIP (0x00000020L)
+#define D3DUSAGE_POINTS (0x00000040L)
+#define D3DUSAGE_RTPATCHES (0x00000080L)
+#define D3DUSAGE_NPATCHES (0x00000100L)
+
+
+// Flags field for GetData
+#define D3DGETDATA_FLUSH (1 << 0) // Tells the runtime to flush if the query is outstanding.
+
+#define D3DFVF_XYZ 0x002
+
+
+#define D3DTA_SELECTMASK 0x0000000f // mask for arg selector
+#define D3DTA_DIFFUSE 0x00000000 // select diffuse color (read only)
+#define D3DTA_CURRENT 0x00000001 // select stage destination register (read/write)
+#define D3DTA_TEXTURE 0x00000002 // select texture color (read only)
+#define D3DTA_TFACTOR 0x00000003 // select D3DRS_TEXTUREFACTOR (read only)
+#define D3DTA_SPECULAR 0x00000004 // select specular color (read only)
+#define D3DTA_TEMP 0x00000005 // select temporary register color (read/write)
+#define D3DTA_CONSTANT 0x00000006 // select texture stage constant
+#define D3DTA_COMPLEMENT 0x00000010 // take 1.0 - x (read modifier)
+#define D3DTA_ALPHAREPLICATE 0x00000020 // replicate alpha to color components (read modifier)
+
+
+#define D3DUSAGE_RENDERTARGET (0x00000001L)
+#define D3DUSAGE_QUERY_VERTEXTEXTURE (0x00100000L)
+#define D3DUSAGE_QUERY_FILTER (0x00020000L)
+#define D3DUSAGE_DEPTHSTENCIL (0x00000002L)
+#define D3DUSAGE_WRITEONLY (0x00000008L)
+#define D3DUSAGE_SOFTWAREPROCESSING (0x00000010L)
+#define D3DUSAGE_DYNAMIC (0x00000200L)
+
+#define D3DSI_INSTLENGTH_MASK 0x0F000000
+#define D3DSI_INSTLENGTH_SHIFT 24
+#define D3DSP_TEXTURETYPE_SHIFT 27
+#define D3DSP_REGTYPE_SHIFT 28
+#define D3DSP_REGTYPE_SHIFT2 8
+#define D3DSP_REGTYPE_MASK 0x70000000
+#define D3DSP_REGTYPE_MASK2 0x00001800
+
+#define D3DSP_REGNUM_MASK 0x000007FF
+
+#define D3DSP_DSTMOD_SHIFT 20
+#define D3DSP_DSTMOD_MASK 0x00F00000
+#define D3DSPDM_MSAMPCENTROID (4<<D3DSP_DSTMOD_SHIFT) // Relevant to multisampling only:
+ // When the pixel center is not covered, sample
+ // attribute or compute gradients/LOD
+ // using multisample "centroid" location.
+ // "Centroid" is some location within the covered
+ // region of the pixel.
+
+#define D3DXSHADER_DEBUG (1 << 0)
+#define D3DXSHADER_AVOID_FLOW_CONTROL (1 << 9)
+
+
+#define D3DLOCK_READONLY 0x00000010L
+#define D3DLOCK_DISCARD 0x00002000L
+#define D3DLOCK_NOOVERWRITE 0x00001000L
+#define D3DLOCK_NOSYSLOCK 0x00000800L
+
+#define D3DLOCK_NO_DIRTY_UPDATE 0x00008000L
+
+
+#define D3DDMAPSAMPLER 256
+#define D3DVERTEXTEXTURESAMPLER0 (D3DDMAPSAMPLER+1)
+#define D3DSP_SRCMOD_SHIFT 24
+
+
+#define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
+#define D3DCOLOR_RGBA(r,g,b,a) D3DCOLOR_ARGB(a,r,g,b)
+#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)
+
+// maps floating point channels (0.f to 1.f range) to D3DCOLOR
+#define D3DCOLOR_COLORVALUE(r,g,b,a) \
+ D3DCOLOR_RGBA((DWORD)((r)*255.f),(DWORD)((g)*255.f),(DWORD)((b)*255.f),(DWORD)((a)*255.f))
+
+#define D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0}
+
+#define D3DSP_DCL_USAGEINDEX_SHIFT 16
+#define D3DSP_DCL_USAGEINDEX_MASK 0x000f0000
+
+// Bit masks for destination parameter modifiers
+#define D3DSPDM_NONE (0<<D3DSP_DSTMOD_SHIFT) // nop
+#define D3DSPDM_SATURATE (1<<D3DSP_DSTMOD_SHIFT) // clamp to 0. to 1. range
+#define D3DSPDM_PARTIALPRECISION (2<<D3DSP_DSTMOD_SHIFT) // Partial precision hint
+#define D3DSPDM_MSAMPCENTROID (4<<D3DSP_DSTMOD_SHIFT) // Relevant to multisampling only:
+ // When the pixel center is not covered, sample
+ // attribute or compute gradients/LOD
+ // using multisample "centroid" location.
+ // "Centroid" is some location within the covered
+ // region of the pixel.
+
+// Value when there is no swizzle (X is taken from X, Y is taken from Y,
+// Z is taken from Z, W is taken from W
+//
+#define D3DVS_NOSWIZZLE (D3DVS_X_X | D3DVS_Y_Y | D3DVS_Z_Z | D3DVS_W_W)
+
+// extract major/minor from version cap
+#define D3DSHADER_VERSION_MAJOR(_Version) (((_Version)>>8)&0xFF)
+#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF)
+
+#define D3DSHADER_ADDRESSMODE_SHIFT 13
+#define D3DSHADER_ADDRESSMODE_MASK (1 << D3DSHADER_ADDRESSMODE_SHIFT)
+
+#define D3DPS_END() 0x0000FFFF
+
+// ps_2_0 texld controls
+#define D3DSI_TEXLD_PROJECT (0x01 << D3DSP_OPCODESPECIFICCONTROL_SHIFT)
+#define D3DSI_TEXLD_BIAS (0x02 << D3DSP_OPCODESPECIFICCONTROL_SHIFT)
+
+
+// destination parameter write mask
+#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red)
+#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green)
+#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue)
+#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha)
+#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components
+
+#define D3DVS_SWIZZLE_SHIFT 16
+#define D3DVS_SWIZZLE_MASK 0x00FF0000
+
+// The following bits define where to take component X from:
+
+#define D3DVS_X_X (0 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Y (1 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_Z (2 << D3DVS_SWIZZLE_SHIFT)
+#define D3DVS_X_W (3 << D3DVS_SWIZZLE_SHIFT)
+
+// The following bits define where to take component Y from:
+
+#define D3DVS_Y_X (0 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Y (1 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_Z (2 << (D3DVS_SWIZZLE_SHIFT + 2))
+#define D3DVS_Y_W (3 << (D3DVS_SWIZZLE_SHIFT + 2))
+
+// The following bits define where to take component Z from:
+
+#define D3DVS_Z_X (0 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Y (1 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_Z (2 << (D3DVS_SWIZZLE_SHIFT + 4))
+#define D3DVS_Z_W (3 << (D3DVS_SWIZZLE_SHIFT + 4))
+
+// The following bits define where to take component W from:
+
+#define D3DVS_W_X (0 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Y (1 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_Z (2 << (D3DVS_SWIZZLE_SHIFT + 6))
+#define D3DVS_W_W (3 << (D3DVS_SWIZZLE_SHIFT + 6))
+
+// source parameter modifiers
+#define D3DSP_SRCMOD_SHIFT 24
+#define D3DSP_SRCMOD_MASK 0x0F000000
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ENUMS
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE
+{
+ D3DSPSM_NONE = 0<<D3DSP_SRCMOD_SHIFT, // nop
+ D3DSPSM_NEG = 1<<D3DSP_SRCMOD_SHIFT, // negate
+ D3DSPSM_BIAS = 2<<D3DSP_SRCMOD_SHIFT, // bias
+ D3DSPSM_BIASNEG = 3<<D3DSP_SRCMOD_SHIFT, // bias and negate
+ D3DSPSM_SIGN = 4<<D3DSP_SRCMOD_SHIFT, // sign
+ D3DSPSM_SIGNNEG = 5<<D3DSP_SRCMOD_SHIFT, // sign and negate
+ D3DSPSM_COMP = 6<<D3DSP_SRCMOD_SHIFT, // complement
+ D3DSPSM_X2 = 7<<D3DSP_SRCMOD_SHIFT, // *2
+ D3DSPSM_X2NEG = 8<<D3DSP_SRCMOD_SHIFT, // *2 and negate
+ D3DSPSM_DZ = 9<<D3DSP_SRCMOD_SHIFT, // divide through by z component
+ D3DSPSM_DW = 10<<D3DSP_SRCMOD_SHIFT, // divide through by w component
+ D3DSPSM_ABS = 11<<D3DSP_SRCMOD_SHIFT, // abs()
+ D3DSPSM_ABSNEG = 12<<D3DSP_SRCMOD_SHIFT, // -abs()
+ D3DSPSM_NOT = 13<<D3DSP_SRCMOD_SHIFT, // for predicate register: "!p0"
+ D3DSPSM_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_PARAM_SRCMOD_TYPE;
+
+
+typedef enum _D3DSAMPLER_TEXTURE_TYPE
+{
+ D3DSTT_UNKNOWN = 0<<D3DSP_TEXTURETYPE_SHIFT, // uninitialized value
+ D3DSTT_2D = 2<<D3DSP_TEXTURETYPE_SHIFT, // dcl_2d s# (for declaring a 2-D texture)
+ D3DSTT_CUBE = 3<<D3DSP_TEXTURETYPE_SHIFT, // dcl_cube s# (for declaring a cube texture)
+ D3DSTT_VOLUME = 4<<D3DSP_TEXTURETYPE_SHIFT, // dcl_volume s# (for declaring a volume texture)
+ D3DSTT_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSAMPLER_TEXTURE_TYPE;
+
+typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE
+{
+ D3DSIO_NOP = 0,
+ D3DSIO_MOV ,
+ D3DSIO_ADD ,
+ D3DSIO_SUB ,
+ D3DSIO_MAD ,
+ D3DSIO_MUL ,
+ D3DSIO_RCP ,
+ D3DSIO_RSQ ,
+ D3DSIO_DP3 ,
+ D3DSIO_DP4 ,
+ D3DSIO_MIN , //10
+ D3DSIO_MAX ,
+ D3DSIO_SLT ,
+ D3DSIO_SGE ,
+ D3DSIO_EXP ,
+ D3DSIO_LOG ,
+ D3DSIO_LIT ,
+ D3DSIO_DST ,
+ D3DSIO_LRP ,
+ D3DSIO_FRC ,
+ D3DSIO_M4x4 , //20
+ D3DSIO_M4x3 ,
+ D3DSIO_M3x4 ,
+ D3DSIO_M3x3 ,
+ D3DSIO_M3x2 ,
+ D3DSIO_CALL ,
+ D3DSIO_CALLNZ ,
+ D3DSIO_LOOP ,
+ D3DSIO_RET ,
+ D3DSIO_ENDLOOP ,
+ D3DSIO_LABEL , //30
+ D3DSIO_DCL ,
+ D3DSIO_POW ,
+ D3DSIO_CRS ,
+ D3DSIO_SGN ,
+ D3DSIO_ABS ,
+ D3DSIO_NRM ,
+ D3DSIO_SINCOS ,
+ D3DSIO_REP ,
+ D3DSIO_ENDREP ,
+ D3DSIO_IF , //40
+ D3DSIO_IFC ,
+ D3DSIO_ELSE ,
+ D3DSIO_ENDIF ,
+ D3DSIO_BREAK ,
+ D3DSIO_BREAKC ,
+ D3DSIO_MOVA ,
+ D3DSIO_DEFB ,
+ D3DSIO_DEFI ,
+
+ D3DSIO_TEXCOORD = 64,
+ D3DSIO_TEXKILL ,
+ D3DSIO_TEX ,
+ D3DSIO_TEXBEM ,
+ D3DSIO_TEXBEML ,
+ D3DSIO_TEXREG2AR ,
+ D3DSIO_TEXREG2GB ,
+ D3DSIO_TEXM3x2PAD ,
+ D3DSIO_TEXM3x2TEX ,
+ D3DSIO_TEXM3x3PAD ,
+ D3DSIO_TEXM3x3TEX ,
+ D3DSIO_RESERVED0 ,
+ D3DSIO_TEXM3x3SPEC ,
+ D3DSIO_TEXM3x3VSPEC ,
+ D3DSIO_EXPP ,
+ D3DSIO_LOGP ,
+ D3DSIO_CND ,
+ D3DSIO_DEF ,
+ D3DSIO_TEXREG2RGB ,
+ D3DSIO_TEXDP3TEX ,
+ D3DSIO_TEXM3x2DEPTH ,
+ D3DSIO_TEXDP3 ,
+ D3DSIO_TEXM3x3 ,
+ D3DSIO_TEXDEPTH ,
+ D3DSIO_CMP ,
+ D3DSIO_BEM ,
+ D3DSIO_DP2ADD ,
+ D3DSIO_DSX ,
+ D3DSIO_DSY ,
+ D3DSIO_TEXLDD ,
+ D3DSIO_SETP ,
+ D3DSIO_TEXLDL ,
+ D3DSIO_BREAKP ,
+
+ D3DSIO_PHASE = 0xFFFD,
+ D3DSIO_COMMENT = 0xFFFE,
+ D3DSIO_END = 0xFFFF,
+
+ D3DSIO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_INSTRUCTION_OPCODE_TYPE;
+
+typedef enum _D3DVS_RASTOUT_OFFSETS
+{
+ D3DSRO_POSITION = 0,
+ D3DSRO_FOG,
+ D3DSRO_POINT_SIZE,
+ D3DSRO_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DVS_RASTOUT_OFFSETS;
+
+/* SwapEffects */
+typedef enum _D3DSWAPEFFECT
+{
+ D3DSWAPEFFECT_DISCARD = 1,
+ D3DSWAPEFFECT_COPY = 3,
+
+ D3DSWAPEFFECT_FORCE_DWORD = 0x7fffffff
+} D3DSWAPEFFECT;
+
+typedef enum _D3DRESOURCETYPE
+{
+ D3DRTYPE_SURFACE = 1,
+ D3DRTYPE_TEXTURE = 3,
+ D3DRTYPE_VOLUMETEXTURE = 4,
+ D3DRTYPE_CUBETEXTURE = 5,
+ D3DRTYPE_VERTEXBUFFER = 6,
+ D3DRTYPE_INDEXBUFFER = 7,
+
+ D3DRTYPE_FORCE_DWORD = 0x7fffffff
+} D3DRESOURCETYPE;
+
+typedef enum _D3DDEVTYPE
+{
+ D3DDEVTYPE_HAL = 1,
+ D3DDEVTYPE_REF = 2,
+
+ D3DDEVTYPE_NULLREF = 4,
+
+ D3DDEVTYPE_FORCE_DWORD = 0x7fffffff
+} D3DDEVTYPE;
+
+typedef enum _D3DSTENCILOP
+{
+ D3DSTENCILOP_KEEP = 1,
+ D3DSTENCILOP_ZERO = 2,
+ D3DSTENCILOP_REPLACE = 3,
+ D3DSTENCILOP_INCRSAT = 4,
+ D3DSTENCILOP_DECRSAT = 5,
+ D3DSTENCILOP_INVERT = 6,
+ D3DSTENCILOP_INCR = 7,
+ D3DSTENCILOP_DECR = 8,
+ D3DSTENCILOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSTENCILOP;
+
+typedef enum _D3DPATCHEDGESTYLE
+{
+ D3DPATCHEDGE_DISCRETE = 0,
+ D3DPATCHEDGE_CONTINUOUS = 1,
+ D3DPATCHEDGE_FORCE_DWORD = 0x7fffffff,
+} D3DPATCHEDGESTYLE;
+
+
+/* Debug monitor tokens (DEBUG only)
+
+ Note that if D3DRS_DEBUGMONITORTOKEN is set, the call is treated as
+ passing a token to the debug monitor. For example, if, after passing
+ D3DDMT_ENABLE/DISABLE to D3DRS_DEBUGMONITORTOKEN other token values
+ are passed in, the enabled/disabled state of the debug
+ monitor will still persist.
+
+ The debug monitor defaults to enabled.
+
+ Calling GetRenderState on D3DRS_DEBUGMONITORTOKEN is not of any use.
+*/
+typedef enum _D3DDEBUGMONITORTOKENS
+{
+ D3DDMT_ENABLE = 0, // enable debug monitor
+} D3DDEBUGMONITORTOKENS;
+
+typedef enum _D3DDEGREETYPE
+{
+ D3DDEGREE_LINEAR = 1,
+ D3DDEGREE_QUADRATIC = 2,
+ D3DDEGREE_CUBIC = 3,
+ D3DDEGREE_FORCE_DWORD = 0x7fffffff,
+} D3DDEGREETYPE;
+
+typedef enum _D3DBLENDOP
+{
+ D3DBLENDOP_ADD = 1,
+ D3DBLENDOP_SUBTRACT = 2,
+ D3DBLENDOP_REVSUBTRACT = 3,
+ D3DBLENDOP_MIN = 4,
+ D3DBLENDOP_MAX = 5,
+ D3DBLENDOP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DBLENDOP;
+
+typedef enum _D3DMULTISAMPLE_TYPE
+{
+ D3DMULTISAMPLE_NONE = 0,
+ D3DMULTISAMPLE_NONMASKABLE = 1,
+ D3DMULTISAMPLE_2_SAMPLES = 2,
+ D3DMULTISAMPLE_3_SAMPLES = 3,
+ D3DMULTISAMPLE_4_SAMPLES = 4,
+ D3DMULTISAMPLE_5_SAMPLES = 5,
+ D3DMULTISAMPLE_6_SAMPLES = 6,
+ D3DMULTISAMPLE_7_SAMPLES = 7,
+ D3DMULTISAMPLE_8_SAMPLES = 8,
+ D3DMULTISAMPLE_9_SAMPLES = 9,
+ D3DMULTISAMPLE_10_SAMPLES = 10,
+ D3DMULTISAMPLE_11_SAMPLES = 11,
+ D3DMULTISAMPLE_12_SAMPLES = 12,
+ D3DMULTISAMPLE_13_SAMPLES = 13,
+ D3DMULTISAMPLE_14_SAMPLES = 14,
+ D3DMULTISAMPLE_15_SAMPLES = 15,
+ D3DMULTISAMPLE_16_SAMPLES = 16,
+
+ D3DMULTISAMPLE_FORCE_DWORD = 0x7fffffff
+} D3DMULTISAMPLE_TYPE;
+
+/* Pool types */
+typedef enum _D3DPOOL
+{
+ D3DPOOL_DEFAULT = 0,
+ D3DPOOL_MANAGED = 1,
+ D3DPOOL_SYSTEMMEM = 2,
+ D3DPOOL_SCRATCH = 3,
+
+ D3DPOOL_FORCE_DWORD = 0x7fffffff
+} D3DPOOL;
+
+typedef enum _D3DQUERYTYPE
+{
+ D3DQUERYTYPE_RESOURCEMANAGER = 5, /* D3DISSUE_END */
+ D3DQUERYTYPE_EVENT = 8, /* D3DISSUE_END */
+ D3DQUERYTYPE_OCCLUSION = 9, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_TIMESTAMP = 10, /* D3DISSUE_END */
+ D3DQUERYTYPE_TIMESTAMPFREQ = 12, /* D3DISSUE_END */
+ D3DQUERYTYPE_INTERFACETIMINGS = 14, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_PIXELTIMINGS = 16, /* D3DISSUE_BEGIN, D3DISSUE_END */
+ D3DQUERYTYPE_CACHEUTILIZATION = 18, /* D3DISSUE_BEGIN, D3DISSUE_END */
+} D3DQUERYTYPE;
+
+typedef enum _D3DRENDERSTATETYPE
+{
+ D3DRS_ZENABLE = 7, /* D3DZBUFFERTYPE (or TRUE/FALSE for legacy) */
+ D3DRS_FILLMODE = 8, /* D3DFILLMODE */
+ D3DRS_SHADEMODE = 9, /* D3DSHADEMODE */
+ D3DRS_ZWRITEENABLE = 14, /* TRUE to enable z writes */
+ D3DRS_ALPHATESTENABLE = 15, /* TRUE to enable alpha tests */
+ D3DRS_LASTPIXEL = 16, /* TRUE for last-pixel on lines */
+ D3DRS_SRCBLEND = 19, /* D3DBLEND */
+ D3DRS_DESTBLEND = 20, /* D3DBLEND */
+ D3DRS_CULLMODE = 22, /* D3DCULL */
+ D3DRS_ZFUNC = 23, /* D3DCMPFUNC */
+ D3DRS_ALPHAREF = 24, /* D3DFIXED */
+ D3DRS_ALPHAFUNC = 25, /* D3DCMPFUNC */
+ D3DRS_DITHERENABLE = 26, /* TRUE to enable dithering */
+ D3DRS_ALPHABLENDENABLE = 27, /* TRUE to enable alpha blending */
+ D3DRS_FOGENABLE = 28, /* TRUE to enable fog blending */
+ D3DRS_SPECULARENABLE = 29, /* TRUE to enable specular */
+ D3DRS_FOGCOLOR = 34, /* D3DCOLOR */
+ D3DRS_FOGTABLEMODE = 35, /* D3DFOGMODE */
+ D3DRS_FOGSTART = 36, /* Fog start (for both vertex and pixel fog) */
+ D3DRS_FOGEND = 37, /* Fog end */
+ D3DRS_FOGDENSITY = 38, /* Fog density */
+ D3DRS_RANGEFOGENABLE = 48, /* Enables range-based fog */
+ D3DRS_STENCILENABLE = 52, /* BOOL enable/disable stenciling */
+ D3DRS_STENCILFAIL = 53, /* D3DSTENCILOP to do if stencil test fails */
+ D3DRS_STENCILZFAIL = 54, /* D3DSTENCILOP to do if stencil test passes and Z test fails */
+ D3DRS_STENCILPASS = 55, /* D3DSTENCILOP to do if both stencil and Z tests pass */
+ D3DRS_STENCILFUNC = 56, /* D3DCMPFUNC fn. Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */
+ D3DRS_STENCILREF = 57, /* Reference value used in stencil test */
+ D3DRS_STENCILMASK = 58, /* Mask value used in stencil test */
+ D3DRS_STENCILWRITEMASK = 59, /* Write mask applied to values written to stencil buffer */
+ D3DRS_TEXTUREFACTOR = 60, /* D3DCOLOR used for multi-texture blend */
+ D3DRS_WRAP0 = 128, /* wrap for 1st texture coord. set */
+ D3DRS_WRAP1 = 129, /* wrap for 2nd texture coord. set */
+ D3DRS_WRAP2 = 130, /* wrap for 3rd texture coord. set */
+ D3DRS_WRAP3 = 131, /* wrap for 4th texture coord. set */
+ D3DRS_WRAP4 = 132, /* wrap for 5th texture coord. set */
+ D3DRS_WRAP5 = 133, /* wrap for 6th texture coord. set */
+ D3DRS_WRAP6 = 134, /* wrap for 7th texture coord. set */
+ D3DRS_WRAP7 = 135, /* wrap for 8th texture coord. set */
+ D3DRS_CLIPPING = 136,
+ D3DRS_LIGHTING = 137,
+ D3DRS_AMBIENT = 139,
+ D3DRS_FOGVERTEXMODE = 140,
+ D3DRS_COLORVERTEX = 141,
+ D3DRS_LOCALVIEWER = 142,
+ D3DRS_NORMALIZENORMALS = 143,
+ D3DRS_DIFFUSEMATERIALSOURCE = 145,
+ D3DRS_SPECULARMATERIALSOURCE = 146,
+ D3DRS_AMBIENTMATERIALSOURCE = 147,
+ D3DRS_EMISSIVEMATERIALSOURCE = 148,
+ D3DRS_VERTEXBLEND = 151,
+ D3DRS_CLIPPLANEENABLE = 152,
+ D3DRS_POINTSIZE = 154, /* float point size */
+ D3DRS_POINTSIZE_MIN = 155, /* float point size min threshold */
+ D3DRS_POINTSPRITEENABLE = 156, /* BOOL point texture coord control */
+ D3DRS_POINTSCALEENABLE = 157, /* BOOL point size scale enable */
+ D3DRS_POINTSCALE_A = 158, /* float point attenuation A value */
+ D3DRS_POINTSCALE_B = 159, /* float point attenuation B value */
+ D3DRS_POINTSCALE_C = 160, /* float point attenuation C value */
+ D3DRS_MULTISAMPLEANTIALIAS = 161, // BOOL - set to do FSAA with multisample buffer
+ D3DRS_MULTISAMPLEMASK = 162, // DWORD - per-sample enable/disable
+ D3DRS_PATCHEDGESTYLE = 163, // Sets whether patch edges will use float style tessellation
+ D3DRS_DEBUGMONITORTOKEN = 165, // DEBUG ONLY - token to debug monitor
+ D3DRS_POINTSIZE_MAX = 166, /* float point size max threshold */
+ D3DRS_INDEXEDVERTEXBLENDENABLE = 167,
+ D3DRS_COLORWRITEENABLE = 168, // per-channel write enable
+ D3DRS_TWEENFACTOR = 170, // float tween factor
+ D3DRS_BLENDOP = 171, // D3DBLENDOP setting
+ D3DRS_POSITIONDEGREE = 172, // NPatch position interpolation degree. D3DDEGREE_LINEAR or D3DDEGREE_CUBIC (default)
+ D3DRS_NORMALDEGREE = 173, // NPatch normal interpolation degree. D3DDEGREE_LINEAR (default) or D3DDEGREE_QUADRATIC
+ D3DRS_SCISSORTESTENABLE = 174,
+ D3DRS_SLOPESCALEDEPTHBIAS = 175,
+ D3DRS_ANTIALIASEDLINEENABLE = 176,
+ D3DRS_MINTESSELLATIONLEVEL = 178,
+ D3DRS_MAXTESSELLATIONLEVEL = 179,
+ D3DRS_ADAPTIVETESS_X = 180,
+ D3DRS_ADAPTIVETESS_Y = 181,
+ D3DRS_ADAPTIVETESS_Z = 182,
+ D3DRS_ADAPTIVETESS_W = 183,
+ D3DRS_ENABLEADAPTIVETESSELLATION = 184,
+ D3DRS_TWOSIDEDSTENCILMODE = 185, /* BOOL enable/disable 2 sided stenciling */
+ D3DRS_CCW_STENCILFAIL = 186, /* D3DSTENCILOP to do if ccw stencil test fails */
+ D3DRS_CCW_STENCILZFAIL = 187, /* D3DSTENCILOP to do if ccw stencil test passes and Z test fails */
+ D3DRS_CCW_STENCILPASS = 188, /* D3DSTENCILOP to do if both ccw stencil and Z tests pass */
+ D3DRS_CCW_STENCILFUNC = 189, /* D3DCMPFUNC fn. ccw Stencil Test passes if ((ref & mask) stencilfn (stencil & mask)) is true */
+ D3DRS_COLORWRITEENABLE1 = 190, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_COLORWRITEENABLE2 = 191, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_COLORWRITEENABLE3 = 192, /* Additional ColorWriteEnables for the devices that support D3DPMISCCAPS_INDEPENDENTWRITEMASKS */
+ D3DRS_BLENDFACTOR = 193, /* D3DCOLOR used for a constant blend factor during alpha blending for devices that support D3DPBLENDCAPS_BLENDFACTOR */
+ D3DRS_SRGBWRITEENABLE = 194, /* Enable rendertarget writes to be DE-linearized to SRGB (for formats that expose D3DUSAGE_QUERY_SRGBWRITE) */
+ D3DRS_DEPTHBIAS = 195,
+ D3DRS_WRAP8 = 198, /* Additional wrap states for vs_3_0+ attributes with D3DDECLUSAGE_TEXCOORD */
+ D3DRS_WRAP9 = 199,
+ D3DRS_WRAP10 = 200,
+ D3DRS_WRAP11 = 201,
+ D3DRS_WRAP12 = 202,
+ D3DRS_WRAP13 = 203,
+ D3DRS_WRAP14 = 204,
+ D3DRS_WRAP15 = 205,
+ D3DRS_SEPARATEALPHABLENDENABLE = 206, /* TRUE to enable a separate blending function for the alpha channel */
+ D3DRS_SRCBLENDALPHA = 207, /* SRC blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+ D3DRS_DESTBLENDALPHA = 208, /* DST blend factor for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+ D3DRS_BLENDOPALPHA = 209, /* Blending operation for the alpha channel when D3DRS_SEPARATEDESTALPHAENABLE is TRUE */
+
+
+ D3DRS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DRENDERSTATETYPE;
+
+typedef enum _D3DCULL
+{
+ D3DCULL_NONE = 1,
+ D3DCULL_CW = 2,
+ D3DCULL_CCW = 3,
+ D3DCULL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DCULL;
+
+typedef enum _D3DTEXTUREFILTERTYPE
+{
+ D3DTEXF_NONE = 0, // filtering disabled (valid for mip filter only)
+ D3DTEXF_POINT = 1, // nearest
+ D3DTEXF_LINEAR = 2, // linear interpolation
+ D3DTEXF_ANISOTROPIC = 3, // anisotropic
+ D3DTEXF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DTEXTUREFILTERTYPE;
+
+typedef enum _D3DBACKBUFFER_TYPE
+{
+ D3DBACKBUFFER_TYPE_MONO = 0,
+
+ D3DBACKBUFFER_TYPE_FORCE_DWORD = 0x7fffffff
+} D3DBACKBUFFER_TYPE;
+
+#define D3DTS_WORLDMATRIX(index) (D3DTRANSFORMSTATETYPE)(index + 256)
+#define D3DTS_WORLD D3DTS_WORLDMATRIX(0)
+#define D3DTS_WORLD1 D3DTS_WORLDMATRIX(1)
+#define D3DTS_WORLD2 D3DTS_WORLDMATRIX(2)
+#define D3DTS_WORLD3 D3DTS_WORLDMATRIX(3)
+
+typedef enum _D3DCMPFUNC
+{
+ D3DCMP_NEVER = 1,
+ D3DCMP_LESS = 2,
+ D3DCMP_EQUAL = 3,
+ D3DCMP_LESSEQUAL = 4,
+ D3DCMP_GREATER = 5,
+ D3DCMP_NOTEQUAL = 6,
+ D3DCMP_GREATEREQUAL = 7,
+ D3DCMP_ALWAYS = 8,
+ D3DCMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DCMPFUNC;
+
+typedef enum _D3DZBUFFERTYPE
+{
+ D3DZB_FALSE = 0,
+ D3DZB_TRUE = 1, // Z buffering
+ D3DZB_USEW = 2, // W buffering
+ D3DZB_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DZBUFFERTYPE;
+
+typedef enum _D3DFILLMODE
+{
+ D3DFILL_POINT = 1,
+ D3DFILL_WIREFRAME = 2,
+ D3DFILL_SOLID = 3,
+ D3DFILL_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DFILLMODE;
+
+typedef enum _D3DBLEND
+{
+ D3DBLEND_ZERO = 1,
+ D3DBLEND_ONE = 2,
+ D3DBLEND_SRCCOLOR = 3,
+ D3DBLEND_INVSRCCOLOR = 4,
+ D3DBLEND_SRCALPHA = 5,
+ D3DBLEND_INVSRCALPHA = 6,
+ D3DBLEND_DESTALPHA = 7,
+ D3DBLEND_INVDESTALPHA = 8,
+ D3DBLEND_DESTCOLOR = 9,
+ D3DBLEND_INVDESTCOLOR = 10,
+ D3DBLEND_SRCALPHASAT = 11,
+ D3DBLEND_BOTHSRCALPHA = 12,
+ D3DBLEND_BOTHINVSRCALPHA = 13,
+ D3DBLEND_BLENDFACTOR = 14, /* Only supported if D3DPBLENDCAPS_BLENDFACTOR is on */
+ D3DBLEND_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DBLEND;
+
+// Values for material source
+typedef enum _D3DMATERIALCOLORSOURCE
+{
+ D3DMCS_MATERIAL = 0, // Color from material is used
+ D3DMCS_COLOR1 = 1, // Diffuse vertex color is used
+ D3DMCS_COLOR2 = 2, // Specular vertex color is used
+ D3DMCS_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DMATERIALCOLORSOURCE;
+
+typedef enum _D3DCUBEMAP_FACES
+{
+ D3DCUBEMAP_FACE_POSITIVE_Z = 4,
+
+ D3DCUBEMAP_FACE_FORCE_DWORD = 0x7fffffff
+} D3DCUBEMAP_FACES;
+
+typedef enum _D3DTEXTURETRANSFORMFLAGS
+{
+ D3DTTFF_DISABLE = 0, // texture coordinates are passed directly
+ D3DTTFF_COUNT3 = 3, // rasterizer should expect 3-D texture coords
+ D3DTTFF_PROJECTED = 256, // texcoords to be divided by COUNTth element
+ D3DTTFF_FORCE_DWORD = 0x7fffffff,
+} D3DTEXTURETRANSFORMFLAGS;
+
+// Note: the Linux/win TOGL reorders these. For the Mac we use the same enums as Windows itself.
+
+typedef enum _D3DTEXTUREADDRESS {
+ D3DTADDRESS_WRAP = 1,
+ D3DTADDRESS_CLAMP = 3,
+ D3DTADDRESS_BORDER = 4,
+ D3DTADDRESS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTEXTUREADDRESS;
+
+typedef enum _D3DSHADEMODE
+{
+ D3DSHADE_FLAT = 1,
+ D3DSHADE_GOURAUD = 2,
+ D3DSHADE_PHONG = 3,
+ D3DSHADE_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSHADEMODE;
+
+typedef enum _D3DFOGMODE
+{
+ D3DFOG_NONE = 0,
+ D3DFOG_LINEAR = 3,
+ D3DFOG_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DFOGMODE;
+
+typedef struct _D3DRECT
+{
+ LONG x1;
+ LONG y1;
+ LONG x2;
+ LONG y2;
+} D3DRECT;
+
+typedef enum _D3DSHADER_PARAM_REGISTER_TYPE
+{
+ D3DSPR_TEMP = 0, // Temporary Register File
+ D3DSPR_INPUT = 1, // Input Register File
+ D3DSPR_CONST = 2, // Constant Register File
+ D3DSPR_ADDR = 3, // Address Register (VS)
+ D3DSPR_TEXTURE = 3, // Texture Register File (PS)
+ D3DSPR_RASTOUT = 4, // Rasterizer Register File
+ D3DSPR_ATTROUT = 5, // Attribute Output Register File
+ D3DSPR_TEXCRDOUT = 6, // Texture Coordinate Output Register File
+ D3DSPR_OUTPUT = 6, // Output register file for VS3.0+
+ D3DSPR_CONSTINT = 7, // Constant Integer Vector Register File
+ D3DSPR_COLOROUT = 8, // Color Output Register File
+ D3DSPR_DEPTHOUT = 9, // Depth Output Register File
+ D3DSPR_SAMPLER = 10, // Sampler State Register File
+ D3DSPR_CONST2 = 11, // Constant Register File 2048 - 4095
+ D3DSPR_CONST3 = 12, // Constant Register File 4096 - 6143
+ D3DSPR_CONST4 = 13, // Constant Register File 6144 - 8191
+ D3DSPR_CONSTBOOL = 14, // Constant Boolean register file
+ D3DSPR_LOOP = 15, // Loop counter register file
+ D3DSPR_TEMPFLOAT16 = 16, // 16-bit float temp register file
+ D3DSPR_MISCTYPE = 17, // Miscellaneous (single) registers.
+ D3DSPR_LABEL = 18, // Label
+ D3DSPR_PREDICATE = 19, // Predicate register
+ D3DSPR_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DSHADER_PARAM_REGISTER_TYPE;
+
+typedef struct _D3DMATRIX
+{
+ union
+ {
+ struct
+ {
+ float _11, _12, _13, _14;
+ float _21, _22, _23, _24;
+ float _31, _32, _33, _34;
+ float _41, _42, _43, _44;
+ };
+ float m[4][4];
+ };
+} D3DMATRIX;
+
+typedef struct _D3DVERTEXBUFFER_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+ UINT Size;
+
+ DWORD FVF;
+
+} D3DVERTEXBUFFER_DESC;
+
+class TOGL_CLASS D3DXMATRIX : public D3DMATRIX
+{
+public:
+ D3DXMATRIX operator*( const D3DXMATRIX &o ) const;
+ operator FLOAT* ();
+ float& operator()( int row, int column );
+ const float& operator()( int row, int column ) const;
+};
+
+typedef DWORD D3DCOLOR;
+
+typedef enum _D3DSAMPLERSTATETYPE
+{
+ D3DSAMP_ADDRESSU = 1, /* D3DTEXTUREADDRESS for U coordinate */
+ D3DSAMP_ADDRESSV = 2, /* D3DTEXTUREADDRESS for V coordinate */
+ D3DSAMP_ADDRESSW = 3, /* D3DTEXTUREADDRESS for W coordinate */
+ D3DSAMP_BORDERCOLOR = 4, /* D3DCOLOR */
+ D3DSAMP_MAGFILTER = 5, /* D3DTEXTUREFILTER filter to use for magnification */
+ D3DSAMP_MINFILTER = 6, /* D3DTEXTUREFILTER filter to use for minification */
+ D3DSAMP_MIPFILTER = 7, /* D3DTEXTUREFILTER filter to use between mipmaps during minification */
+ D3DSAMP_MIPMAPLODBIAS = 8, /* float Mipmap LOD bias */
+ D3DSAMP_MAXMIPLEVEL = 9, /* DWORD 0..(n-1) LOD index of largest map to use (0 == largest) */
+ D3DSAMP_MAXANISOTROPY = 10, /* DWORD maximum anisotropy */
+ D3DSAMP_SRGBTEXTURE = 11, /* Default = 0 (which means Gamma 1.0,
+ no correction required.) else correct for
+ Gamma = 2.2 */
+ D3DSAMP_SHADOWFILTER = 12, /* Tells the sampler that it should be doing shadow compares */
+ D3DSAMP_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DSAMPLERSTATETYPE;
+
+typedef enum _D3DDECLTYPE
+{
+ D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.)
+ D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.)
+ D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.)
+ D3DDECLTYPE_FLOAT4 = 3, // 4D float
+ D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range
+ // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A)
+ D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte
+ D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.)
+ D3DDECLTYPE_SHORT4 = 7, // 4D signed short
+
+// The following types are valid only with vertex shaders >= 2.0
+
+
+ D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0
+ D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1)
+ D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0)
+ D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1)
+ D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0)
+ D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1)
+ D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1)
+ D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1)
+ D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values
+ D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused.
+} D3DDECLTYPE;
+
+typedef enum _D3DDECLMETHOD
+{
+ D3DDECLMETHOD_DEFAULT = 0,
+ D3DDECLMETHOD_PARTIALU,
+ D3DDECLMETHOD_PARTIALV,
+ D3DDECLMETHOD_CROSSUV, // Normal
+ D3DDECLMETHOD_UV,
+ D3DDECLMETHOD_LOOKUP, // Lookup a displacement map
+ D3DDECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map
+} D3DDECLMETHOD;
+
+typedef enum _D3DDECLUSAGE
+{
+ D3DDECLUSAGE_POSITION = 0,
+ D3DDECLUSAGE_BLENDWEIGHT = 1,
+ D3DDECLUSAGE_BLENDINDICES = 2,
+ D3DDECLUSAGE_NORMAL = 3,
+ D3DDECLUSAGE_PSIZE = 4,
+ D3DDECLUSAGE_TEXCOORD = 5,
+ D3DDECLUSAGE_TANGENT = 6,
+ D3DDECLUSAGE_BINORMAL = 7,
+ D3DDECLUSAGE_TESSFACTOR = 8,
+ D3DDECLUSAGE_PLUGH = 9, // mystery value
+ D3DDECLUSAGE_COLOR = 10,
+ D3DDECLUSAGE_FOG = 11,
+ D3DDECLUSAGE_DEPTH = 12,
+ D3DDECLUSAGE_SAMPLE = 13,
+} D3DDECLUSAGE;
+
+typedef enum _D3DPRIMITIVETYPE
+{
+ D3DPT_POINTLIST = 1,
+ D3DPT_LINELIST = 2,
+ D3DPT_TRIANGLELIST = 4,
+ D3DPT_TRIANGLESTRIP = 5,
+ D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DPRIMITIVETYPE;
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// STRUCTURES
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+typedef struct TOGL_CLASS D3DXPLANE
+{
+ float& operator[]( int i );
+ bool operator==( const D3DXPLANE &o );
+ bool operator!=( const D3DXPLANE &o );
+ operator float*();
+ operator const float*() const;
+
+ float a, b, c, d;
+} D3DXPLANE;
+
+typedef enum _D3DVERTEXBLENDFLAGS
+{
+ D3DVBF_DISABLE = 0, // Disable vertex blending
+ D3DVBF_1WEIGHTS = 1, // 2 matrix blending
+ D3DVBF_2WEIGHTS = 2, // 3 matrix blending
+ D3DVBF_3WEIGHTS = 3, // 4 matrix blending
+ D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR
+ D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0
+ D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
+} D3DVERTEXBLENDFLAGS;
+
+typedef struct _D3DINDEXBUFFER_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+ UINT Size;
+} D3DINDEXBUFFER_DESC;
+
+typedef struct _D3DVERTEXELEMENT9
+{
+ WORD Stream; // Stream index
+ WORD Offset; // Offset in the stream in bytes
+ BYTE Type; // Data type
+ BYTE Method; // Processing method
+ BYTE Usage; // Semantics
+ BYTE UsageIndex; // Semantic index
+} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9;
+
+
+#define MAX_DEVICE_IDENTIFIER_STRING 512
+typedef struct _D3DADAPTER_IDENTIFIER9
+{
+ char Driver[MAX_DEVICE_IDENTIFIER_STRING];
+ char Description[MAX_DEVICE_IDENTIFIER_STRING];
+ char DeviceName[32]; /* Device name for GDI (ex. \\.\DISPLAY1) */
+
+ LARGE_INTEGER DriverVersion; /* Defined for 32 bit components */
+
+ DWORD VendorId;
+ DWORD DeviceId;
+ DWORD SubSysId;
+ DWORD Revision;
+ DWORD VideoMemory;
+
+} D3DADAPTER_IDENTIFIER9;
+
+typedef struct _D3DCOLORVALUE
+{
+ float r;
+ float g;
+ float b;
+ float a;
+} D3DCOLORVALUE;
+
+typedef struct _D3DMATERIAL9
+{
+ D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */
+ D3DCOLORVALUE Ambient; /* Ambient color RGB */
+ D3DCOLORVALUE Specular; /* Specular 'shininess' */
+ D3DCOLORVALUE Emissive; /* Emissive color RGB */
+ float Power; /* Sharpness if specular highlight */
+} D3DMATERIAL9;
+
+typedef struct _D3DVOLUME_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+
+ UINT Width;
+ UINT Height;
+ UINT Depth;
+} D3DVOLUME_DESC;
+
+typedef struct _D3DVIEWPORT9
+{
+ DWORD X;
+ DWORD Y; /* Viewport Top left */
+ DWORD Width;
+ DWORD Height; /* Viewport Dimensions */
+ float MinZ; /* Min/max of clip Volume */
+ float MaxZ;
+} D3DVIEWPORT9;
+
+typedef struct _D3DPSHADERCAPS2_0
+{
+ DWORD Caps;
+ INT DynamicFlowControlDepth;
+ INT NumTemps;
+ INT StaticFlowControlDepth;
+ INT NumInstructionSlots;
+} D3DPSHADERCAPS2_0;
+
+typedef struct _D3DCAPS9
+{
+ /* Device Info */
+ D3DDEVTYPE DeviceType;
+
+ /* Caps from DX7 Draw */
+ DWORD Caps;
+ DWORD Caps2;
+
+ /* Cursor Caps */
+ DWORD CursorCaps;
+
+ /* 3D Device Caps */
+ DWORD DevCaps;
+
+ DWORD PrimitiveMiscCaps;
+ DWORD RasterCaps;
+ DWORD TextureCaps;
+ DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's
+
+ DWORD MaxTextureWidth, MaxTextureHeight;
+ DWORD MaxVolumeExtent;
+
+ DWORD MaxTextureAspectRatio;
+ DWORD MaxAnisotropy;
+
+ DWORD TextureOpCaps;
+ DWORD MaxTextureBlendStages;
+ DWORD MaxSimultaneousTextures;
+
+ DWORD VertexProcessingCaps;
+ DWORD MaxActiveLights;
+ DWORD MaxUserClipPlanes;
+ DWORD MaxVertexBlendMatrices;
+ DWORD MaxVertexBlendMatrixIndex;
+
+ DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call
+ DWORD MaxStreams;
+
+ DWORD VertexShaderVersion;
+ DWORD MaxVertexShaderConst; // number of vertex shader constant registers
+
+ DWORD PixelShaderVersion;
+
+ // Here are the DX9 specific ones
+ DWORD DevCaps2;
+ D3DPSHADERCAPS2_0 PS20Caps;
+
+ DWORD NumSimultaneousRTs; // Will be at least 1
+ DWORD MaxVertexShader30InstructionSlots;
+ DWORD MaxPixelShader30InstructionSlots;
+
+ // only on Posix/GL
+ DWORD FakeSRGBWrite; // 1 for parts which can't support SRGB writes due to driver issues - 0 for others
+ DWORD MixedSizeTargets; // 1 for parts which can mix attachment sizes (RT's color vs depth)
+ DWORD CanDoSRGBReadFromRTs; // 0 when we're on Leopard, 1 when on Snow Leopard
+} D3DCAPS9;
+
+typedef struct _D3DDISPLAYMODE
+{
+ UINT Width;
+ UINT Height;
+ UINT RefreshRate;
+ D3DFORMAT Format;
+} D3DDISPLAYMODE;
+
+typedef struct _D3DGAMMARAMP
+{
+ WORD red [256];
+ WORD green[256];
+ WORD blue [256];
+} D3DGAMMARAMP;
+
+
+/* Resize Optional Parameters */
+typedef struct _D3DPRESENT_PARAMETERS_
+{
+ UINT BackBufferWidth;
+ UINT BackBufferHeight;
+ D3DFORMAT BackBufferFormat;
+ UINT BackBufferCount;
+
+ D3DMULTISAMPLE_TYPE MultiSampleType;
+ DWORD MultiSampleQuality;
+
+ D3DSWAPEFFECT SwapEffect;
+ VD3DHWND hDeviceWindow;
+ BOOL Windowed;
+ BOOL EnableAutoDepthStencil;
+ D3DFORMAT AutoDepthStencilFormat;
+ DWORD Flags;
+
+ /* FullScreen_RefreshRateInHz must be zero for Windowed mode */
+ UINT FullScreen_RefreshRateInHz;
+ UINT PresentationInterval;
+} D3DPRESENT_PARAMETERS;
+
+typedef struct _D3DDEVICE_CREATION_PARAMETERS
+{
+ UINT AdapterOrdinal;
+ D3DDEVTYPE DeviceType;
+ VD3DHWND hFocusWindow;
+ DWORD BehaviorFlags;
+} D3DDEVICE_CREATION_PARAMETERS;
+
+/* Structures for LockBox */
+typedef struct _D3DBOX
+{
+ UINT Left;
+ UINT Top;
+ UINT Right;
+ UINT Bottom;
+ UINT Front;
+ UINT Back;
+} D3DBOX;
+
+typedef struct _D3DLOCKED_BOX
+{
+ INT RowPitch;
+ INT SlicePitch;
+ void* pBits;
+} D3DLOCKED_BOX;
+
+typedef struct _D3DSURFACE_DESC
+{
+ D3DFORMAT Format;
+ D3DRESOURCETYPE Type;
+ DWORD Usage;
+ D3DPOOL Pool;
+
+ D3DMULTISAMPLE_TYPE MultiSampleType;
+ DWORD MultiSampleQuality;
+ UINT Width;
+ UINT Height;
+} D3DSURFACE_DESC;
+
+
+typedef struct _D3DLOCKED_RECT
+{
+ INT Pitch;
+ void* pBits;
+} D3DLOCKED_RECT;
+
+
+typedef struct _D3DRASTER_STATUS
+{
+ BOOL InVBlank;
+ UINT ScanLine;
+} D3DRASTER_STATUS;
+
+typedef enum _D3DLIGHTTYPE
+{
+ D3DLIGHT_POINT = 1,
+ D3DLIGHT_SPOT = 2,
+ D3DLIGHT_DIRECTIONAL = 3,
+ D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DLIGHTTYPE;
+
+typedef struct TOGL_CLASS _D3DVECTOR
+{
+ float x;
+ float y;
+ float z;
+} D3DVECTOR;
+
+class TOGL_CLASS D3DXVECTOR2
+{
+public:
+ operator FLOAT* ();
+ operator CONST FLOAT* () const;
+
+ float x,y;
+};
+
+class TOGL_CLASS D3DXVECTOR3 : public D3DVECTOR
+{
+public:
+ D3DXVECTOR3() {}
+ D3DXVECTOR3( float a, float b, float c );
+ operator FLOAT* ();
+ operator CONST FLOAT* () const;
+};
+
+typedef enum _D3DXINCLUDE_TYPE
+{
+ D3DXINC_LOCAL,
+
+ // force 32-bit size enum
+ D3DXINC_FORCE_DWORD = 0x7fffffff
+
+} D3DXINCLUDE_TYPE;
+
+typedef struct _D3DLIGHT9
+{
+ D3DLIGHTTYPE Type; /* Type of light source */
+ D3DCOLORVALUE Diffuse; /* Diffuse color of light */
+ D3DCOLORVALUE Specular; /* Specular color of light */
+ D3DCOLORVALUE Ambient; /* Ambient color of light */
+ D3DVECTOR Position; /* Position in world space */
+ D3DVECTOR Direction; /* Direction in world space */
+ float Range; /* Cutoff range */
+ float Falloff; /* Falloff */
+ float Attenuation0; /* Constant attenuation */
+ float Attenuation1; /* Linear attenuation */
+ float Attenuation2; /* Quadratic attenuation */
+ float Theta; /* Inner angle of spotlight cone */
+ float Phi; /* Outer angle of spotlight cone */
+} D3DLIGHT9;
+
+class TOGL_CLASS D3DXVECTOR4
+{
+public:
+ D3DXVECTOR4() {}
+ D3DXVECTOR4( float a, float b, float c, float d );
+
+ float x,y,z,w;
+};
+
+//----------------------------------------------------------------------------
+// D3DXMACRO:
+// ----------
+// Preprocessor macro definition. The application pass in a NULL-terminated
+// array of this structure to various D3DX APIs. This enables the application
+// to #define tokens at runtime, before the file is parsed.
+//----------------------------------------------------------------------------
+
+typedef struct _D3DXMACRO
+{
+ LPCSTR Name;
+ LPCSTR Definition;
+
+} D3DXMACRO, *LPD3DXMACRO;
+
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+//
+// Also look for any functions marked with "**** FIXED FUNCTION STUFF"
+//
+// It's only laying around here so we don't have to chop up the shader system a lot to strip out the fixed function code paths.
+// ------------------------------------------------------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------------------------------------------------------ //
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTRANSFORMSTATETYPE
+{
+ D3DTS_VIEW = 2,
+ D3DTS_PROJECTION = 3,
+ D3DTS_TEXTURE0 = 16,
+ D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTRANSFORMSTATETYPE;
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTEXTUREOP
+{
+ // Control
+ D3DTOP_DISABLE = 1, // disables stage
+ D3DTOP_SELECTARG1 = 2, // the default
+ D3DTOP_SELECTARG2 = 3,
+
+ // Modulate
+ D3DTOP_MODULATE = 4, // multiply args together
+ D3DTOP_MODULATE2X = 5, // multiply and 1 bit
+ D3DTOP_MODULATE4X = 6, // multiply and 2 bits
+
+ // Add
+ D3DTOP_ADD = 7, // add arguments together
+ D3DTOP_ADDSIGNED = 8, // add with -0.5 bias
+ D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit
+ D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation
+ D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product
+ // Arg1 + Arg2 - Arg1*Arg2
+ // = Arg1 + (1-Arg1)*Arg2
+
+ // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha)
+ D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha
+ D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha
+ D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR
+
+ // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha)
+ D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha
+ D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color
+
+ // Specular mapping
+ D3DTOP_PREMODULATE = 17, // modulate with next texture before use
+ D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB
+ // COLOROP only
+ D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A
+ // COLOROP only
+ D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB
+ // COLOROP only
+ D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A
+ // COLOROP only
+
+ // Bump mapping
+ D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation
+ D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel
+
+ // This can do either diffuse or specular bump mapping with correct input.
+ // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B)
+ // where each component has been scaled and offset to make it signed.
+ // The result is replicated into all four (including alpha) channels.
+ // This is a valid COLOROP only.
+ D3DTOP_DOTPRODUCT3 = 24,
+
+ // Triadic ops
+ D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2
+ D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2
+
+ D3DTOP_FORCE_DWORD = 0x7fffffff,
+} D3DTEXTUREOP;
+
+// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
+typedef enum _D3DTEXTURESTAGESTATETYPE
+{
+ D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */
+ D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */
+ D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */
+ D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */
+ D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */
+ D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */
+ D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */
+ D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */
+ D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */
+ D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */
+ D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */
+ D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */
+ D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */
+
+
+ D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */
+} D3DTEXTURESTAGESTATETYPE;
+
+//===========================================================================//
+
+enum GLMVertexAttributeIndex
+{
+ kGLMGenericAttr00 = 0,
+ kGLMGenericAttr01,
+ kGLMGenericAttr02,
+ kGLMGenericAttr03,
+ kGLMGenericAttr04,
+ kGLMGenericAttr05,
+ kGLMGenericAttr06,
+ kGLMGenericAttr07,
+ kGLMGenericAttr08,
+ kGLMGenericAttr09,
+ kGLMGenericAttr10,
+ kGLMGenericAttr11,
+ kGLMGenericAttr12,
+ kGLMGenericAttr13,
+ kGLMGenericAttr14,
+ kGLMGenericAttr15,
+
+ kGLMVertexAttributeIndexMax // ideally < 32
+};
+
+struct GLMVertexAttributeDesc // all the info you need to do vertex setup for one attribute
+{
+ CGLMBuffer *m_buffer; // NULL allowed in which case m_offset is the full 32-bit pointer.. so you can draw from plain RAM if desired
+ GLuint m_datasize; // comp count of the attribute (1-4)
+ GLenum m_datatype; // data type of the attribute (GL_FLOAT, GL_UNSIGNED_BYTE, etc)
+ GLuint m_stride;
+ GLuint m_offset; // net offset to attribute 'zero' within the buffer.
+ GLboolean m_normalized; // apply to any fixed point data that needs normalizing, esp color bytes
+
+ // may need a seed value at some point to be able to disambiguate re-lifed buffers holding same pointer
+ // simpler alternative is to do shoot-down inside the vertex/index buffer free calls.
+ // I'd rather not have to have each attribute fiddling a ref count on the buffer to which it refers..
+
+#define EQ(fff) ( (src.fff) == (fff) )
+ // test in decreasing order of likelihood of difference, but do not include the buffer revision as caller is not supplying it..
+ bool operator==(const GLMVertexAttributeDesc& src) const { return EQ(m_buffer) && EQ(m_offset) && EQ(m_stride) && EQ(m_datatype) && EQ(m_normalized) && EQ(m_datasize); }
+#undef EQ
+
+ uint m_bufferRevision; // only set in GLM context's copy, to disambiguate references that are same offset / same buffer but cross an orphan event
+};
+
+
+#define MAX_D3DVERTEXELEMENTS 16
+
+struct D3DVERTEXELEMENT9_GL
+{
+ // fields right out of the original decl element (copied)
+ D3DVERTEXELEMENT9 m_dxdecl; // d3d info
+ // WORD Stream; // Stream index
+ // WORD Offset; // Offset in the stream in bytes
+ // BYTE Type; // Data type
+ // BYTE Method; // Processing method
+ // BYTE Usage; // Semantics
+ // BYTE UsageIndex; // Semantic index
+
+ GLMVertexAttributeDesc m_gldecl;
+ // CGLMBuffer *m_buffer; // late-dropped from selected stream desc (left NULL, will replace with stream source buffer at sync time)
+ // GLuint m_datasize; // component count (1,2,3,4) of the attrib
+ // GLenum m_datatype; // data type of the attribute (GL_FLOAT et al)
+ // GLuint m_stride; // late-dropped from stream desc
+ // GLuint m_offset; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL.
+ // GLuint m_normalized; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL.
+};
+
+struct IDirect3DDevice9Params
+{
+ UINT m_adapter;
+ D3DDEVTYPE m_deviceType;
+ VD3DHWND m_focusWindow;
+ DWORD m_behaviorFlags;
+ D3DPRESENT_PARAMETERS m_presentationParameters;
+};
+
+#define D3D_MAX_STREAMS 4
+struct D3DStreamDesc
+{
+ IDirect3DVertexBuffer9 *m_vtxBuffer;
+ uint m_offset;
+ uint m_stride;
+};
+
+struct D3DIndexDesc
+{
+ IDirect3DIndexBuffer9 *m_idxBuffer;
+};
+
+// we latch sampler values until draw time and then convert them all to GL form
+// note these are similar in name to the fields of a GLMTexSamplingParams but contents are not
+// particularly in the texture filtering area
+
+struct D3DSamplerDesc
+{
+ D3DTEXTUREADDRESS m_addressModes[3]; // D3DTEXTUREADDRESS modes for S,T,R
+ DWORD m_borderColor; // DWORD bordercolor
+ D3DTEXTUREFILTERTYPE m_magFilter; // mag filter
+ D3DTEXTUREFILTERTYPE m_minFilter; // min filter
+ D3DTEXTUREFILTERTYPE m_mipFilter; // mip filter
+ float m_mipmapBias; // float: mipmap bias
+ DWORD m_maxMipLevel; // DWORD 0..(n-1) LOD index of largest map to use (0 == largest)
+ DWORD m_maxAniso; // D3DSAMP_MAXANISOTROPY max aniso
+ DWORD m_srgb; // D3DSAMP_SRGBTEXTURE 0 = no SRGB sampling
+ DWORD m_shadowFilter; // D3DSAMP_SHADOWFILTER
+};
+
+// Tracking and naming sampler dimensions
+#define SAMPLER_TYPE_2D 0
+#define SAMPLER_TYPE_CUBE 1
+#define SAMPLER_TYPE_3D 2
+#define SAMPLER_TYPE_UNUSED 3
+
+#endif // DXABSTRACT_TYPES_H
diff --git a/mp/src/public/togl/osx/glentrypoints.h b/mp/src/public/togl/osx/glentrypoints.h new file mode 100644 index 00000000..1ae4423c --- /dev/null +++ b/mp/src/public/togl/osx/glentrypoints.h @@ -0,0 +1,329 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glentrypoints.h
+//
+//===============================================================================
+
+#ifndef GLENTRYPOINTS_H
+#define GLENTRYPOINTS_H
+
+#pragma once
+
+#ifdef DX_TO_GL_ABSTRACTION
+
+#include "tier0/platform.h"
+#include "tier0/dynfunction.h"
+#include "tier0/vprof_telemetry.h"
+#include "interface.h"
+
+#include "togl/rendermechanism.h"
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+
+#ifndef CALLBACK
+#define CALLBACK
+#endif
+
+
+void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL);
+
+#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME
+class CGLExecuteHelperBase
+{
+public:
+ inline void StartCall(const char *pName);
+ inline void StopCall(const char *pName);
+#if GL_TRACK_API_TIME
+ TmU64 m_nStartTime;
+#endif
+};
+
+template < class FunctionType, typename Result >
+class CGLExecuteHelper : public CGLExecuteHelperBase
+{
+public:
+ inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(); StopCall(pName); }
+ template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a); StopCall(pName); }
+ template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b); StopCall(pName); }
+ template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
+
+ inline operator Result() const { return m_Result; }
+ inline operator char*() const { return (char*)m_Result; }
+
+ FunctionType m_pFn;
+
+ Result m_Result;
+};
+
+template < class FunctionType>
+class CGLExecuteHelper<FunctionType, void> : public CGLExecuteHelperBase
+{
+public:
+ inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(); StopCall(pName); }
+ template<typename A> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a); StopCall(pName); }
+ template<typename A, typename B> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b); StopCall(pName); }
+ template<typename A, typename B, typename C> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); }
+ template<typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J> inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); }
+
+ FunctionType m_pFn;
+};
+#endif
+
+template < class FunctionType, typename Result >
+class CDynamicFunctionOpenGLBase
+{
+public:
+ // Construct with a NULL function pointer. You must manually call
+ // Lookup() before you can call a dynamic function through this interface.
+ CDynamicFunctionOpenGLBase() : m_pFn(NULL) {}
+
+ // Construct and do a lookup right away. You will need to make sure that
+ // the lookup actually succeeded, as the gl library might have failed to load
+ // or (fn) might not exist in it.
+ CDynamicFunctionOpenGLBase(const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(fn, fallback);
+ }
+
+ // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
+ CDynamicFunctionOpenGLBase(const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(fn, okay, fallback);
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // This allows you to chain lookups like this:
+ // bool okay = true;
+ // x.Lookup(lib, "x", okay);
+ // y.Lookup(lib, "y", okay);
+ // z.Lookup(lib, "z", okay);
+ // if (okay) { printf("All functions were loaded successfully!\n"); }
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return (okay)).
+ bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ if (!okay)
+ return false;
+ else if (this->m_pFn == NULL)
+ {
+ this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, false, (void *) fallback);
+ this->SetFuncName( fn );
+ }
+ return okay;
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return true).
+ bool Lookup(const char *fn, FunctionType fallback=NULL)
+ {
+ bool okay = true;
+ return Lookup(fn, okay, fallback);
+ }
+
+ // Invalidates the current lookup. Makes the function pointer NULL. You
+ // will need to call Lookup() before you can call a dynamic function
+ // through this interface again.
+ void Reset() { m_pFn = NULL; }
+
+ // Force this to be a specific function pointer.
+ void Force(FunctionType ptr) { m_pFn = ptr; }
+
+ // Retrieve the actual function pointer.
+ FunctionType Pointer() const { return m_pFn; }
+
+#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME
+ #if GL_TELEMETRY_ZONES
+ #define GL_FUNC_NAME m_szName
+ #else
+ #define GL_FUNC_NAME ""
+ #endif
+
+ inline CGLExecuteHelper<FunctionType, Result> operator() () const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME ); }
+
+ template<typename T>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a); }
+
+ template<typename T, typename U>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b); }
+
+ template<typename T, typename U, typename V>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c ) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c); }
+
+ template<typename T, typename U, typename V, typename W>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d); }
+
+ template<typename T, typename U, typename V, typename W, typename X>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i); }
+
+ template<typename T, typename U, typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C>
+ inline CGLExecuteHelper<FunctionType, Result> operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i, C j) const { return CGLExecuteHelper<FunctionType, Result>(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i, j); }
+#else
+ operator FunctionType() const { return m_pFn; }
+#endif
+
+ // Can be used to verify that we have an actual function looked up and
+ // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
+ operator bool () const { return m_pFn != NULL; }
+ bool operator !() const { return m_pFn == NULL; }
+
+protected:
+ FunctionType m_pFn;
+
+#if GL_TELEMETRY_ZONES
+ char m_szName[32];
+ inline void SetFuncName(const char *pFn) { V_strncpy( m_szName, pFn, sizeof( m_szName ) ); }
+#else
+ inline void SetFuncName(const char *pFn) { (void)pFn; }
+#endif
+};
+
+// This works a lot like CDynamicFunctionMustInit, but we use SDL_GL_GetProcAddress().
+template < const bool bRequired, class FunctionType, typename Result >
+class CDynamicFunctionOpenGL : public CDynamicFunctionOpenGLBase< FunctionType, Result >
+{
+private: // forbid default constructor.
+ CDynamicFunctionOpenGL() {}
+
+public:
+ CDynamicFunctionOpenGL(const char *fn, FunctionType fallback=NULL)
+ {
+ bool okay = true;
+ Lookup(fn, okay, fallback);
+ this->SetFuncName( fn );
+ }
+
+ CDynamicFunctionOpenGL(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ Lookup(fn, okay, fallback);
+ this->SetFuncName( fn );
+ }
+
+ // Please note this is not virtual.
+ // !!! FIXME: we might want to fall back and try "EXT" or "ARB" versions in some case.
+ bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ if (this->m_pFn == NULL)
+ {
+ this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, bRequired, (void *) fallback);
+ this->SetFuncName( fn );
+ }
+ return okay;
+ }
+};
+
+
+// This provides all the entry points for a given OpenGL context.
+// ENTRY POINTS ARE ONLY VALID FOR THE CONTEXT THAT WAS CURRENT WHEN
+// YOU LOOKED THEM UP. 99% of the time, this is not a problem, but
+// that 1% is really hard to track down. Always access the GL
+// through this class!
+class COpenGLEntryPoints
+{
+public:
+ // The GL context you are looking up entry points for must be current when you construct this object!
+ COpenGLEntryPoints();
+
+ uint64 m_nTotalGLCycles, m_nTotalGLCalls;
+
+ int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2.
+ int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1.
+ int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0.
+ bool m_bHave_OpenGL;
+
+ #define GL_EXT(x,glmajor,glminor) bool m_bHave_##x;
+ #define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (APIENTRY *) arg, ret > fn;
+ #define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (APIENTRY *) arg, void > fn;
+ #include "togl/glfuncs.inl"
+ #undef GL_FUNC_VOID
+ #undef GL_FUNC
+ #undef GL_EXT
+};
+
+// This will be set to the current OpenGL context's entry points.
+extern COpenGLEntryPoints *gGL;
+typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, bool &, const bool, void *);
+
+#ifdef TOGL_DLL_EXPORT
+ DLL_EXPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
+ DLL_EXPORT void ToGLDisconnectLibraries();
+ DLL_EXPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
+#else
+ DLL_IMPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory );
+ DLL_IMPORT void ToGLDisconnectLibraries();
+ DLL_IMPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback);
+#endif
+
+#if GL_TELEMETRY_ZONES || GL_TRACK_API_TIME
+inline void CGLExecuteHelperBase::StartCall(const char *pName)
+{
+ (void)pName;
+
+#if GL_TELEMETRY_ZONES
+ tmEnter( TELEMETRY_LEVEL3, TMZF_NONE, pName );
+#endif
+
+#if GL_TRACK_API_TIME
+ m_nStartTime = tmFastTime();
+#endif
+}
+
+inline void CGLExecuteHelperBase::StopCall(const char *pName)
+{
+#if GL_TRACK_API_TIME
+ uint64 nTotalCycles = tmFastTime() - m_nStartTime;
+#endif
+
+#if GL_TELEMETRY_ZONES
+ tmLeave( TELEMETRY_LEVEL3 );
+#endif
+
+#if GL_TRACK_API_TIME
+ //double flMilliseconds = g_Telemetry.flRDTSCToMilliSeconds * nTotalCycles;
+ if (gGL)
+ {
+ gGL->m_nTotalGLCycles += nTotalCycles;
+ gGL->m_nTotalGLCalls++;
+ }
+#endif
+}
+#endif
+
+#endif // DX_TO_GL_ABSTRACTION
+
+#endif // GLENTRYPOINTS_H
diff --git a/mp/src/public/togl/osx/glfuncs.h b/mp/src/public/togl/osx/glfuncs.h new file mode 100644 index 00000000..484786c6 --- /dev/null +++ b/mp/src/public/togl/osx/glfuncs.h @@ -0,0 +1,184 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+// !!! FIXME: Some of these aren't base OpenGL...pick out the extensions.
+// !!! FIXME: Also, look up these -1, -1 versions numbers.
+GL_FUNC(OpenGL,true,GLenum,glGetError,(void),())
+GL_FUNC_VOID(OpenGL,true,glActiveTexture,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glAlphaFunc,(GLenum a,GLclampf b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glAttachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBegin,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glBindAttribLocationARB,(GLhandleARB a,GLuint b,const GLcharARB *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glBindBufferARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBindProgramARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBindTexture,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBlendColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glBlendEquation,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glBlendFunc,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glBufferDataARB,(GLenum a,GLsizeiptrARB b,const GLvoid *c,GLenum d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glClear,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glClearColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glClearDepth,(GLclampd a),(a))
+GL_FUNC_VOID(OpenGL,true,glClearStencil,(GLint a),(a))
+GL_FUNC_VOID(OpenGL,true,glClipPlane,(GLenum a,const GLdouble *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glColorMask,(GLboolean a,GLboolean b,GLboolean c,GLboolean d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glCompileShaderARB,(GLhandleARB a),(a))
+GL_FUNC_VOID(OpenGL,true,glCompressedTexImage2D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLint f,GLsizei g,const GLvoid *h),(a,b,c,d,e,f,g,h))
+GL_FUNC_VOID(OpenGL,true,glCompressedTexImage3D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLsizei h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC(OpenGL,true,GLhandleARB,glCreateProgramObjectARB,(void),())
+GL_FUNC(OpenGL,true,GLhandleARB,glCreateShaderObjectARB,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteBuffersARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteObjectARB,(GLhandleARB a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteProgramsARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteQueriesARB,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDeleteShader,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glDeleteTextures,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDepthFunc,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDepthMask,(GLboolean a),(a))
+GL_FUNC_VOID(OpenGL,true,glDepthRange,(GLclampd a,GLclampd b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDetachObjectARB,(GLhandleARB a,GLhandleARB b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glDisable,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDisableVertexAttribArray,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glDrawArrays,(GLenum a,GLint b,GLsizei c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glDrawBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDrawRangeElements,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glEnd,(void),())
+GL_FUNC_VOID(OpenGL,true,glFinish,(void),())
+GL_FUNC_VOID(OpenGL,true,glFlush,(void),())
+GL_FUNC_VOID(OpenGL,true,glFrontFace,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glGenBuffersARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenProgramsARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenQueriesARB,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGenTextures,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetBooleanv,(GLenum a,GLboolean *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetCompressedTexImage,(GLenum a,GLint b,GLvoid *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glGetDoublev,(GLenum a,GLdouble *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetFloatv,(GLenum a,GLfloat *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetInfoLogARB,(GLhandleARB a,GLsizei b,GLsizei *c,GLcharARB *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glGetIntegerv,(GLenum a,GLint *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glGetObjectParameterivARB,(GLhandleARB a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glGetProgramivARB,(GLenum a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC(OpenGL,true,const GLubyte *,glGetString,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glGetTexImage,(GLenum a,GLint b,GLenum c,GLenum d,GLvoid *e),(a,b,c,d,e))
+GL_FUNC(OpenGL,true,GLint,glGetUniformLocationARB,(GLhandleARB a,const GLcharARB *b),(a,b))
+GL_FUNC(OpenGL,true,GLboolean,glIsEnabled,(GLenum a),(a))
+GL_FUNC(OpenGL,true,GLboolean,glIsTexture,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glLinkProgramARB,(GLhandleARB a),(a))
+GL_FUNC(OpenGL,true,GLvoid*,glMapBufferARB,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glOrtho,(GLdouble a,GLdouble b,GLdouble c,GLdouble d,GLdouble e,GLdouble f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glPixelStorei,(GLenum a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPolygonMode,(GLenum a,GLenum b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPolygonOffset,(GLfloat a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPopAttrib,(void),())
+GL_FUNC_VOID(OpenGL,true,glProgramStringARB,(GLenum a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glPushAttrib,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glReadBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glScissor,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glShaderSourceARB,(GLhandleARB a,GLsizei b,const GLcharARB **c,const GLint *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glStencilFunc,(GLenum a,GLint b,GLuint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glStencilMask,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glStencilOp,(GLenum a,GLenum b,GLenum c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexCoord2f,(GLfloat a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glTexImage2D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLint f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC_VOID(OpenGL,true,glTexImage3D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLenum h,GLenum i,const GLvoid *j),(a,b,c,d,e,f,g,h,i,j))
+GL_FUNC_VOID(OpenGL,true,glTexParameterfv,(GLenum a,GLenum b,const GLfloat *c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexParameteri,(GLenum a,GLenum b,GLint c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glTexSubImage2D,(GLenum a,GLint b,GLint c,GLint d,GLsizei e,GLsizei f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i))
+GL_FUNC_VOID(OpenGL,true,glUniform1f,(GLint a,GLfloat b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform1i,(GLint a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform1iARB,(GLint a,GLint b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glUniform4fv,(GLint a,GLsizei b,const GLfloat *c),(a,b,c))
+GL_FUNC(OpenGL,true,GLboolean,glUnmapBuffer,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glUseProgram,(GLuint a),(a))
+GL_FUNC_VOID(OpenGL,true,glVertex3f,(GLfloat a,GLfloat b,GLfloat c),(a,b,c))
+GL_FUNC_VOID(OpenGL,true,glVertexAttribPointer,(GLuint a,GLint b,GLenum c,GLboolean d,GLsizei e,const GLvoid *f),(a,b,c,d,e,f))
+GL_FUNC_VOID(OpenGL,true,glViewport,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glEnableClientState,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glDisableClientState,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glClientActiveTexture,(GLenum a),(a))
+GL_FUNC_VOID(OpenGL,true,glVertexPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glTexCoordPointer,(GLint a,GLenum b,GLsizei c,const GLvoid *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glProgramEnvParameters4fvEXT,(GLenum a,GLuint b,GLsizei c,const GLfloat *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glColor4sv,(const GLshort *a),(a))
+GL_FUNC_VOID(OpenGL,true,glStencilOpSeparate,(GLenum a,GLenum b,GLenum c,GLenum d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glStencilFuncSeparate,(GLenum a,GLenum b,GLint c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glGetTexLevelParameteriv,(GLenum a,GLint b,GLenum c,GLint *d),(a,b,c,d))
+GL_FUNC_VOID(OpenGL,true,glColor4f,(GLfloat a,GLfloat b,GLfloat c,GLfloat d),(a,b,c,d))
+GL_EXT(GL_EXT_framebuffer_object,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindFramebufferEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glBindRenderbufferEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC(GL_EXT_framebuffer_object,false,GLenum,glCheckFramebufferStatusEXT,(GLenum a),(a))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteRenderbuffersEXT,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferRenderbufferEXT,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture2DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glFramebufferTexture3DEXT,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenFramebuffersEXT,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glGenRenderbuffersEXT,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_EXT_framebuffer_object,false,glDeleteFramebuffersEXT,(GLsizei a,const GLuint *b),(a,b))
+GL_EXT(GL_EXT_framebuffer_blit,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_blit,false,glBlitFramebufferEXT,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j))
+GL_EXT(GL_EXT_framebuffer_multisample,-1,-1)
+GL_FUNC_VOID(GL_EXT_framebuffer_multisample,false,glRenderbufferStorageMultisampleEXT,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e))
+GL_EXT(GL_APPLE_fence,-1,-1)
+GL_FUNC(GL_APPLE_fence,false,GLboolean,glTestFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glSetFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glFinishFenceAPPLE,(GLuint a),(a))
+GL_FUNC_VOID(GL_APPLE_fence,false,glDeleteFencesAPPLE,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_APPLE_fence,false,glGenFencesAPPLE,(GLsizei a,GLuint *b),(a,b))
+GL_EXT(GL_NV_fence,-1,-1)
+GL_FUNC(GL_NV_fence,false,GLboolean,glTestFenceNV,(GLuint a),(a))
+GL_FUNC_VOID(GL_NV_fence,false,glSetFenceNV,(GLuint a,GLenum b),(a,b))
+GL_FUNC_VOID(GL_NV_fence,false,glFinishFenceNV,(GLuint a),(a))
+GL_FUNC_VOID(GL_NV_fence,false,glDeleteFencesNV,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_NV_fence,false,glGenFencesNV,(GLsizei a,GLuint *b),(a,b))
+GL_EXT(GL_ARB_sync,3,2)
+#ifdef HAVE_GL_ARB_SYNC
+GL_FUNC_VOID(GL_ARB_sync,false,glGetSynciv,(GLsync a, GLenum b, GLsizei c, GLsizei *d, GLint *e),(a,b,c,d,e))
+GL_FUNC(GL_ARB_sync,false,GLenum,glClientWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_sync,false,glWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_sync,false,glDeleteSync,(GLsync a),(a))
+GL_FUNC(GL_ARB_sync,false,GLsync,glFenceSync,(GLenum a, GLbitfield b),(a,b))
+#endif
+GL_EXT(GL_EXT_draw_buffers2,-1,-1)
+GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glColorMaskIndexedEXT,(GLuint a,GLboolean b,GLboolean c,GLboolean d,GLboolean e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glEnableIndexedEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glDisableIndexedEXT,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_EXT_draw_buffers2,false,glGetBooleanIndexedvEXT,(GLenum a,GLuint b,GLboolean *c),(a,b,c))
+GL_EXT(GL_EXT_bindable_uniform,-1,-1)
+GL_FUNC_VOID(GL_EXT_bindable_uniform,false,glUniformBufferEXT,(GLuint a,GLint b,GLuint c),(a,b,c))
+GL_EXT(GL_APPLE_flush_buffer_range,-1,-1)
+GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glBufferParameteriAPPLE,(GLenum a,GLenum b,GLint c),(a,b,c))
+GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glFlushMappedBufferRangeAPPLE,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c))
+GL_EXT(GL_ARB_map_buffer_range,-1,-1)
+GL_FUNC(GL_ARB_map_buffer_range,false,void*,glMapBufferRange,(GLenum a,GLintptr b,GLsizeiptr c,GLbitfield d),(a,b,c,d))
+GL_FUNC_VOID(GL_ARB_map_buffer_range,false,glFlushMappedBufferRange,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c))
+GL_EXT(GL_ARB_occlusion_query,-1,-1)
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glBeginQueryARB,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glEndQueryARB,(GLenum a),(a))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectivARB,(GLuint a,GLenum b,GLint *c),(a,b,c))
+GL_FUNC_VOID(GL_ARB_occlusion_query,false,glGetQueryObjectuivARB,(GLuint a,GLenum b,GLuint *c),(a,b,c))
+GL_EXT(GL_APPLE_texture_range,-1,-1)
+GL_FUNC_VOID(GL_APPLE_texture_range,false,glTextureRangeAPPLE,(GLenum a,GLsizei b,void *c),(a,b,c))
+GL_FUNC_VOID(GL_APPLE_texture_range,false,glGetTexParameterPointervAPPLE,(GLenum a,GLenum b,void* *c),(a,b,c))
+GL_EXT(GL_APPLE_client_storage,-1,-1)
+GL_EXT(GL_ARB_uniform_buffer,-1,-1)
+GL_EXT(GL_ARB_vertex_array_bgra,-1,-1)
+GL_EXT(GL_EXT_vertex_array_bgra,-1,-1)
+GL_EXT(GL_ARB_framebuffer_object,3,0)
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindFramebuffer,(GLenum a,GLuint b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindRenderbuffer,(GLenum a,GLuint b),(a,b))
+GL_FUNC(GL_ARB_framebuffer_object,false,GLenum,glCheckFramebufferStatus,(GLenum a),(a))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteRenderbuffers,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferRenderbuffer,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture2D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture3D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenFramebuffers,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenRenderbuffers,(GLsizei a,GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteFramebuffers,(GLsizei a,const GLuint *b),(a,b))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBlitFramebuffer,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j))
+GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glRenderbufferStorageMultisample,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e))
+GL_EXT(GL_GREMEDY_string_marker,-1,-1)
+GL_FUNC_VOID(GL_GREMEDY_string_marker,false,glStringMarkerGREMEDY,(GLsizei a,const void *b),(a,b))
+GL_FUNC_VOID(OpenGL,true,glPushClientAttrib,(GLbitfield a),(a))
+GL_FUNC_VOID(OpenGL,true,glPopClientAttrib,(void),())
+
diff --git a/mp/src/public/togl/osx/glmdebug.h b/mp/src/public/togl/osx/glmdebug.h new file mode 100644 index 00000000..5981677d --- /dev/null +++ b/mp/src/public/togl/osx/glmdebug.h @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef GLMDEBUG_H
+#define GLMDEBUG_H
+
+#include "tier0/platform.h"
+#include <stdarg.h>
+
+// include this anywhere you need to be able to compile-out code related specifically to GLM debugging.
+
+// we expect DEBUG to be driven by the build system so you can include this header anywhere.
+// when we come out, GLMDEBUG will be defined to a value - 0, 1, or 2
+// 0 means no GLM debugging is possible
+// 1 means it's possible and resulted from being a debug build
+// 2 means it's possible and resulted from being manually forced on for a release build
+
+#ifdef POSIX
+ #ifndef GLMDEBUG
+ #ifdef DEBUG
+ #define GLMDEBUG 1 // normally 1 here, testing
+ #else
+ // #define GLMDEBUG 2 // don't check this in enabled..
+ #endif
+
+ #ifndef GLMDEBUG
+ #define GLMDEBUG 0
+ #endif
+ #endif
+#else
+ #ifndef GLMDEBUG
+ #define GLMDEBUG 0
+ #endif
+#endif
+
+
+//===============================================================================
+// debug channels
+
+enum EGLMDebugChannel
+{
+ ePrintf,
+ eDebugger,
+ eGLProfiler
+};
+
+#if GLMDEBUG
+ // make all these prototypes disappear in non GLMDEBUG
+ void GLMDebugInitialize( bool forceReinit=false );
+
+ bool GLMDetectOGLP( void );
+ bool GLMDetectGDB( void );
+ uint GLMDetectAvailableChannels( void );
+
+ uint GLMDebugChannelMask( uint *newValue = NULL );
+ // note that GDB and OGLP can both come and go during run - forceCheck will allow that to be detected.
+ // mask returned is in form of 1<<n, n from EGLMDebugChannel
+#endif
+
+//===============================================================================
+// debug message flavors
+
+enum EGLMDebugFlavor
+{
+ eAllFlavors, // 0
+ eDebugDump, // 1 debug dump flavor -D-
+ eTenure, // 2 code tenures > <
+ eComment, // 3 one off messages ---
+ eMatrixData, // 4 matrix data -M-
+ eShaderData, // 5 shader data (params) -S-
+ eFrameBufData, // 6 FBO data (attachments) -F-
+ eDXStuff, // 7 dxabstract spew -X-
+ eAllocations, // 8 tracking allocs and frees -A-
+ eSlowness, // 9 slow things happening (srgb flips..) -Z-
+ eDefaultFlavor, // not specified (no marker)
+ eFlavorCount
+};
+uint GLMDebugFlavorMask( uint *newValue = NULL );
+
+// make all these prototypes disappear in non GLMDEBUG
+#if GLMDEBUG
+ // these are unconditional outputs, they don't interrogate the string
+ void GLMStringOut( const char *string );
+ void GLMStringOutIndented( const char *string, int indentColumns );
+
+ #ifdef TOGL_DLL_EXPORT
+ // these will look at the string to guess its flavor: <, >, ---, -M-, -S-
+ DLL_EXPORT void GLMPrintfVA( const char *fmt, va_list vargs );
+ DLL_EXPORT void GLMPrintf( const char *fmt, ... );
+ #else
+ DLL_IMPORT void GLMPrintfVA( const char *fmt, va_list vargs );
+ DLL_IMPORT void GLMPrintf( const char *fmt, ... );
+ #endif
+
+ // these take an explicit flavor with a default value
+ void GLMPrintStr( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor );
+
+ #define GLMPRINTTEXT_NUMBEREDLINES 0x80000000
+ void GLMPrintText( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor, uint options=0 ); // indent each newline
+
+ int GLMIncIndent( int indentDelta );
+ int GLMGetIndent( void );
+ void GLMSetIndent( int indent );
+
+#endif
+
+// helpful macro if you are in a position to call GLM functions directly (i.e. you live in materialsystem / shaderapidx9)
+#if GLMDEBUG
+ #define GLMPRINTF(args) GLMPrintf args
+ #define GLMPRINTSTR(args) GLMPrintStr args
+ #define GLMPRINTTEXT(args) GLMPrintText args
+#else
+ #define GLMPRINTF(args)
+ #define GLMPRINTSTR(args)
+ #define GLMPRINTTEXT(args)
+#endif
+
+
+//===============================================================================
+// knob twiddling
+#ifdef TOGL_DLL_EXPORT
+ DLL_EXPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value
+ DLL_EXPORT float GLMKnobToggle( char *knobname );
+#else
+ DLL_IMPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value
+ DLL_IMPORT float GLMKnobToggle( char *knobname );
+#endif
+
+//===============================================================================
+// other stuff
+
+#if GLMDEBUG
+void GLMTriggerDebuggerBreak();
+inline void GLMDebugger( void )
+{
+ if (GLMDebugChannelMask() & (1<<eDebugger))
+ {
+ DebuggerBreak();
+ }
+
+ if (GLMDebugChannelMask() & (1<<eGLProfiler))
+ {
+ GLMTriggerDebuggerBreak();
+ }
+}
+#else
+ #define GLMDebugger() do { } while(0)
+#endif
+
+// helpers for CGLSetOption - no op if no profiler
+void GLMProfilerClearTrace( void );
+void GLMProfilerEnableTrace( bool enable );
+
+// helpers for CGLSetParameter - no op if no profiler
+void GLMProfilerDumpState( void );
+
+void CheckGLError( int line );
+
+#endif // GLMDEBUG_H
diff --git a/mp/src/public/togl/osx/glmdisplay.h b/mp/src/public/togl/osx/glmdisplay.h new file mode 100644 index 00000000..fdb594fe --- /dev/null +++ b/mp/src/public/togl/osx/glmdisplay.h @@ -0,0 +1,177 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmdisplay.h
+// display related stuff - used by both GLMgr and the CocoaMgr
+//
+//===============================================================================
+
+#ifndef GLMDISPLAY_H
+#define GLMDISPLAY_H
+
+#pragma once
+
+#ifdef OSX
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/CGLTypes.h>
+#include <OpenGL/CGLRenderers.h>
+#include <OpenGL/CGLCurrent.h>
+
+typedef uint32_t CGDirectDisplayID;
+typedef uint32_t CGOpenGLDisplayMask;
+typedef double CGRefreshRate;
+
+//#include <ApplicationServices/ApplicationServices.h>
+#elif defined(LINUX)
+#include "tier0/platform.h"
+#include <GL/gl.h>
+#include <GL/glext.h>
+#else
+#error
+#endif
+
+typedef void _PseudoNSGLContext; // aka NSOpenGLContext
+typedef _PseudoNSGLContext *PseudoNSGLContextPtr;
+
+struct GLMDisplayModeInfoFields
+{
+ uint m_modePixelWidth;
+ uint m_modePixelHeight;
+ uint m_modeRefreshHz;
+ // are we even going to talk about bit depth... not yet
+};
+
+struct GLMDisplayInfoFields
+{
+#ifdef OSX
+ CGDirectDisplayID m_cgDisplayID;
+ CGOpenGLDisplayMask m_glDisplayMask; // result of CGDisplayIDToOpenGLDisplayMask on the cg_displayID.
+#endif
+ uint m_displayPixelWidth;
+ uint m_displayPixelHeight;
+};
+
+struct GLMRendererInfoFields
+{
+ /*properties of interest and their desired values.
+
+ kCGLRPFullScreen = 54, true
+ kCGLRPAccelerated = 73, true
+ kCGLRPWindow = 80, true
+
+ kCGLRPRendererID = 70, informational
+ kCGLRPDisplayMask = 84, informational
+ kCGLRPBufferModes = 100, informational
+ kCGLRPColorModes = 103, informational
+ kCGLRPAccumModes = 104, informational
+ kCGLRPDepthModes = 105, informational
+ kCGLRPStencilModes = 106, informational
+ kCGLRPMaxAuxBuffers = 107, informational
+ kCGLRPMaxSampleBuffers = 108, informational
+ kCGLRPMaxSamples = 109, informational
+ kCGLRPSampleModes = 110, informational
+ kCGLRPSampleAlpha = 111, informational
+ kCGLRPVideoMemory = 120, informational
+ kCGLRPTextureMemory = 121, informational
+ kCGLRPRendererCount = 128 number of renderers in the CGLRendererInfoObj under examination
+
+ kCGLRPOffScreen = 53, D/C
+ kCGLRPRobust = 75, FALSE or D/C - aka we're asking for no-fallback
+ kCGLRPBackingStore = 76, D/C
+ kCGLRPMPSafe = 78, D/C
+ kCGLRPMultiScreen = 81, D/C
+ kCGLRPCompliant = 83, D/C
+ */
+
+
+ //--------------------------- info we have from CGL renderer queries, IOKit, Gestalt
+ //--------------------------- these are set up in the displayDB by CocoaMgr
+ GLint m_fullscreen;
+ GLint m_accelerated;
+ GLint m_windowed;
+
+ GLint m_rendererID;
+ GLint m_displayMask;
+ GLint m_bufferModes;
+ GLint m_colorModes;
+ GLint m_accumModes;
+ GLint m_depthModes;
+ GLint m_stencilModes;
+
+ GLint m_maxAuxBuffers;
+ GLint m_maxSampleBuffers;
+ GLint m_maxSamples;
+ GLint m_sampleModes;
+ GLint m_sampleAlpha;
+
+ GLint m_vidMemory;
+ GLint m_texMemory;
+
+ uint m_pciVendorID;
+ uint m_pciDeviceID;
+ char m_pciModelString[64];
+ char m_driverInfoString[64];
+
+ //--------------------------- OS version related - set up by CocoaMgr
+
+ // OS version found
+ uint m_osComboVersion; // 0x00XXYYZZ : XX major, YY minor, ZZ minor minor : 10.6.3 --> 0x000A0603. 10.5.8 --> 0x000A0508.
+
+ //--------------------------- shorthands - also set up by CocoaMgr - driven by vendorid / deviceid
+
+ bool m_ati;
+ bool m_atiR5xx;
+ bool m_atiR6xx;
+ bool m_atiR7xx;
+ bool m_atiR8xx;
+ bool m_atiNewer;
+
+ bool m_intel;
+ bool m_intel95x;
+ bool m_intel3100;
+ bool m_intelNewer;
+
+ bool m_nv;
+ bool m_nvG7x;
+ bool m_nvG8x;
+ bool m_nvNewer;
+
+ //--------------------------- context query results - left blank in the display DB - but valid in a GLMContext (call ctx->Caps() to get a const ref)
+
+ // booleans
+ bool m_hasGammaWrites; // aka glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) / glEnable(GL_FRAMEBUFFER_SRGB_EXT)
+ bool m_hasMixedAttachmentSizes; // aka ARB_fbo in 10.6.3 - test for min OS vers, then exported ext string
+ bool m_hasBGRA; // aka GL_BGRA vertex attribs in 10.6.3 - - test for min OS vers, then exported ext string
+ bool m_hasNewFullscreenMode; // aka 10.6.x "big window" fullscreen mode
+ bool m_hasNativeClipVertexMode; // aka GLSL gl_ClipVertex does not fall back to SW- OS version and folklore-based
+ bool m_hasOcclusionQuery; // occlusion query: do you speak it ?!
+ bool m_hasFramebufferBlit; // framebuffer blit: know what I'm sayin?!
+ bool m_hasPerfPackage1; // means new MTGL, fast OQ, fast uniform upload, NV can resolve flipped (late summer 2010 post 10.6.4 update)
+
+ // counts
+ int m_maxAniso; // aniso limit - context query
+
+ // other exts
+ bool m_hasBindableUniforms;
+ bool m_hasUniformBuffers;
+
+ // runtime options that aren't negotiable once set
+ bool m_hasDualShaders; // must supply CLI arg "-glmdualshaders" or we go GLSL only
+
+ //--------------------------- " can'ts " - specific problems that need to be worked around
+
+ bool m_cantBlitReliably; // Intel chipsets have problems blitting sRGB sometimes
+ bool m_cantAttachSRGB; // NV G8x on 10.5.8 can't have srgb tex on FBO color - separate issue from hasGammaWrites
+ bool m_cantResolveFlipped; // happens on NV in 10.6.4 and prior - console variable "gl_can_resolve_flipped" can overrule
+ bool m_cantResolveScaled; // happens everywhere per GL spec but may be relaxed some day - console variable "gl_can_resolve_scaled" can overrule
+ bool m_costlyGammaFlips; // this means that sRGB sampling state affects shader code gen, resulting in state-dependent code regen
+
+
+ //--------------------------- " bads " - known bad drivers
+ bool m_badDriver1064NV; // this is the bad NVIDIA driver on 10.6.4 - stutter, tex corruption, black screen issues
+};
+
+
+
+#endif
diff --git a/mp/src/public/togl/osx/glmdisplaydb.h b/mp/src/public/togl/osx/glmdisplaydb.h new file mode 100644 index 00000000..4588aff3 --- /dev/null +++ b/mp/src/public/togl/osx/glmdisplaydb.h @@ -0,0 +1,115 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef GLMDISPLAYDB_H
+#define GLMDISPLAYDB_H
+
+#include "tier1/utlvector.h"
+
+//===============================================================================
+
+// modes, displays, and renderers
+// think of renderers as being at the top of a tree.
+// each renderer has displays hanging off of it.
+// each display has modes hanging off of it.
+// the tree is populated on demand and then queried as needed.
+
+//===============================================================================
+
+// GLMDisplayModeInfoFields is in glmdisplay.h
+
+class GLMDisplayMode
+{
+public:
+ GLMDisplayModeInfoFields m_info;
+
+ GLMDisplayMode( uint width, uint height, uint refreshHz );
+ GLMDisplayMode() { };
+ ~GLMDisplayMode( void );
+
+
+ void Init( uint width, uint height, uint refreshHz );
+ void Dump( int which );
+};
+
+//===============================================================================
+
+// GLMDisplayInfoFields is in glmdisplay.h
+
+class GLMDisplayInfo
+{
+public:
+ GLMDisplayInfoFields m_info;
+ CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes
+
+ GLMDisplayInfo( void );
+ ~GLMDisplayInfo( void );
+
+ void PopulateModes( void );
+
+ void Dump( int which );
+};
+
+//===============================================================================
+
+// GLMRendererInfoFields is in glmdisplay.h
+
+class GLMRendererInfo
+{
+public:
+ GLMRendererInfoFields m_info;
+ GLMDisplayInfo *m_display; // starts out NULL, set by PopulateDisplays
+
+ GLMRendererInfo ( GLMRendererInfoFields *info );
+ ~GLMRendererInfo ( void );
+
+ void PopulateDisplays();
+ void Dump( int which );
+};
+
+//===============================================================================
+
+// this is just a tuple describing fake adapters which are really renderer/display pairings.
+// dxabstract bridges the gap between the d3d adapter-centric world and the GL renderer+display world.
+// this makes it straightforward to handle cases like two video cards with two displays on one, and one on the other -
+// you get three fake adapters which represent each useful screen.
+
+// the constraint that dxa will have to follow though, is that if the user wants to change their
+// display selection for full screen, they would only be able to pick on that has the same underlying renderer.
+// can't change fakeAdapter from one to another with different GL renderer under it. Screen hop but no card hop.
+
+struct GLMFakeAdapter
+{
+ int m_rendererIndex;
+ int m_displayIndex;
+};
+
+class GLMDisplayDB
+{
+public:
+ CUtlVector< GLMRendererInfo* > *m_renderers; // starts out NULL, set by PopulateRenderers
+
+ CUtlVector< GLMFakeAdapter > m_fakeAdapters;
+
+ GLMDisplayDB ( void );
+ ~GLMDisplayDB ( void );
+
+ virtual void PopulateRenderers( void );
+ virtual void PopulateFakeAdapters( uint realRendererIndex ); // fake adapters = one real adapter times however many displays are on it
+ virtual void Populate( void );
+
+ // The info-get functions return false on success.
+ virtual int GetFakeAdapterCount( void );
+ virtual bool GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut );
+
+ virtual int GetRendererCount( void );
+ virtual bool GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut );
+
+ virtual int GetDisplayCount( int rendererIndex );
+ virtual bool GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut );
+
+ virtual int GetModeCount( int rendererIndex, int displayIndex );
+ virtual bool GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut );
+
+ virtual void Dump( void );
+};
+
+#endif // GLMDISPLAYDB_H
diff --git a/mp/src/public/togl/osx/glmgr.h b/mp/src/public/togl/osx/glmgr.h new file mode 100644 index 00000000..1e951ca9 --- /dev/null +++ b/mp/src/public/togl/osx/glmgr.h @@ -0,0 +1,1088 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgr.h
+// singleton class, common basis for managing GL contexts
+// responsible for tracking adapters and contexts
+//
+//===============================================================================
+
+#ifndef GLMGR_H
+#define GLMGR_H
+
+#pragma once
+
+#undef HAVE_GL_ARB_SYNC
+#ifdef LINUX
+#define HAVE_GL_ARB_SYNC 1
+#endif
+
+#include "glentrypoints.h"
+#include "glmdebug.h"
+#include "glmdisplay.h"
+#include "glmgrext.h"
+#include "glmgrbasics.h"
+#include "cglmtex.h"
+#include "cglmfbo.h"
+#include "cglmprogram.h"
+#include "cglmbuffer.h"
+#include "cglmquery.h"
+
+#include "tier0/vprof_telemetry.h"
+#include "materialsystem/ishader.h"
+#include "dxabstract_types.h"
+
+
+#ifdef LINUX
+#define Debugger DebuggerBreak
+#undef CurrentTime
+
+// prevent some conflicts in SDL headers...
+#undef M_PI
+#include <stdint.h>
+#ifndef _STDINT_H_
+#define _STDINT_H_ 1
+#endif
+
+#include "SDL/SDL.h"
+#endif
+
+//===============================================================================
+// glue to call out to Obj-C land (these are in glmgrcocoa.mm)
+#ifdef OSX
+PseudoNSGLContextPtr GetCurrentNSGLContext( );
+CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx );
+#endif
+
+#include "tier0/dynfunction.h"
+
+//===============================================================================
+
+// parrot the D3D present parameters, more or less... "adapter" translates into "active display index" per the m_activeDisplayCount below.
+class GLMDisplayParams
+{
+ public:
+
+ // presumption, these indices are in sync with the current display DB that GLMgr has handy
+ //int m_rendererIndex; // index of renderer (-1 if root context)
+ //int m_displayIndex; // index of display in renderer - for FS
+ //int m_modeIndex; // index of mode in display - for FS
+
+ void *m_focusWindow; // (VD3DHWND aka WindowRef) - what window does this context display into
+
+ bool m_fsEnable; // fullscreen on or not
+ bool m_vsyncEnable; // vsync on or not
+
+ // height and width have to match the display mode info if full screen.
+
+ uint m_backBufferWidth; // pixel width (aka screen h-resolution if full screen)
+ uint m_backBufferHeight; // pixel height (aka screen v-resolution if full screen)
+ D3DFORMAT m_backBufferFormat; // pixel format
+ uint m_multiSampleCount; // 0 means no MSAA, 2 means 2x MSAA, etc
+ // uint m_multiSampleQuality; // no MSAA quality control yet
+
+ bool m_enableAutoDepthStencil; // generally set to 'TRUE' per CShaderDeviceDx8::SetPresentParameters
+ D3DFORMAT m_autoDepthStencilFormat;
+
+ uint m_fsRefreshHz; // if full screen, this refresh rate (likely 0 for LCD's)
+
+ //uint m_rootRendererID; // only used if m_rendererIndex is -1.
+ //uint m_rootDisplayMask; // only used if m_rendererIndex is -1.
+
+ bool m_mtgl; // enable multi threaded GL driver
+};
+
+//===============================================================================
+
+class GLMgr
+{
+public:
+
+ //===========================================================================
+ // class methods - singleton
+ static void NewGLMgr( void ); // instantiate singleton..
+ static GLMgr *aGLMgr( void ); // return singleton..
+ static void DelGLMgr( void ); // tear down singleton..
+
+ //===========================================================================
+ // plain methods
+
+ #if 0 // turned all these off while new approach is coded
+ void RefreshDisplayDB( void ); // blow away old display DB, make a new one
+ GLMDisplayDB *GetDisplayDB( void ); // get a ptr to the one GLMgr keeps. only valid til next refresh.
+
+ // eligible renderers will be ranked by desirability starting at index 0 within the db
+ // within each renderer, eligible displays will be ranked some kind of desirability (area? dist from menu bar?)
+ // within each display, eligible modes will be ranked by descending areas
+
+ // calls supplying indices are implicitly making reference to the current DB
+ bool CaptureDisplay( int rendIndex, int displayIndex, bool captureAll ); // capture one display or all displays
+ void ReleaseDisplays( void ); // release all captures
+
+ int GetDisplayMode( int rendIndex, int displayIndex ); // retrieve current display res (returns modeIndex)
+ void SetDisplayMode( GLMDisplayParams *params ); // set the display res (only useful for FS)
+ #endif
+
+ GLMContext *NewContext( GLMDisplayParams *params ); // this will have to change
+ void DelContext( GLMContext *context );
+
+ // with usage of CGLMacro.h we could dispense with the "current context" thing
+ // and just declare a member variable of GLMContext, allowing each glXXX call to be routed directly
+ // to the correct context
+ void SetCurrentContext( GLMContext *context ); // make current in calling thread only
+ GLMContext *GetCurrentContext( void );
+
+protected:
+ friend class GLMContext;
+
+ GLMgr();
+ ~GLMgr();
+};
+
+
+//===========================================================================//
+
+// helper function to do enable or disable in one step
+inline void glSetEnable( GLenum which, bool enable )
+{
+ if (enable)
+ gGL->glEnable(which);
+ else
+ gGL->glDisable(which);
+}
+
+// helper function for int vs enum clarity
+inline void glGetEnumv( GLenum which, GLenum *dst )
+{
+ gGL->glGetIntegerv( which, (int*)dst );
+}
+
+//===========================================================================//
+//
+// types to support the GLMContext
+//
+//===========================================================================//
+
+// Each state set/get path we are providing caching for, needs its own struct and a comparison operator.
+// we also provide an enum of how many such types there are, handy for building dirty masks etc.
+
+// shorthand macros
+#define EQ(fff) ( (src.fff) == (fff) )
+
+//rasterizer
+struct GLAlphaTestEnable_t { GLint enable; bool operator==(const GLAlphaTestEnable_t& src) const { return EQ(enable); } };
+struct GLAlphaTestFunc_t { GLenum func; GLclampf ref; bool operator==(const GLAlphaTestFunc_t& src) const { return EQ(func) && EQ(ref); } };
+struct GLCullFaceEnable_t { GLint enable; bool operator==(const GLCullFaceEnable_t& src) const { return EQ(enable); } };
+struct GLCullFrontFace_t { GLenum value; bool operator==(const GLCullFrontFace_t& src) const { return EQ(value); } };
+struct GLPolygonMode_t { GLenum values[2]; bool operator==(const GLPolygonMode_t& src) const { return EQ(values[0]) && EQ(values[1]); } };
+struct GLDepthBias_t { GLfloat factor; GLfloat units; bool operator==(const GLDepthBias_t& src) const { return EQ(factor) && EQ(units); } };
+struct GLScissorEnable_t { GLint enable; bool operator==(const GLScissorEnable_t& src) const { return EQ(enable); } };
+struct GLScissorBox_t { GLint x,y; GLsizei width, height; bool operator==(const GLScissorBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } };
+struct GLAlphaToCoverageEnable_t{ GLint enable; bool operator==(const GLAlphaToCoverageEnable_t& src) const { return EQ(enable); } };
+struct GLViewportBox_t { GLint x,y; GLsizei width, height; bool operator==(const GLViewportBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } };
+struct GLViewportDepthRange_t { GLdouble near,far; bool operator==(const GLViewportDepthRange_t& src) const { return EQ(near) && EQ(far); } };
+struct GLClipPlaneEnable_t { GLint enable; bool operator==(const GLClipPlaneEnable_t& src) const { return EQ(enable); } };
+struct GLClipPlaneEquation_t { GLfloat x,y,z,w; bool operator==(const GLClipPlaneEquation_t& src) const { return EQ(x) && EQ(y) && EQ(z) && EQ(w); } };
+
+//blend
+struct GLColorMaskSingle_t { char r,g,b,a; bool operator==(const GLColorMaskSingle_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLColorMaskMultiple_t { char r,g,b,a; bool operator==(const GLColorMaskMultiple_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLBlendEnable_t { GLint enable; bool operator==(const GLBlendEnable_t& src) const { return EQ(enable); } };
+struct GLBlendFactor_t { GLenum srcfactor,dstfactor; bool operator==(const GLBlendFactor_t& src) const { return EQ(srcfactor) && EQ(dstfactor); } };
+struct GLBlendEquation_t { GLenum equation; bool operator==(const GLBlendEquation_t& src) const { return EQ(equation); } };
+struct GLBlendColor_t { GLfloat r,g,b,a; bool operator==(const GLBlendColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLBlendEnableSRGB_t { GLint enable; bool operator==(const GLBlendEnableSRGB_t& src) const { return EQ(enable); } };
+
+//depth
+struct GLDepthTestEnable_t { GLint enable; bool operator==(const GLDepthTestEnable_t& src) const { return EQ(enable); } };
+struct GLDepthFunc_t { GLenum func; bool operator==(const GLDepthFunc_t& src) const { return EQ(func); } };
+struct GLDepthMask_t { char mask; bool operator==(const GLDepthMask_t& src) const { return EQ(mask); } };
+
+//stencil
+struct GLStencilTestEnable_t { GLint enable; bool operator==(const GLStencilTestEnable_t& src) const { return EQ(enable); } };
+struct GLStencilFunc_t { GLenum frontfunc, backfunc; GLint ref; GLuint mask; bool operator==(const GLStencilFunc_t& src) const { return EQ(frontfunc) && EQ(backfunc) && EQ(ref) && EQ(mask); } };
+struct GLStencilOp_t { GLenum sfail; GLenum dpfail; GLenum dppass; bool operator==(const GLStencilOp_t& src) const { return EQ(sfail) && EQ(dpfail) && EQ(dppass); } };
+struct GLStencilWriteMask_t { GLint mask; bool operator==(const GLStencilWriteMask_t& src) const { return EQ(mask); } };
+
+//clearing
+struct GLClearColor_t { GLfloat r,g,b,a; bool operator==(const GLClearColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } };
+struct GLClearDepth_t { GLdouble d; bool operator==(const GLClearDepth_t& src) const { return EQ(d); } };
+struct GLClearStencil_t { GLint s; bool operator==(const GLClearStencil_t& src) const { return EQ(s); } };
+
+#undef EQ
+
+enum EGLMStateBlockType
+{
+ kGLAlphaTestEnable,
+ kGLAlphaTestFunc,
+
+ kGLCullFaceEnable,
+ kGLCullFrontFace,
+
+ kGLPolygonMode,
+
+ kGLDepthBias,
+
+ kGLScissorEnable,
+ kGLScissorBox,
+
+ kGLViewportBox,
+ kGLViewportDepthRange,
+
+ kGLClipPlaneEnable,
+ kGLClipPlaneEquation,
+
+ kGLColorMaskSingle,
+ kGLColorMaskMultiple,
+
+ kGLBlendEnable,
+ kGLBlendFactor,
+ kGLBlendEquation,
+ kGLBlendColor,
+ kGLBlendEnableSRGB,
+
+ kGLDepthTestEnable,
+ kGLDepthFunc,
+ kGLDepthMask,
+
+ kGLStencilTestEnable,
+ kGLStencilFunc,
+ kGLStencilOp,
+ kGLStencilWriteMask,
+
+ kGLClearColor,
+ kGLClearDepth,
+ kGLClearStencil,
+
+ kGLAlphaToCoverageEnable,
+
+ kGLMStateBlockLimit
+};
+
+//===========================================================================//
+
+// templated functions representing GL R/W bottlenecks
+// one set of set/get/getdefault is instantiated for each of the GL*** types above.
+
+// use these from the non array state objects
+template<typename T> void GLContextSet( T *src );
+template<typename T> void GLContextGet( T *dst );
+template<typename T> void GLContextGetDefault( T *dst );
+
+// use these from the array state objects
+template<typename T> void GLContextSetIndexed( T *src, int index );
+template<typename T> void GLContextGetIndexed( T *dst, int index );
+template<typename T> void GLContextGetDefaultIndexed( T *dst, int index );
+
+//===========================================================================//
+
+// caching state object template. One of these is instantiated in the context per unique struct type above
+template<typename T> class GLState
+{
+ public:
+
+ GLState<T>()
+ {
+ dirty = false;
+ memset( &data, 0, sizeof(data) );
+ };
+
+ // write: client src into cache
+ // common case is both false. dirty is calculated, context write is deferred.
+ void Write( T *src, bool noCompare=false, bool noDefer=false )
+ {
+ if (noCompare)
+ {
+ dirty = true;
+ }
+ else
+ {
+ // only == is implemented, so test for equal and negate
+ // note, you only set dirty if mismatch, you never clear it until flush
+ if ( !(data == *src) )
+ {
+ dirty = true;
+ }
+ }
+
+ data = *src;
+
+ if (noDefer)
+ {
+ Flush( true ); // dirty becomes false
+ }
+ };
+
+ // write cache->context if dirty or forced.
+ void Flush( bool noDefer=false )
+ {
+ if (dirty || noDefer)
+ {
+ GLContextSet( &data );
+ GLMCheckError();
+ // good place for some error checking here
+ dirty = false;
+ }
+ };
+
+ // default: write default value to cache, optionally write through
+ void Default( bool noDefer=false )
+ {
+ GLContextGetDefault( &data ); // read default values directly to our cache copy
+ dirty = true;
+ Flush(noDefer);
+ };
+
+ // read: sel = 0 for cache, 1 for context
+ void Read( T *dst, int sel )
+ {
+ if (sel==0)
+ {
+ *dst = data;
+ }
+ else
+ {
+ GLContextGet( dst );
+ GLMCheckError();
+ }
+ };
+
+ // check: verify that context equals cache, return true if mismatched or if illegal values seen
+ bool Check ( void )
+ {
+ T temp;
+ bool result;
+
+ GLContextGet( &temp );
+ GLMCheckError();
+ result = !(temp == data);
+ return result;
+ };
+
+ protected:
+ T data;
+ bool dirty;
+};
+
+// caching state object template - with multiple values behind it that are indexed
+template<typename T, int COUNT> class GLStateArray
+{
+ public:
+
+ GLStateArray<T,COUNT>()
+ {
+ memset( &dirty, 0, sizeof(dirty) );
+ memset( &data, 0, sizeof(data) );
+ };
+
+ // write: client src into cache
+ // common case is both false. dirty is calculated, context write is deferred.
+ void WriteIndex( T *src, int index, bool noCompare=false, bool noDefer=false )
+ {
+ if (noCompare)
+ {
+ dirty[index] = true;
+ }
+ else
+ {
+ // only == is implemented, so test for equal and negate
+ // note, you only set dirty if mismatch, you never clear it until flush
+ if (! (data[index] == *src) )
+ {
+ dirty[index] = true;
+ }
+ }
+
+ data[index] = *src;
+
+ if (noDefer)
+ {
+ FlushIndex( index, true ); // dirty becomes false
+ }
+ };
+
+ // write cache->context if dirty or forced.
+ void FlushIndex( int index, bool noDefer=false )
+ {
+ if (dirty[index] || noDefer)
+ {
+ GLContextSetIndexed( &data[index], index );
+ GLMCheckError();
+ dirty[index] = false;
+ }
+ };
+
+ // write all slots in the array
+ void Flush( bool noDefer=false )
+ {
+ for( int i=0; i<COUNT; i++)
+ {
+ FlushIndex( i, noDefer );
+ }
+ }
+
+ // default: write default value to cache, optionally write through
+ void DefaultIndex( int index, bool noDefer=false )
+ {
+ GLContextGetDefaultIndexed( &data[index], index ); // read default values directly to our cache copy
+ dirty[index] = true;
+ Flush(noDefer);
+ };
+
+ void Default( void )
+ {
+ for( int i=0; i<COUNT; i++)
+ {
+ DefaultIndex( i );
+ }
+ }
+
+ // read: sel = 0 for cache, 1 for context
+ void ReadIndex( T *dst, int index, int sel )
+ {
+ if (sel==0)
+ {
+ *dst = data[index];
+ }
+ else
+ {
+ GLContextGetIndexed( dst, index );
+ GLMCheckError();
+ }
+ };
+
+ // check: verify that context equals cache, return true if mismatched or if illegal values seen
+ bool CheckIndex( int index )
+ {
+ T temp;
+ bool result;
+
+ GLContextGetIndexed( &temp, index );
+ GLMCheckError();
+ result = !(temp == data[index]);
+
+ return result;
+ };
+
+ bool Check( void )
+ {
+ T temp;
+ bool result = false;
+
+ for( int i=0; i<COUNT; i++)
+ {
+ result |= CheckIndex( i );
+ }
+
+ return result;
+ };
+
+ protected:
+ T data [COUNT];
+ bool dirty [COUNT];
+};
+
+
+//===========================================================================//
+
+struct GLMTexSampler
+{
+ GLMTexSamplingParams m_samp;
+ CGLMTex *m_drawTex; // tex which must be bound at time of draw
+ CGLMTex *m_boundTex; // tex which is actually bound now (if does not match, a rebind is needed to draw)
+};
+
+#ifdef NEVER
+//===========================================================================//
+
+enum GLMVertexAttributeIndex
+{
+ kGLMGenericAttr00 = 0,
+ kGLMGenericAttr01,
+ kGLMGenericAttr02,
+ kGLMGenericAttr03,
+ kGLMGenericAttr04,
+ kGLMGenericAttr05,
+ kGLMGenericAttr06,
+ kGLMGenericAttr07,
+ kGLMGenericAttr08,
+ kGLMGenericAttr09,
+ kGLMGenericAttr10,
+ kGLMGenericAttr11,
+ kGLMGenericAttr12,
+ kGLMGenericAttr13,
+ kGLMGenericAttr14,
+ kGLMGenericAttr15,
+
+ kGLMVertexAttributeIndexMax // ideally < 32
+};
+
+struct GLMVertexAttributeDesc // all the info you need to do vertex setup for one attribute
+{
+ CGLMBuffer *m_buffer; // NULL allowed in which case m_offset is the full 32-bit pointer.. so you can draw from plain RAM if desired
+ GLuint m_datasize; // comp count of the attribute (1-4)
+ GLenum m_datatype; // data type of the attribute (GL_FLOAT, GL_UNSIGNED_BYTE, etc)
+ GLuint m_stride;
+ GLuint m_offset; // net offset to attribute 'zero' within the buffer.
+ GLboolean m_normalized; // apply to any fixed point data that needs normalizing, esp color bytes
+
+ // may need a seed value at some point to be able to disambiguate re-lifed buffers holding same pointer
+ // simpler alternative is to do shoot-down inside the vertex/index buffer free calls.
+ // I'd rather not have to have each attribute fiddling a ref count on the buffer to which it refers..
+
+#define EQ(fff) ( (src.fff) == (fff) )
+ // test in decreasing order of likelihood of difference, but do not include the buffer revision as caller is not supplying it..
+ bool operator==(const GLMVertexAttributeDesc& src) const { return EQ(m_buffer) && EQ(m_offset) && EQ(m_stride) && EQ(m_datatype) && EQ(m_normalized) && EQ(m_datasize); }
+#undef EQ
+
+ uint m_bufferRevision; // only set in GLM context's copy, to disambiguate references that are same offset / same buffer but cross an orphan event
+};
+
+// GLMContext will maintain one of these structures inside the context to represent the current state.
+// Client can supply a new one when it wants to change the setup.
+//FIXME GLMContext can do the work to migrate from old setup to new setup as efficiently as possible (but it doesn't yet)
+#endif
+
+struct GLMVertexSetup
+{
+ uint m_attrMask; // which attrs are enabled (1<<n) mask where n is a GLMVertexAttributeIndex.
+
+ GLMVertexAttributeDesc m_attrs[ kGLMVertexAttributeIndexMax ];
+
+ // copied in from dxabstract, not strictly needed for operation, helps debugging
+ unsigned char m_vtxAttribMap[16];
+
+ /* high nibble is usage per _D3DDECLUSAGE
+ typedef enum _D3DDECLUSAGE
+ {
+ D3DDECLUSAGE_POSITION = 0,
+ D3DDECLUSAGE_BLENDWEIGHT = 1,
+ D3DDECLUSAGE_BLENDINDICES = 2,
+ D3DDECLUSAGE_NORMAL = 3,
+ D3DDECLUSAGE_PSIZE = 4,
+ D3DDECLUSAGE_TEXCOORD = 5,
+ D3DDECLUSAGE_TANGENT = 6,
+ D3DDECLUSAGE_BINORMAL = 7,
+ D3DDECLUSAGE_TESSFACTOR = 8,
+ D3DDECLUSAGE_PLUGH = 9, // mystery value
+ D3DDECLUSAGE_COLOR = 10,
+ D3DDECLUSAGE_FOG = 11,
+ D3DDECLUSAGE_DEPTH = 12,
+ D3DDECLUSAGE_SAMPLE = 13,
+ } D3DDECLUSAGE;
+
+ low nibble is usageindex (i.e. POSITION0, POSITION1, etc)
+ array position is attrib number.
+ */
+};
+
+//===========================================================================//
+
+//FIXME magic numbers here
+
+#define kGLMProgramParamFloat4Limit 256
+#define kGLMProgramParamBoolLimit 16
+#define kGLMProgramParamInt4Limit 16
+
+#define kGLMVertexProgramParamFloat4Limit 256
+#define kGLMFragmentProgramParamFloat4Limit 32
+
+struct GLMProgramParamsF
+{
+ float m_values[kGLMProgramParamFloat4Limit][4]; // float4's 256 of them
+ uint m_dirtySlotCount; // index of slot past highest dirty (assume 0 for base of range)
+};
+
+struct GLMProgramParamsB
+{
+ int m_values[kGLMProgramParamBoolLimit]; // bools, 4 of them
+ uint m_dirtySlotCount;
+};
+
+struct GLMProgramParamsI
+{
+ int m_values[kGLMProgramParamInt4Limit][4]; // int4s, 16 of them
+ uint m_dirtySlotCount;
+};
+
+enum EGLMParamWriteMode
+{
+ eParamWriteAllSlots, // glUniform4fv of the maximum size (not recommended if shader is down-sizing the decl)
+ eParamWriteShaderSlots, // glUniform4fv of the active slot count ("highwater")
+ eParamWriteShaderSlotsOptional, // glUniform4fv of the active slot count ("highwater") - but only if at least one has been written - it's optional
+ eParamWriteDirtySlotRange // glUniform4fv of the 0-N range where N is highest dirty slot
+};
+
+enum EGLMAttribWriteMode
+{
+ eAttribWriteAll,
+ eAttribWriteDirty
+};
+
+//===========================================================================//
+
+#if GLMDEBUG
+enum EGLMDebugCallSite
+{
+ eBeginFrame, // inside begin frame func - frame number has been inc'd, batch number should be -1
+ eClear, // inside clear func
+ eDrawElements, // inside repeat loop, prior to draw call - batch numberhas been inc'd
+ eEndFrame, // end frame
+ ePresent // before showing pixels
+};
+
+// caller should zero one of these out and fill in the m_caller before invoking the hook
+struct GLMDebugHookInfo
+{
+ // info from the caller to the debug hook
+ EGLMDebugCallSite m_caller;
+
+
+ // state the hook uses to keep track of progress within a single run of the caller
+ int m_iteration; // which call to the hook is this. if it's zero, it precedes any action in the caller.
+
+
+ // bools used to communicate between caller and hook
+ bool m_loop; // hook tells caller to loop around again (don't exit)
+ bool m_holding; // current mood of hook, are we holding on this batch (i.e. rerun)
+
+ // specific info for a draw call
+ GLenum m_drawMode;
+ GLuint m_drawStart;
+ GLuint m_drawEnd;
+ GLsizei m_drawCount;
+ GLenum m_drawType;
+ const GLvoid *m_drawIndices;
+};
+#endif
+
+//===========================================================================//
+
+#define kGLMUserClipPlanes 2
+#define kGLMScratchFBOCount 4
+
+class GLMContext
+{
+ public:
+ // set/check current context (perq for many other calls)
+ void MakeCurrent( bool bRenderThread = false );
+ void ReleaseCurrent( bool bRenderThread = false );
+
+ // CheckCurrent has been removed (it no longer compiled). To minimize churn I'm leaving
+ // the inline NOP version.
+ // DO NOT change this to non-inlined. It's called all over the place from very hot codepaths.
+ FORCEINLINE void CheckCurrent( void ) { }
+
+ void PopulateCaps( void ); // fill out later portions of renderer info record which need context queries
+ void DumpCaps( void ); // printf all the caps info (you can call this in release too)
+ const GLMRendererInfoFields& Caps( void ); // peek at the caps record
+
+ // state cache/mirror
+ void SetDefaultStates( void );
+ void FlushStates( bool noDefer = false );
+ void VerifyStates( void );
+
+ // textures
+ // Lock and Unlock reqs go directly to the tex object
+ CGLMTex *NewTex( GLMTexLayoutKey *key, char *debugLabel=NULL );
+ void DelTex( CGLMTex *tex );
+
+ // options for Blit (replacement for ResolveTex and BlitTex)
+ // pass NULL for dstTex if you want to target GL_BACK with the blit. You get y-flip with that, don't change the dstrect yourself.
+ void Blit2( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, uint filter );
+
+ // tex blit (via FBO blit)
+ void BlitTex( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, uint filter, bool useBlitFB = true );
+
+ // MSAA resolve - we do this in GLMContext because it has to do a bunch of FBO/blit gymnastics
+ void ResolveTex( CGLMTex *tex, bool forceDirty=false );
+
+ // texture pre-load (residency forcing) - normally done one-time but you can force it
+ void PreloadTex( CGLMTex *tex, bool force=false );
+
+ // samplers
+ void SetSamplerTex( int sampler, CGLMTex *tex );
+ void SetSamplerParams( int sampler, GLMTexSamplingParams *params );
+
+ // render targets (FBO's)
+ CGLMFBO *NewFBO( void );
+ void DelFBO( CGLMFBO *fbo );
+ void SetDrawingFBO( CGLMFBO *fbo ); // as with samplers, the notion of the target FBO is latched til draw time and then checked
+
+ // programs
+ CGLMProgram *NewProgram( EGLMProgramType type, char *progString );
+ void DelProgram( CGLMProgram *prog );
+ void NullProgram( void ); // de-ac all shader state
+
+ void SetDrawingProgram( EGLMProgramType type, CGLMProgram *prog ); // set NULL for no program
+ void SetDrawingLang( EGLMProgramLang lang, bool immediate=false ); // choose ARB or GLSL. immediate=false defers lang change to top of frame
+
+ void LinkShaderPair( CGLMProgram *vp, CGLMProgram *fp ); // ensure this combo has been linked and is in the GLSL pair cache
+ void ClearShaderPairCache( void ); // call this to shoot down all the linked pairs
+ void QueryShaderPair( int index, GLMShaderPairInfo *infoOut ); // this lets you query the shader pair cache for saving its state
+
+ // buffers
+ // Lock and Unlock reqs go directly to the buffer object
+ CGLMBuffer *NewBuffer( EGLMBufferType type, uint size, uint options );
+ void DelBuffer( CGLMBuffer *buff );
+
+ void SetIndexBuffer( CGLMBuffer *buff );
+ void SetVertexAttributes( GLMVertexSetup *setup );
+ // note, no API is exposed for setting a single attribute source.
+ // come prepared with a complete block of attributes to use.
+
+ // Queries
+ CGLMQuery *NewQuery( GLMQueryParams *params );
+ void DelQuery( CGLMQuery *query );
+
+ // "slot" means a vec4-sized thing
+ // these write into .env parameter space
+ void SetProgramParametersF( EGLMProgramType type, uint baseSlot, float *slotData, uint slotCount ); // take vec4f's
+ void SetProgramParametersB( EGLMProgramType type, uint baseSlot, int *slotData, uint boolCount ); // take "BOOL" aka int
+ void SetProgramParametersI( EGLMProgramType type, uint baseSlot, int *slotData, uint slotCount ); // take int4s
+
+ // state sync
+ void FlushDrawStates( bool shadersOn=true ); // pushes all drawing state - samplers, tex, programs, etc.
+
+ // drawing
+ void DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices );
+ void CheckNative( void );
+
+ // clearing
+ void Clear( bool color, unsigned long colorValue, bool depth, float depthValue, bool stencil, unsigned int stencilValue, GLScissorBox_t *rect = NULL );
+
+ // display
+ //void SetVSyncEnable( bool vsyncOn );
+ //void SetFullScreen( bool fsOn, int screenIndex ); // will be latched for next BeginFrame
+ //void ActivateFullScreen( bool fsOn, int screenIndex ); // will be called by BeginFrame
+ bool SetDisplayParams( GLMDisplayParams *params ); // either the first time setup, or a change to new setup
+
+ void Present( CGLMTex *tex ); // somewhat hardwired for the time being
+
+ // mode switch / reset
+ void Reset( void ); // not a lot of args for now..
+
+ // writers for the state block inputs
+
+ void WriteAlphaTestEnable ( GLAlphaTestEnable_t *src );
+ void WriteAlphaTestFunc ( GLAlphaTestFunc_t *src );
+ void WriteCullFaceEnable ( GLCullFaceEnable_t *src );
+ void WriteCullFrontFace ( GLCullFrontFace_t *src );
+ void WritePolygonMode ( GLPolygonMode_t *src );
+ void WriteDepthBias ( GLDepthBias_t *src );
+ void WriteClipPlaneEnable ( GLClipPlaneEnable_t *src, int which );
+ void WriteClipPlaneEquation ( GLClipPlaneEquation_t *src, int which );
+ void WriteScissorEnable ( GLScissorEnable_t *src );
+ void WriteScissorBox ( GLScissorBox_t *src );
+ void WriteAlphaToCoverageEnable ( GLAlphaToCoverageEnable_t *src );
+ void WriteViewportBox ( GLViewportBox_t *src );
+ void WriteViewportDepthRange ( GLViewportDepthRange_t *src );
+ void WriteColorMaskSingle ( GLColorMaskSingle_t *src );
+ void WriteColorMaskMultiple ( GLColorMaskMultiple_t *src, int which );
+ void WriteBlendEnable ( GLBlendEnable_t *src );
+ void WriteBlendFactor ( GLBlendFactor_t *src );
+ void WriteBlendEquation ( GLBlendEquation_t *src );
+ void WriteBlendColor ( GLBlendColor_t *src );
+ void WriteBlendEnableSRGB ( GLBlendEnableSRGB_t *src );
+ void WriteDepthTestEnable ( GLDepthTestEnable_t *src );
+ void WriteDepthFunc ( GLDepthFunc_t *src );
+ void WriteDepthMask ( GLDepthMask_t *src );
+ void WriteStencilTestEnable ( GLStencilTestEnable_t *src );
+ void WriteStencilFunc ( GLStencilFunc_t *src );
+ void WriteStencilOp ( GLStencilOp_t *src, int which );
+ void WriteStencilWriteMask ( GLStencilWriteMask_t *src );
+ void WriteClearColor ( GLClearColor_t *src );
+ void WriteClearDepth ( GLClearDepth_t *src );
+ void WriteClearStencil ( GLClearStencil_t *src );
+
+
+ // debug stuff
+ void BeginFrame( void );
+ void EndFrame( void );
+
+ // new interactive debug stuff
+#if GLMDEBUG
+ void DebugDump( GLMDebugHookInfo *info, uint options, uint vertDumpMode );
+ void DebugHook( GLMDebugHookInfo *info );
+ void DebugPresent( void );
+ void DebugClear( void );
+#endif
+
+ FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; }
+
+ protected:
+ friend class GLMgr; // only GLMgr can make GLMContext objects
+ friend class GLMRendererInfo; // only GLMgr can make GLMContext objects
+ friend class CGLMTex; // tex needs to be able to do binds
+ friend class CGLMFBO; // fbo needs to be able to do binds
+ friend class CGLMProgram;
+ friend class CGLMShaderPair;
+ friend class CGLMShaderPairCache;
+ friend class CGLMBuffer;
+ friend class GLMTester; // tester class needs access back into GLMContext
+
+ friend class IDirect3D9;
+ friend class IDirect3DDevice9;
+
+ // methods------------------------------------------
+
+ // old GLMContext( GLint displayMask, GLint rendererID, PseudoNSGLContextPtr nsglShareCtx );
+ GLMContext( GLMDisplayParams *params );
+ ~GLMContext();
+
+ // textures
+ void SelectTMU( int tmu ); // wrapper for glActiveTexture()
+ int BindTexToTMU( CGLMTex *tex, int tmu, bool noCheck=false );
+
+ // render targets / FBO's
+ void BindFBOToCtx( CGLMFBO *fbo, GLenum bindPoint = GL_FRAMEBUFFER_EXT ); // you can also choose GL_READ_FRAMEBUFFER_EXT / GL_DRAW_FRAMEBUFFER_EXT
+
+ // programs
+ //void BindProgramToCtx( EGLMProgramType type, CGLMProgram *prog ); // will set program mode enable appropriately
+
+ // buffers
+ void BindBufferToCtx( EGLMBufferType type, CGLMBuffer *buff, bool force = false ); // does not twiddle any enables.
+
+ // debug font
+ void GenDebugFontTex( void );
+ void DrawDebugText( float x, float y, float z, float drawCharWidth, float drawCharHeight, char *string );
+
+ // members------------------------------------------
+
+ // context
+ DWORD m_nCurOwnerThreadId;
+
+ GLMRendererInfoFields m_caps;
+
+ bool m_displayParamsValid; // is there a param block copied in yet
+ GLMDisplayParams m_displayParams; // last known display config, either via constructor, or by SetDisplayParams...
+
+#if defined(USE_SDL)
+ int m_pixelFormatAttribs[100]; // more than enough
+ void * m_ctx;
+#endif
+
+ // texture form table
+ CGLMTexLayoutTable *m_texLayoutTable;
+
+ // context state mirrors
+
+ GLState<GLAlphaTestEnable_t> m_AlphaTestEnable;
+
+ GLState<GLAlphaTestFunc_t> m_AlphaTestFunc;
+
+ GLState<GLCullFaceEnable_t> m_CullFaceEnable;
+ GLState<GLCullFrontFace_t> m_CullFrontFace;
+ GLState<GLPolygonMode_t> m_PolygonMode;
+
+ GLState<GLDepthBias_t> m_DepthBias;
+
+ GLStateArray<GLClipPlaneEnable_t,kGLMUserClipPlanes> m_ClipPlaneEnable;
+ GLStateArray<GLClipPlaneEquation_t,kGLMUserClipPlanes> m_ClipPlaneEquation; // dxabstract puts them directly into param slot 253(0) and 254(1)
+
+ GLState<GLScissorEnable_t> m_ScissorEnable;
+ GLState<GLScissorBox_t> m_ScissorBox;
+
+ GLState<GLAlphaToCoverageEnable_t> m_AlphaToCoverageEnable;
+
+ GLState<GLViewportBox_t> m_ViewportBox;
+ GLState<GLViewportDepthRange_t> m_ViewportDepthRange;
+
+ GLState<GLColorMaskSingle_t> m_ColorMaskSingle;
+ GLStateArray<GLColorMaskMultiple_t,8> m_ColorMaskMultiple; // need an official constant for the color buffers limit
+
+ GLState<GLBlendEnable_t> m_BlendEnable;
+ GLState<GLBlendFactor_t> m_BlendFactor;
+ GLState<GLBlendEquation_t> m_BlendEquation;
+ GLState<GLBlendColor_t> m_BlendColor;
+ GLState<GLBlendEnableSRGB_t> m_BlendEnableSRGB; // write to this one to transmit intent to write SRGB encoded pixels to drawing FB
+ bool m_FakeBlendEnableSRGB; // writes to above will be shunted here if fake SRGB is in effect.
+
+ GLState<GLDepthTestEnable_t> m_DepthTestEnable;
+ GLState<GLDepthFunc_t> m_DepthFunc;
+ GLState<GLDepthMask_t> m_DepthMask;
+
+ GLState<GLStencilTestEnable_t> m_StencilTestEnable; // global stencil test enable
+ GLState<GLStencilFunc_t> m_StencilFunc; // holds front and back stencil funcs
+ GLStateArray<GLStencilOp_t,2> m_StencilOp; // indexed: 0=front 1=back
+ GLState<GLStencilWriteMask_t> m_StencilWriteMask;
+
+ GLState<GLClearColor_t> m_ClearColor;
+ GLState<GLClearDepth_t> m_ClearDepth;
+ GLState<GLClearStencil_t> m_ClearStencil;
+
+ // texture bindings and sampler setup
+ int m_activeTexture; // mirror for glActiveTexture
+ GLMTexSampler m_samplers[GLM_SAMPLER_COUNT];
+
+ // texture lock tracking - CGLMTex objects share usage of this
+ CUtlVector< GLMTexLockDesc > m_texLocks;
+
+ // render target binding - check before draw
+ // similar to tex sampler mechanism, we track "bound" from "chosen for drawing" separately,
+ // so binding for creation/setup need not disrupt any notion of what will be used at draw time
+
+ CGLMFBO *m_boundDrawFBO; // FBO on GL_DRAW_FRAMEBUFFER bind point
+ CGLMFBO *m_boundReadFBO; // FBO on GL_READ_FRAMEBUFFER bind point
+ // ^ both are set if you bind to GL_FRAMEBUFFER_EXT
+
+ CGLMFBO *m_drawingFBO; // what FBO should be bound at draw time (to both read/draw bp's).
+
+ CGLMFBO *m_blitReadFBO;
+ CGLMFBO *m_blitDrawFBO; // scratch FBO's for framebuffer blit
+
+ CGLMFBO *m_scratchFBO[ kGLMScratchFBOCount ]; // general purpose FBO's for internal use
+
+ CUtlVector< CGLMFBO* > m_fboTable; // each live FBO goes in the table
+
+ // program bindings
+ EGLMProgramLang m_drawingLangAtFrameStart; // selector for start of frame (spills into m_drawingLang)
+ EGLMProgramLang m_drawingLang; // selector for which language we desire to draw with on the next batch
+ CGLMProgram *m_drawingProgram[ kGLMNumProgramTypes ];
+
+ GLMProgramParamsF m_programParamsF[ kGLMNumProgramTypes ];
+ GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used
+ GLMProgramParamsI m_programParamsI[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used
+ EGLMParamWriteMode m_paramWriteMode;
+
+ CGLMProgram *m_nullFragmentProgram; // write opaque black. Activate when caller asks for null FP
+
+ CGLMProgram *m_preloadTexVertexProgram; // programs to help preload textures (dummies)
+ CGLMProgram *m_preload2DTexFragmentProgram;
+ CGLMProgram *m_preload3DTexFragmentProgram;
+ CGLMProgram *m_preloadCubeTexFragmentProgram;
+
+ CGLMProgram *m_boundProgram[ kGLMNumProgramTypes ];
+
+ CGLMShaderPairCache *m_pairCache; // GLSL only
+ CGLMShaderPair *m_boundPair; // GLSL only
+ uint m_boundPairRevision; // GLSL only
+ GLhandleARB m_boundPairProgram; // GLSL only
+
+ // buffer bindings
+ CGLMBuffer *m_lastKnownBufferBinds[ kGLMNumBufferTypes ]; // tracked per bind point for dupe-bind-absorb
+ GLMVertexAttributeDesc m_lastKnownVertexAttribs[ kGLMVertexAttributeIndexMax ]; // tracked per attrib for dupe-set-absorb
+ uint m_lastKnownVertexAttribMask; // tracked for dupe-enable-absorb
+
+ CGLMBuffer *m_drawIndexBuffer; // ... ? do we need dupe tracking for index buffer setup? ?
+
+ GLMVertexSetup m_drawVertexSetup;
+
+ EGLMAttribWriteMode m_attribWriteMode;
+
+ bool m_slowCheckEnable; // turn this on or no native checking is done ("-glmassertslow" or "-glmsspewslow")
+ bool m_slowAssertEnable; // turn this on to assert on a non-native batch "-glmassertslow"
+ bool m_slowSpewEnable; // turn this on to log non-native batches to stdout "-glmspewslow"
+
+ // debug font texture
+ CGLMTex *m_debugFontTex; // might be NULL unless you call GenDebugFontTex
+ CGLMBuffer *m_debugFontIndices; // up to 1024 indices (256 chars times 4)
+ CGLMBuffer *m_debugFontVertices; // up to 1024 verts
+
+ // batch/frame debugging support
+ int m_debugFrameIndex; // init to -1. Increment at BeginFrame
+ int m_debugBatchIndex; // init to -1. Increment at any draw call
+
+#if GLMDEBUG
+ // interactive (DebugHook) debug support
+
+ // using these you can implement frame advance, batch single step, and batch rewind (let it run til next frame and hold on prev batch #)
+ int m_holdFrameBegin; // -1 if no hold req'd, otherwise # of frame to hold at (at beginframe time)
+ int m_holdFrameEnd; // -1 if no hold req'd, otherwise # of frame to hold at (at endframe time)
+
+ int m_holdBatch,m_holdBatchFrame; // -1 if no hold, else # of batch&frame to hold at (both must be set)
+ // these can be expired/cleared to -1 if the frame passes without a hit
+ // may be desirable to re-pause in that event, as user was expecting a hold to occur
+
+ bool m_debugDelayEnable; // allow sleep delay
+ uint m_debugDelay; // sleep time per hook call in microseconds (for usleep())
+
+ // pre-draw global toggles / options
+ bool m_autoClearColor,m_autoClearDepth,m_autoClearStencil;
+ float m_autoClearColorValues[4];
+
+ // debug knobs
+ int m_selKnobIndex;
+ float m_selKnobMinValue,m_selKnobMaxValue,m_selKnobIncrement;
+#endif
+
+};
+
+struct GLMTestParams
+{
+ GLMContext *m_ctx;
+ int *m_testList; // -1 termed
+
+ bool m_glErrToDebugger;
+ bool m_glErrToConsole;
+
+ bool m_intlErrToDebugger;
+ bool m_intlErrToConsole;
+
+ int m_frameCount; // how many frames to test.
+};
+
+class GLMTester
+{
+ public:
+
+ GLMTester(GLMTestParams *params);
+ ~GLMTester();
+
+
+ // optionally callable by test routines to get basic drawables wired up
+ void StdSetup( void );
+ void StdCleanup( void );
+
+ // callable by test routines to clear the frame or present it
+ void Clear( void );
+ void Present( int seed );
+
+ // error reporting
+ void CheckGLError( char *comment ); // obey m_params setting for console / debugger response
+ void InternalError( int errcode, char *comment ); // if errcode!=0, obey m_params setting for console / debugger response
+
+ void RunTests();
+
+ void RunOneTest( int testindex );
+
+ // test routines themselves
+ void Test0();
+ void Test1();
+ void Test2();
+ void Test3();
+
+ GLMTestParams m_params; // copy of caller's params, do not mutate...
+
+ // std-setup stuff
+ int m_drawWidth, m_drawHeight;
+ CGLMFBO *m_drawFBO;
+ CGLMTex *m_drawColorTex;
+ CGLMTex *m_drawDepthTex;
+};
+
+class CShowPixelsParams
+{
+public:
+ GLuint m_srcTexName;
+ int m_width,m_height;
+ bool m_vsyncEnable;
+ bool m_fsEnable; // want receiving view to be full screen. for now, just target the main screen. extend later.
+ bool m_useBlit; // use FBO blit - sending context says it is available.
+ bool m_noBlit; // the back buffer has already been populated by the caller (perhaps via direct MSAA resolve from multisampled RT tex)
+ bool m_onlySyncView; // react to full/windowed state change only, do not present bits
+};
+
+
+#define kMaxCrawlFrames 100
+#define kMaxCrawlText (kMaxCrawlFrames * 256)
+class CStackCrawlParams
+{
+ public:
+ uint m_frameLimit; // input: max frames to retrieve
+ uint m_frameCount; // output: frames found
+ void *m_crawl[kMaxCrawlFrames]; // call site addresses
+ char *m_crawlNames[kMaxCrawlFrames]; // pointers into text following, one per decoded name
+ char m_crawlText[kMaxCrawlText];
+};
+
+#endif
diff --git a/mp/src/public/togl/osx/glmgrbasics.h b/mp/src/public/togl/osx/glmgrbasics.h new file mode 100644 index 00000000..559bc10f --- /dev/null +++ b/mp/src/public/togl/osx/glmgrbasics.h @@ -0,0 +1,299 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgrbasics.h
+// types, common headers, forward declarations, utilities
+//
+//===============================================================================
+
+#ifndef GLMBASICS_H
+#define GLMBASICS_H
+
+#pragma once
+
+#ifdef OSX
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/CGLTypes.h>
+#include <OpenGL/CGLRenderers.h>
+#include <OpenGL/CGLCurrent.h>
+#include <OpenGL/CGLProfiler.h>
+//#include <ApplicationServices/ApplicationServices.h>
+#elif defined(LINUX)
+#include <GL/gl.h>
+#include <GL/glext.h>
+#else
+#error
+#endif
+
+#include "tier0/platform.h"
+
+#include "bitmap/imageformat.h"
+#include "bitvec.h"
+#include "tier1/checksum_md5.h"
+#include "tier1/utlvector.h"
+#include "tier1/convar.h"
+
+#include <sys/stat.h>
+
+#include "dxabstract_types.h"
+
+// types
+struct GLMRect;
+typedef void *PseudoGLContextPtr;
+
+
+ // 3-d integer box (used for texture lock/unlock etc)
+struct GLMRegion
+{
+ int xmin,xmax;
+ int ymin,ymax;
+ int zmin,zmax;
+};
+
+struct GLMRect // follows GL convention - if coming from the D3D rect you will need to fiddle the Y's
+{
+ int xmin; // left
+ int ymin; // bottom
+ int xmax; // right
+ int ymax; // top
+};
+
+// macros
+
+//#define GLMassert(x) assert(x)
+
+// forward decls
+class GLMgr; // singleton
+class GLMContext; // GL context
+class CGLMContextTester; // testing class
+class CGLMTex;
+class CGLMFBO;
+class CGLMProgram;
+class CGLMBuffer;
+
+
+// utilities
+
+typedef enum
+{
+ // D3D codes
+ eD3D_DEVTYPE,
+ eD3D_FORMAT,
+ eD3D_RTYPE,
+ eD3D_USAGE,
+ eD3D_RSTATE, // render state
+ eD3D_SIO, // D3D shader bytecode
+ eD3D_VTXDECLUSAGE,
+
+ // CGL codes
+ eCGL_RENDID,
+
+ // OpenGL error codes
+ eGL_ERROR,
+
+ // OpenGL enums
+ eGL_ENUM,
+ eGL_RENDERER
+
+} GLMThing_t;
+
+const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const
+const char* GLMDecodeMask( GLMThing_t type, unsigned long value ); // decode a bitmask
+
+void GLMStop( void ); // aka Debugger()
+void GLMCheckError( bool noStop = false, bool noLog= false );
+void GLMEnableTrace( bool on );
+
+// expose these in release now
+// Mimic PIX events so we can decorate debug spew
+void GLMBeginPIXEvent( const char *str );
+void GLMEndPIXEvent( void );
+
+//===============================================================================
+// knob twiddling
+float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value
+float GLMKnobToggle( char *knobname );
+
+//===============================================================================
+// other stuff
+
+// helpers for CGLSetOption - no op if no profiler
+void GLMProfilerClearTrace( void );
+void GLMProfilerEnableTrace( bool enable );
+
+// helpers for CGLSetParameter - no op if no profiler
+void GLMProfilerDumpState( void );
+
+
+//===============================================================================
+// classes
+
+// helper class making function tracking easier to wire up
+#if GLMDEBUG
+class GLMFuncLogger
+{
+ public:
+
+ // simple function log
+ GLMFuncLogger( const char *funcName )
+ {
+ m_funcName = funcName;
+ m_earlyOut = false;
+
+ GLMPrintf( ">%s", m_funcName );
+ };
+
+ // more advanced version lets you pass args (i.e. called parameters or anything else of interest)
+ // no macro for this one, since no easy way to pass through the args as well as the funcname
+ GLMFuncLogger( const char *funcName, char *fmt, ... )
+ {
+ m_funcName = funcName;
+ m_earlyOut = false;
+
+ // this acts like GLMPrintf here
+ // all the indent policy is down in GLMPrintfVA
+ // which means we need to inject a ">" at the front of the format string to make this work... sigh.
+
+ char modifiedFmt[2000];
+ modifiedFmt[0] = '>';
+ strcpy( modifiedFmt+1, fmt );
+
+ va_list vargs;
+ va_start(vargs, fmt);
+ GLMPrintfVA( modifiedFmt, vargs );
+ va_end( vargs );
+ }
+
+ ~GLMFuncLogger( )
+ {
+ if (m_earlyOut)
+ {
+ GLMPrintf( "<%s (early out)", m_funcName );
+ }
+ else
+ {
+ GLMPrintf( "<%s", m_funcName );
+ }
+ };
+
+ void EarlyOut( void )
+ {
+ m_earlyOut = true;
+ };
+
+ const char *m_funcName; // set at construction time
+ bool m_earlyOut;
+};
+
+// handy macro to go with the function tracking class
+#define GLM_FUNC GLMFuncLogger _logger_ ( __FUNCTION__ )
+#else
+#define GLM_FUNC
+#endif
+
+
+// class to keep an in-memory mirror of a file which may be getting edited during run
+class CGLMFileMirror
+{
+public:
+ CGLMFileMirror( char *fullpath ); // just associates mirror with file. if file exists it will be read.
+ //if non existent it will be created with size zero
+ ~CGLMFileMirror( );
+
+ bool HasData( void ); // see if data avail
+ void GetData( char **dataPtr, uint *dataSizePtr ); // read it out
+ void SetData( char *data, uint dataSize ); // put data in (and write it to disk)
+ bool PollForChanges( void ); // check disk copy. If different, read it back in and return true.
+
+ void UpdateStatInfo( void ); // make sure stat info is current for our file
+ void ReadFile( void );
+ void WriteFile( void );
+
+ void OpenInEditor( bool foreground=false ); // pass TRUE if you would like the editor to pop to foreground
+
+ /// how about a "wait for change" method..
+
+ char *m_path; // fullpath to file
+ bool m_exists;
+ struct stat m_stat; // stat results for the file (last time checked)
+
+ char *m_data; // content of file
+ uint m_size; // length of content
+
+};
+
+// class based on the file mirror, that makes it easy to edit them outside the app.
+
+// it receives an initial block of text from the engine, and hashes it. ("orig")
+// it munges it by duplicating all the text after the "!!" line, and appending it in commented form. ("munged")
+// a mirror file is activated, using a filename based on the hash from the orig text.
+// if there is already content on disk matching that filename, use that content *unless* the 'blitz' parameter is set.
+// (i.e. engine is instructing this subsystem to wipe out any old/modified variants of the text)
+
+
+class CGLMEditableTextItem
+{
+public:
+ CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix = NULL ); // create a text blob from text source, optional filename suffix
+ ~CGLMEditableTextItem( );
+
+ bool HasData( void );
+ bool PollForChanges( void ); // return true if stale i.e. you need to get a new edition
+ void GetCurrentText( char **textOut, uint *sizeOut ); // query for read access to the active blob (could be the original, could be external edited copy)
+ void OpenInEditor( bool foreground=false ); // call user attention to this text
+
+ // internal methods
+ void GenHashOfOrigText( void );
+ void GenBaseNameAndFullPath( char *prefix, char *suffix );
+ void GenMungedText( bool fromMirror );
+
+ // members
+ // orig
+ uint m_origSize;
+ char *m_origText; // what was submitted
+ unsigned char m_origDigest[MD5_DIGEST_LENGTH]; // digest of what was submitted
+
+ // munged
+ uint m_mungedSize;
+ char *m_mungedText; // re-processed edition, initial content submission to the file mirror
+
+ // mirror
+ char *m_mirrorBaseName; // generated from the hash of the orig text, plus the label / prefix
+ char *m_mirrorFullPath; // base name
+ CGLMFileMirror *m_mirror; // file mirror itself. holds "official" copy for GetCurrentText to return.
+};
+
+
+// debug font
+extern unsigned char g_glmDebugFontMap[16384];
+
+// class for cracking multi-part text blobs
+// sections are demarcated by beginning-of-line markers submitted in a table by the caller
+
+struct GLMTextSection
+{
+ int m_markerIndex; // based on table of markers passed in to constructor
+ uint m_textOffset; // where is the text - offset
+ int m_textLength; // how big is the section
+};
+
+class CGLMTextSectioner
+{
+public:
+ CGLMTextSectioner( char *text, int textSize, char **markers ); // constructor finds all the sections
+ ~CGLMTextSectioner( );
+
+ int Count( void ); // how many sections found
+ void GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut );
+ // find section, size, what marker
+ // note that more than one section can be marked similarly.
+ // so policy isn't made here, you walk the sections and decide what to do if there are dupes.
+
+ //members
+
+ //section table
+ CUtlVector< GLMTextSection > m_sectionTable;
+};
+
+#endif
diff --git a/mp/src/public/togl/osx/glmgrext.h b/mp/src/public/togl/osx/glmgrext.h new file mode 100644 index 00000000..1fc4edce --- /dev/null +++ b/mp/src/public/togl/osx/glmgrext.h @@ -0,0 +1,93 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// glmgrext.h
+// helper file for extension testing and runtime importing of entry points
+//
+//===============================================================================
+
+#pragma once
+
+#ifdef OSX
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#elif defined(LINUX)
+#include <GL/gl.h>
+#include <GL/glext.h>
+#else
+#error
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+ #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+ #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef ARB_texture_rg
+ #define GL_COMPRESSED_RED 0x8225
+ #define GL_COMPRESSED_RG 0x8226
+ #define GL_RG 0x8227
+ #define GL_RG_INTEGER 0x8228
+ #define GL_R8 0x8229
+ #define GL_R16 0x822A
+ #define GL_RG8 0x822B
+ #define GL_RG16 0x822C
+ #define GL_R16F 0x822D
+ #define GL_R32F 0x822E
+ #define GL_RG16F 0x822F
+ #define GL_RG32F 0x8230
+ #define GL_R8I 0x8231
+ #define GL_R8UI 0x8232
+ #define GL_R16I 0x8233
+ #define GL_R16UI 0x8234
+ #define GL_R32I 0x8235
+ #define GL_R32UI 0x8236
+ #define GL_RG8I 0x8237
+ #define GL_RG8UI 0x8238
+ #define GL_RG16I 0x8239
+ #define GL_RG16UI 0x823A
+ #define GL_RG32I 0x823B
+ #define GL_RG32UI 0x823C
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+ #define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#endif
+
+// unpublished extension enums (thus the "X")
+
+// from EXT_framebuffer_multisample_blit_scaled..
+#define XGL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
+#define XGL_SCALED_RESOLVE_NICEST_EXT 0x90BB
+
+#ifndef GL_TEXTURE_MINIMIZE_STORAGE_APPLE
+#define GL_TEXTURE_MINIMIZE_STORAGE_APPLE 0x85B6
+#endif
+
+#ifndef GL_ALL_COMPLETED_NV
+#define GL_ALL_COMPLETED_NV 0x84F2
+#endif
+
+#ifndef GL_MAP_READ_BIT
+#define GL_MAP_READ_BIT 0x0001
+#endif
+
+#ifndef GL_MAP_WRITE_BIT
+#define GL_MAP_WRITE_BIT 0x0002
+#endif
+
+#ifndef GL_MAP_INVALIDATE_RANGE_BIT
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#endif
+
+#ifndef GL_MAP_INVALIDATE_BUFFER_BIT
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#endif
+
+#ifndef GL_MAP_FLUSH_EXPLICIT_BIT
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#endif
+
+#ifndef GL_MAP_UNSYNCHRONIZED_BIT
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#endif
+
diff --git a/mp/src/public/togl/rendermechanism.h b/mp/src/public/togl/rendermechanism.h new file mode 100644 index 00000000..b409c4ac --- /dev/null +++ b/mp/src/public/togl/rendermechanism.h @@ -0,0 +1,70 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef RENDERMECHANISM_H
+#define RENDERMECHANISM_H
+
+#if defined(DX_TO_GL_ABSTRACTION)
+
+#undef PROTECTED_THINGS_ENABLE
+
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include "tier0/basetypes.h"
+#include "tier0/platform.h"
+
+#if defined(LINUX) || defined(_WIN32)
+
+#include "togl/linuxwin/glmdebug.h"
+#include "togl/linuxwin/glbase.h"
+#include "togl/linuxwin/glentrypoints.h"
+#include "togl/linuxwin/glmdisplay.h"
+#include "togl/linuxwin/glmdisplaydb.h"
+#include "togl/linuxwin/glmgrbasics.h"
+#include "togl/linuxwin/glmgrext.h"
+#include "togl/linuxwin/cglmbuffer.h"
+#include "togl/linuxwin/cglmtex.h"
+#include "togl/linuxwin/cglmfbo.h"
+#include "togl/linuxwin/cglmprogram.h"
+#include "togl/linuxwin/cglmquery.h"
+#include "togl/linuxwin/glmgr.h"
+#include "togl/linuxwin/dxabstract_types.h"
+#include "togl/linuxwin/dxabstract.h"
+
+#elif defined(OSX)
+#include "togl/osx/glmdebug.h"
+//#include "togl/osx/glbase.h"
+#include "togl/osx/glentrypoints.h"
+#include "togl/osx/glmdisplay.h"
+#include "togl/osx/glmdisplaydb.h"
+#include "togl/osx/glmgrbasics.h"
+#include "togl/osx/glmgrext.h"
+#include "togl/osx/cglmbuffer.h"
+#include "togl/osx/cglmtex.h"
+#include "togl/osx/cglmfbo.h"
+#include "togl/osx/cglmprogram.h"
+#include "togl/osx/cglmquery.h"
+#include "togl/osx/glmgr.h"
+#include "togl/osx/dxabstract_types.h"
+#include "togl/osx/dxabstract.h"
+
+#endif
+
+#else
+ //USE_ACTUAL_DX
+ #ifdef WIN32
+ #ifdef _X360
+ #include "d3d9.h"
+ #include "d3dx9.h"
+ #else
+ #include <windows.h>
+ #include "../../dx9sdk/include/d3d9.h"
+ #include "../../dx9sdk/include/d3dx9.h"
+ #endif
+ typedef HWND VD3DHWND;
+ #endif
+
+ #define GLMPRINTF(args)
+ #define GLMPRINTSTR(args)
+ #define GLMPRINTTEXT(args)
+#endif // defined(DX_TO_GL_ABSTRACTION)
+
+#endif // RENDERMECHANISM_H
diff --git a/mp/src/public/vgui/IVGui.h b/mp/src/public/vgui/IVGui.h index 06a3ec8c..e512538a 100644 --- a/mp/src/public/vgui/IVGui.h +++ b/mp/src/public/vgui/IVGui.h @@ -95,6 +95,10 @@ public: // data accessor for above
virtual bool GetShouldVGuiControlSleep() = 0;
+
+ // enables VR mode
+ virtual void SetVRMode( bool bVRMode ) = 0;
+ virtual bool GetVRMode() = 0;
};
#define VGUI_IVGUI_INTERFACE_VERSION "VGUI_ivgui008"
diff --git a/mp/src/thirdparty/protobuf-2.3.0/install-sh b/mp/src/thirdparty/protobuf-2.3.0/install-sh index 97a459c7..a5897de6 100644 --- a/mp/src/thirdparty/protobuf-2.3.0/install-sh +++ b/mp/src/thirdparty/protobuf-2.3.0/install-sh @@ -1,519 +1,519 @@ -#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2006-12-25.00
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-
-nl='
-'
-IFS=" "" $nl"
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit=${DOITPROG-}
-if test -z "$doit"; then
- doit_exec=exec
-else
- doit_exec=$doit
-fi
-
-# Put in absolute file names if you don't have them in your path;
-# or use environment vars.
-
-chgrpprog=${CHGRPPROG-chgrp}
-chmodprog=${CHMODPROG-chmod}
-chownprog=${CHOWNPROG-chown}
-cmpprog=${CMPPROG-cmp}
-cpprog=${CPPROG-cp}
-mkdirprog=${MKDIRPROG-mkdir}
-mvprog=${MVPROG-mv}
-rmprog=${RMPROG-rm}
-stripprog=${STRIPPROG-strip}
-
-posix_glob='?'
-initialize_posix_glob='
- test "$posix_glob" != "?" || {
- if (set -f) 2>/dev/null; then
- posix_glob=
- else
- posix_glob=:
- fi
- }
-'
-
-posix_mkdir=
-
-# Desired mode of installed file.
-mode=0755
-
-chgrpcmd=
-chmodcmd=$chmodprog
-chowncmd=
-mvcmd=$mvprog
-rmcmd="$rmprog -f"
-stripcmd=
-
-src=
-dst=
-dir_arg=
-dst_arg=
-
-copy_on_change=false
-no_target_directory=
-
-usage="\
-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
- --help display this help and exit.
- --version display version info and exit.
-
- -c (ignored)
- -C install only if different (preserve the last data modification time)
- -d create directories instead of installing files.
- -g GROUP $chgrpprog installed files to GROUP.
- -m MODE $chmodprog installed files to MODE.
- -o USER $chownprog installed files to USER.
- -s $stripprog installed files.
- -t DIRECTORY install into DIRECTORY.
- -T report an error if DSTFILE is a directory.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
- RMPROG STRIPPROG
-"
-
-while test $# -ne 0; do
- case $1 in
- -c) ;;
-
- -C) copy_on_change=true;;
-
- -d) dir_arg=true;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) mode=$2
- case $mode in
- *' '* | *' '* | *'
-'* | *'*'* | *'?'* | *'['*)
- echo "$0: invalid mode: $mode" >&2
- exit 1;;
- esac
- shift;;
-
- -o) chowncmd="$chownprog $2"
- shift;;
-
- -s) stripcmd=$stripprog;;
-
- -t) dst_arg=$2
- shift;;
-
- -T) no_target_directory=true;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- --) shift
- break;;
-
- -*) echo "$0: invalid option: $1" >&2
- exit 1;;
-
- *) break;;
- esac
- shift
-done
-
-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
- # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dst_arg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dst_arg"
- shift # fnord
- fi
- shift # arg
- dst_arg=$arg
- done
-fi
-
-if test $# -eq 0; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-if test -z "$dir_arg"; then
- trap '(exit $?); exit' 1 2 13 15
-
- # Set umask so as not to create temps with too-generous modes.
- # However, 'strip' requires both read and write access to temps.
- case $mode in
- # Optimize common cases.
- *644) cp_umask=133;;
- *755) cp_umask=22;;
-
- *[0-7])
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw='% 200'
- fi
- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
- *)
- if test -z "$stripcmd"; then
- u_plus_rw=
- else
- u_plus_rw=,u+rw
- fi
- cp_umask=$mode$u_plus_rw;;
- esac
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- dstdir=$dst
- test -d "$dstdir"
- dstdir_status=$?
- else
-
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dst_arg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dst_arg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dst_arg: Is a directory" >&2
- exit 1
- fi
- dstdir=$dst
- dst=$dstdir/`basename "$src"`
- dstdir_status=0
- else
- # Prefer dirname, but fall back on a substitute if dirname fails.
- dstdir=`
- (dirname "$dst") 2>/dev/null ||
- expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$dst" : 'X\(//\)[^/]' \| \
- X"$dst" : 'X\(//\)$' \| \
- X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
- echo X"$dst" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
- s//\1/
- q
- }
- /^X\(\/\/\)[^/].*/{
- s//\1/
- q
- }
- /^X\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'
- `
-
- test -d "$dstdir"
- dstdir_status=$?
- fi
- fi
-
- obsolete_mkdir_used=false
-
- if test $dstdir_status != 0; then
- case $posix_mkdir in
- '')
- # Create intermediate dirs using mode 755 as modified by the umask.
- # This is like FreeBSD 'install' as of 1997-10-28.
- umask=`umask`
- case $stripcmd.$umask in
- # Optimize common cases.
- *[2367][2367]) mkdir_umask=$umask;;
- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
- *[0-7])
- mkdir_umask=`expr $umask + 22 \
- - $umask % 100 % 40 + $umask % 20 \
- - $umask % 10 % 4 + $umask % 2
- `;;
- *) mkdir_umask=$umask,go-w;;
- esac
-
- # With -d, create the new directory with the user-specified mode.
- # Otherwise, rely on $mkdir_umask.
- if test -n "$dir_arg"; then
- mkdir_mode=-m$mode
- else
- mkdir_mode=
- fi
-
- posix_mkdir=false
- case $umask in
- *[123567][0-7][0-7])
- # POSIX mkdir -p sets u+wx bits regardless of umask, which
- # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
- ;;
- *)
- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
- if (umask $mkdir_umask &&
- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
- then
- if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
- # other-writeable bit of parent directory when it shouldn't.
- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
- ls_ld_tmpdir=`ls -ld "$tmpdir"`
- case $ls_ld_tmpdir in
- d????-?r-*) different_mode=700;;
- d????-?--*) different_mode=755;;
- *) false;;
- esac &&
- $mkdirprog -m$different_mode -p -- "$tmpdir" && {
- ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
- }
- }
- then posix_mkdir=:
- fi
- rmdir "$tmpdir/d" "$tmpdir"
- else
- # Remove any dirs left behind by ancient mkdir implementations.
- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
- fi
- trap '' 0;;
- esac;;
- esac
-
- if
- $posix_mkdir && (
- umask $mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
- )
- then :
- else
-
- # The umask is ridiculous, or mkdir does not conform to POSIX,
- # or it failed possibly due to a race condition. Create the
- # directory the slow way, step by step, checking for races as we go.
-
- case $dstdir in
- /*) prefix='/';;
- -*) prefix='./';;
- *) prefix='';;
- esac
-
- eval "$initialize_posix_glob"
-
- oIFS=$IFS
- IFS=/
- $posix_glob set -f
- set fnord $dstdir
- shift
- $posix_glob set +f
- IFS=$oIFS
-
- prefixes=
-
- for d
- do
- test -z "$d" && continue
-
- prefix=$prefix$d
- if test -d "$prefix"; then
- prefixes=
- else
- if $posix_mkdir; then
- (umask=$mkdir_umask &&
- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
- # Don't fail if two instances are running concurrently.
- test -d "$prefix" || exit 1
- else
- case $prefix in
- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
- *) qprefix=$prefix;;
- esac
- prefixes="$prefixes '$qprefix'"
- fi
- fi
- prefix=$prefix/
- done
-
- if test -n "$prefixes"; then
- # Don't fail if two instances are running concurrently.
- (umask $mkdir_umask &&
- eval "\$doit_exec \$mkdirprog $prefixes") ||
- test -d "$dstdir" || exit 1
- obsolete_mkdir_used=true
- fi
- fi
- fi
-
- if test -n "$dir_arg"; then
- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
- else
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
-
- # Copy the file name to the temp name.
- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
- # If -C, don't bother to copy if it wouldn't change the file.
- if $copy_on_change &&
- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
- eval "$initialize_posix_glob" &&
- $posix_glob set -f &&
- set X $old && old=:$2:$4:$5:$6 &&
- set X $new && new=:$2:$4:$5:$6 &&
- $posix_glob set +f &&
-
- test "$old" = "$new" &&
- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
- then
- rm -f "$dsttmp"
- else
- # Rename the file to the real destination.
- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
-
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
- {
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- test ! -f "$dst" ||
- $doit $rmcmd -f "$dst" 2>/dev/null ||
- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
- } ||
- { echo "$0: cannot unlink or rename $dst" >&2
- (exit 1); exit 1
- }
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dst"
- }
- fi || exit 1
-
- trap '' 0
- fi
-done
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
+#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/mp/src/tier1/lzmaDecoder.cpp b/mp/src/tier1/lzmaDecoder.cpp new file mode 100644 index 00000000..1d7b24a8 --- /dev/null +++ b/mp/src/tier1/lzmaDecoder.cpp @@ -0,0 +1,764 @@ +//
+// LZMA Codec.
+//
+// LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+// http://www.7-zip.org/
+//
+// Modified to use Source platform utilities and memory allocation overrides.
+//=====================================================================================//
+
+#include "tier0/platform.h"
+#include "tier0/dbg.h"
+#include "tier1/lzmaDecoder.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif
+
+/* #define _LZMA_SYSTEM_SIZE_T */
+/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_SYSTEM_SIZE_T
+#include <stddef.h>
+typedef size_t SizeT;
+#else
+typedef UInt32 SizeT;
+#endif
+#endif
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+#define _LZMA_PROB32
+/* It can increase speed on some 32-bit CPUs,
+but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+ int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+ int lc;
+ int lp;
+ int pb;
+#ifdef _LZMA_OUT_READ
+ UInt32 DictionarySize;
+#endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+ CLzmaProperties Properties;
+ CProb *Probs;
+
+#ifdef _LZMA_IN_CB
+ const unsigned char *Buffer;
+ const unsigned char *BufferLim;
+#endif
+
+#ifdef _LZMA_OUT_READ
+ unsigned char *Dictionary;
+ UInt32 Range;
+ UInt32 Code;
+ UInt32 DictionaryPos;
+ UInt32 GlobalPos;
+ UInt32 DistanceLimit;
+ UInt32 Reps[4];
+ int State;
+ int RemainLen;
+ unsigned char TempDictionary[4];
+#endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+#ifdef _LZMA_IN_CB
+ ILzmaInCallback *inCallback,
+#else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+#endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+ BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+{ UpdateBit0(p); mi <<= 1; A0; } else \
+{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
+
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+{ int i = numLevels; res = 1; \
+ do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+ res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+ unsigned char prop0;
+ if (size < LZMA_PROPERTIES_SIZE)
+ return LZMA_RESULT_DATA_ERROR;
+ prop0 = propsData[0];
+ if (prop0 >= (9 * 5 * 5))
+ return LZMA_RESULT_DATA_ERROR;
+ {
+ for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+ for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+ propsRes->lc = prop0;
+ /*
+ unsigned char remainder = (unsigned char)(prop0 / 9);
+ propsRes->lc = prop0 % 9;
+ propsRes->pb = remainder / 5;
+ propsRes->lp = remainder % 5;
+ */
+ }
+
+#ifdef _LZMA_OUT_READ
+ {
+ int i;
+ propsRes->DictionarySize = 0;
+ for (i = 0; i < 4; i++)
+ propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+ if (propsRes->DictionarySize == 0)
+ propsRes->DictionarySize = 1;
+ }
+#endif
+ return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+#ifdef _LZMA_IN_CB
+ ILzmaInCallback *InCallback,
+#else
+ const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+#endif
+ unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+ CProb *p = vs->Probs;
+ SizeT nowPos = 0;
+ Byte previousByte = 0;
+ UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+ UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+ int lc = vs->Properties.lc;
+
+#ifdef _LZMA_OUT_READ
+
+ UInt32 Range = vs->Range;
+ UInt32 Code = vs->Code;
+#ifdef _LZMA_IN_CB
+ const Byte *Buffer = vs->Buffer;
+ const Byte *BufferLim = vs->BufferLim;
+#else
+ const Byte *Buffer = inStream;
+ const Byte *BufferLim = inStream + inSize;
+#endif
+ int state = vs->State;
+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+ int len = vs->RemainLen;
+ UInt32 globalPos = vs->GlobalPos;
+ UInt32 distanceLimit = vs->DistanceLimit;
+
+ Byte *dictionary = vs->Dictionary;
+ UInt32 dictionarySize = vs->Properties.DictionarySize;
+ UInt32 dictionaryPos = vs->DictionaryPos;
+
+ Byte tempDictionary[4];
+
+#ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+#endif
+ *outSizeProcessed = 0;
+ if (len == kLzmaStreamWasFinishedId)
+ return LZMA_RESULT_OK;
+
+ if (dictionarySize == 0)
+ {
+ dictionary = tempDictionary;
+ dictionarySize = 1;
+ tempDictionary[0] = vs->TempDictionary[0];
+ }
+
+ if (len == kLzmaNeedInitId)
+ {
+ {
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ UInt32 i;
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ rep0 = rep1 = rep2 = rep3 = 1;
+ state = 0;
+ globalPos = 0;
+ distanceLimit = 0;
+ dictionaryPos = 0;
+ dictionary[dictionarySize - 1] = 0;
+#ifdef _LZMA_IN_CB
+ RC_INIT;
+#else
+ RC_INIT(inStream, inSize);
+#endif
+ }
+ len = 0;
+ }
+ while(len != 0 && nowPos < outSize)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+ len--;
+ }
+ if (dictionaryPos == 0)
+ previousByte = dictionary[dictionarySize - 1];
+ else
+ previousByte = dictionary[dictionaryPos - 1];
+
+#else /* if !_LZMA_OUT_READ */
+
+ int state = 0;
+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+ int len = 0;
+ const Byte *Buffer;
+ const Byte *BufferLim;
+ UInt32 Range;
+ UInt32 Code;
+
+#ifndef _LZMA_IN_CB
+ *inSizeProcessed = 0;
+#endif
+ *outSizeProcessed = 0;
+
+ {
+ UInt32 i;
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+ for (i = 0; i < numProbs; i++)
+ p[i] = kBitModelTotal >> 1;
+ }
+
+#ifdef _LZMA_IN_CB
+ RC_INIT;
+#else
+ RC_INIT(inStream, inSize);
+#endif
+
+#endif /* _LZMA_OUT_READ */
+
+ while(nowPos < outSize)
+ {
+ CProb *prob;
+ UInt32 bound;
+ int posState = (int)(
+ (nowPos
+#ifdef _LZMA_OUT_READ
+ + globalPos
+#endif
+ )
+ & posStateMask);
+
+ prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+ int symbol = 1;
+ UpdateBit0(prob)
+ prob = p + Literal + (LZMA_LIT_SIZE *
+ (((
+ (nowPos
+#ifdef _LZMA_OUT_READ
+ + globalPos
+#endif
+ )
+ & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state >= kNumLitStates)
+ {
+ int matchByte;
+#ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+#else
+ matchByte = outStream[nowPos - rep0];
+#endif
+ do
+ {
+ int bit;
+ CProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & 0x100);
+ probLit = prob + 0x100 + bit + symbol;
+ RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+ }
+ while (symbol < 0x100);
+ }
+ while (symbol < 0x100)
+ {
+ CProb *probLit = prob + symbol;
+ RC_GET_BIT(probLit, symbol)
+ }
+ previousByte = (Byte)symbol;
+
+ outStream[nowPos++] = previousByte;
+#ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+#endif
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ }
+else
+{
+ UpdateBit1(prob);
+ prob = p + IsRep + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < kNumLitStates ? 0 : 3;
+ prob = p + LenCoder;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG0 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IfBit0(prob)
+ {
+#ifdef _LZMA_OUT_READ
+ UInt32 pos;
+#endif
+ UpdateBit0(prob);
+
+#ifdef _LZMA_OUT_READ
+ if (distanceLimit == 0)
+#else
+ if (nowPos == 0)
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+
+ state = state < kNumLitStates ? 9 : 11;
+#ifdef _LZMA_OUT_READ
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+#else
+ previousByte = outStream[nowPos - rep0];
+#endif
+ outStream[nowPos++] = previousByte;
+#ifdef _LZMA_OUT_READ
+ if (distanceLimit < dictionarySize)
+ distanceLimit++;
+#endif
+
+ continue;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ UpdateBit1(prob);
+ prob = p + IsRepG1 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ prob = p + IsRepG2 + state;
+ IfBit0(prob)
+ {
+ UpdateBit0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UpdateBit1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = p + RepLenCoder;
+ }
+ {
+ int numBits, offset;
+ CProb *probLen = prob + LenChoice;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ numBits = kLenNumLowBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenChoice2;
+ IfBit0(probLen)
+ {
+ UpdateBit0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ numBits = kLenNumMidBits;
+ }
+ else
+ {
+ UpdateBit1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ numBits = kLenNumHighBits;
+ }
+ }
+ RangeDecoderBitTreeDecode(probLen, numBits, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ int posSlot;
+ state += kNumLitStates;
+ prob = p + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = (2 | ((UInt32)posSlot & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ rep0 <<= numDirectBits;
+ prob = p + SpecPos + rep0 - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ RC_NORMALIZE
+ Range >>= 1;
+ rep0 <<= 1;
+ if (Code >= Range)
+ {
+ Code -= Range;
+ rep0 |= 1;
+ }
+ }
+ while (--numDirectBits != 0);
+ prob = p + Align;
+ rep0 <<= kNumAlignBits;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ int i = 1;
+ int mi = 1;
+ do
+ {
+ CProb *prob3 = prob + mi;
+ RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+ i <<= 1;
+ }
+ while(--numDirectBits != 0);
+ }
+ }
+ else
+ rep0 = posSlot;
+ if (++rep0 == (UInt32)(0))
+ {
+ /* it's for stream version */
+ len = kLzmaStreamWasFinishedId;
+ break;
+ }
+ }
+
+ len += kMatchMinLen;
+#ifdef _LZMA_OUT_READ
+ if (rep0 > distanceLimit)
+#else
+ if (rep0 > nowPos)
+#endif
+ return LZMA_RESULT_DATA_ERROR;
+
+#ifdef _LZMA_OUT_READ
+ if (dictionarySize - distanceLimit > (UInt32)len)
+ distanceLimit += len;
+ else
+ distanceLimit = dictionarySize;
+#endif
+
+ do
+ {
+#ifdef _LZMA_OUT_READ
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ if (++dictionaryPos == dictionarySize)
+ dictionaryPos = 0;
+#else
+ previousByte = outStream[nowPos - rep0];
+#endif
+ len--;
+ outStream[nowPos++] = previousByte;
+ }
+ while(len != 0 && nowPos < outSize);
+}
+ }
+ RC_NORMALIZE;
+
+#ifdef _LZMA_OUT_READ
+ vs->Range = Range;
+ vs->Code = Code;
+ vs->DictionaryPos = dictionaryPos;
+ vs->GlobalPos = globalPos + (UInt32)nowPos;
+ vs->DistanceLimit = distanceLimit;
+ vs->Reps[0] = rep0;
+ vs->Reps[1] = rep1;
+ vs->Reps[2] = rep2;
+ vs->Reps[3] = rep3;
+ vs->State = state;
+ vs->RemainLen = len;
+ vs->TempDictionary[0] = tempDictionary[0];
+#endif
+
+#ifdef _LZMA_IN_CB
+ vs->Buffer = Buffer;
+ vs->BufferLim = BufferLim;
+#else
+ *inSizeProcessed = (SizeT)(Buffer - inStream);
+#endif
+ *outSizeProcessed = nowPos;
+ return LZMA_RESULT_OK;
+}
+
+//-----------------------------------------------------------------------------
+// Returns true if buffer is compressed.
+//-----------------------------------------------------------------------------
+bool CLZMA::IsCompressed( unsigned char *pInput )
+{
+ lzma_header_t *pHeader = (lzma_header_t *)pInput;
+ if ( pHeader && pHeader->id == LZMA_ID )
+ {
+ return true;
+ }
+
+ // unrecognized
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Returns uncompressed size of compressed input buffer. Used for allocating output
+// buffer for decompression. Returns 0 if input buffer is not compressed.
+//-----------------------------------------------------------------------------
+unsigned int CLZMA::GetActualSize( unsigned char *pInput )
+{
+ lzma_header_t *pHeader = (lzma_header_t *)pInput;
+ if ( pHeader && pHeader->id == LZMA_ID )
+ {
+ return LittleLong( pHeader->actualSize );
+ }
+
+ // unrecognized
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Uncompress a buffer, Returns the uncompressed size. Caller must provide an
+// adequate sized output buffer or memory corruption will occur.
+//-----------------------------------------------------------------------------
+unsigned int CLZMA::Uncompress( unsigned char *pInput, unsigned char *pOutput )
+{
+ unsigned int actualSize = GetActualSize( pInput );
+ if ( !actualSize )
+ {
+ // unrecognized
+ return 0;
+ }
+
+ CLzmaDecoderState state;
+ if ( LzmaDecodeProperties( &state.Properties, ((lzma_header_t *)pInput)->properties, LZMA_PROPERTIES_SIZE ) != LZMA_RESULT_OK )
+ {
+ Assert( 0 );
+ }
+ state.Probs = (CProb *)malloc( LzmaGetNumProbs( &state.Properties ) * sizeof( CProb ) );
+
+ unsigned int lzmaSize = LittleLong( ((lzma_header_t *)pInput)->lzmaSize );
+
+ SizeT inProcessed;
+ SizeT outProcessed;
+ int result = LzmaDecode( &state, pInput + sizeof( lzma_header_t ), lzmaSize, &inProcessed, pOutput, actualSize, &outProcessed );
+
+ free( state.Probs );
+
+ if ( result != LZMA_RESULT_OK || outProcessed != (SizeT)actualSize )
+ {
+ Assert( 0 );
+ return 0;
+ }
+
+ return outProcessed;
+}
+
diff --git a/mp/src/tier1/snappy-stubs-internal.h b/mp/src/tier1/snappy-stubs-internal.h index c585a2e6..f75fd482 100644 --- a/mp/src/tier1/snappy-stubs-internal.h +++ b/mp/src/tier1/snappy-stubs-internal.h @@ -138,12 +138,21 @@ class LogMessage { class LogMessageCrash : public LogMessage {
public:
LogMessageCrash() { }
+#if _MSC_VER == 1700
+// Bogus warning from VS 2012:
+// warning C4722: 'snappy::LogMessageCrash::~LogMessageCrash' : destructor never returns, potential memory leak
+#pragma warning(push)
+#pragma warning(disable : 4722)
+#endif
~LogMessageCrash() {
fprintf( stderr, "\n" );
// cerr << endl;
abort();
}
};
+#if _MSC_VER == 1700
+#pragma warning(pop)
+#endif
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
diff --git a/mp/src/tier1/tier1.vpc b/mp/src/tier1/tier1.vpc index 2784d62c..eac035ce 100644 --- a/mp/src/tier1/tier1.vpc +++ b/mp/src/tier1/tier1.vpc @@ -44,7 +44,7 @@ $Project "tier1" $File "interface.cpp"
$File "KeyValues.cpp"
$File "kvpacker.cpp"
- $File "lzmaDecoder.cpp" [!$SOURCESDK]
+ $File "lzmaDecoder.cpp"
$File "lzss.cpp" [!$SOURCESDK]
$File "mempool.cpp"
$File "memstack.cpp"
diff --git a/mp/src/utils/vrad/lightmap.cpp b/mp/src/utils/vrad/lightmap.cpp index b6f8c1f7..bc3d254e 100644 --- a/mp/src/utils/vrad/lightmap.cpp +++ b/mp/src/utils/vrad/lightmap.cpp @@ -661,8 +661,9 @@ bool BuildFacesamples( lightinfo_t *pLightInfo, facelight_t *pFaceLight ) pTex->lightmapVecsLuxelsPerWorldUnits[1] ) ) );
// allocate a large number of samples for creation -- get copied later!
- char sampleData[sizeof(sample_t)*SINGLE_BRUSH_MAP*2];
- sample_t *samples = (sample_t*)sampleData; // use a char array to speed up the debug version.
+ CUtlVector<sample_t> sampleData;
+ sampleData.SetCount( SINGLE_BRUSH_MAP * 2 );
+ sample_t *samples = sampleData.Base();
sample_t *pSamples = samples;
// lightmap space winding
diff --git a/mp/src/utils/vrad/trace.cpp b/mp/src/utils/vrad/trace.cpp index f049fc40..8069dbe7 100644 --- a/mp/src/utils/vrad/trace.cpp +++ b/mp/src/utils/vrad/trace.cpp @@ -622,14 +622,23 @@ void AddBrushesForRayTrace( void ) for ( int j = 0; j < face->numedges; j++ )
{
+ if ( j >= MAX_POINTS_ON_WINDING )
+ Error( "***** ERROR! MAX_POINTS_ON_WINDING reached!" );
+
+ if ( face->firstedge + j >= ARRAYSIZE( dsurfedges ) )
+ Error( "***** ERROR! face->firstedge + j >= ARRAYSIZE( dsurfedges )!" );
+
int surfEdge = dsurfedges[face->firstedge + j];
- short v;
+ unsigned short v;
if (surfEdge < 0)
v = dedges[-surfEdge].v[1];
else
v = dedges[surfEdge].v[0];
+ if ( v >= ARRAYSIZE( dvertexes ) )
+ Error( "***** ERROR! v(%u) >= ARRAYSIZE( dvertexes(%d) )!", ( unsigned int )v, ARRAYSIZE( dvertexes ) );
+
dvertex_t *dv = &dvertexes[v];
points[j] = dv->point;
}
diff --git a/mp/src/utils/vrad/vrad_dispcoll.cpp b/mp/src/utils/vrad/vrad_dispcoll.cpp index df69a4ac..7e788d07 100644 --- a/mp/src/utils/vrad/vrad_dispcoll.cpp +++ b/mp/src/utils/vrad/vrad_dispcoll.cpp @@ -665,8 +665,8 @@ void CVRADDispColl::CreateChildPatchesSub( int iParentPatch ) // Split along the longest edge.
Vector vecEdges[3];
vecEdges[0] = pParentPatch->winding->p[1] - pParentPatch->winding->p[0];
- vecEdges[1] = pParentPatch->winding->p[2] - pParentPatch->winding->p[0];
- vecEdges[2] = pParentPatch->winding->p[2] - pParentPatch->winding->p[1];
+ vecEdges[1] = pParentPatch->winding->p[2] - pParentPatch->winding->p[1];
+ vecEdges[2] = pParentPatch->winding->p[0] - pParentPatch->winding->p[2];
// Find the longest edge.
float flEdgeLength = 0.0f;
diff --git a/mp/src/utils/vrad/vraddisps.cpp b/mp/src/utils/vrad/vraddisps.cpp index 1e8d2606..0bbafd40 100644 --- a/mp/src/utils/vrad/vraddisps.cpp +++ b/mp/src/utils/vrad/vraddisps.cpp @@ -1135,7 +1135,7 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal if( bNeighborBump )
{
float flScale = patchNormal.Dot( normals[0] );
- flScale = clamp( flScale, 0.0f, flScale );
+ flScale = max( 0.0f, flScale );
float flBumpInfluence = influence * flScale;
for( int ndxBump = 0; ndxBump < ( NUM_BUMP_VECTS+1 ); ndxBump++ )
@@ -1148,7 +1148,7 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal else
{
float flScale = patchNormal.Dot( normals[0] );
- flScale = clamp( flScale, 0.0f, flScale );
+ flScale = max( 0.0f, flScale );
float flBumpInfluence = influence * flScale * 0.05f;
for( int ndxBump = 0; ndxBump < ( NUM_BUMP_VECTS+1 ); ndxBump++ )
@@ -1162,7 +1162,7 @@ void AddPatchLightToRadial( Vector const &patchOrigin, Vector const &patchNormal else
{
float flScale = patchNormal.Dot( luxelNormal );
- flScale = clamp( flScale, 0.0f, flScale );
+ flScale = max( 0.0f, flScale );
influence *= flScale;
pRadial->light[0][ndxRadial].AddWeighted( pPatchLight[0], influence );
@@ -1580,21 +1580,13 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace //
int ndxU, ndxV;
- // NOTE: These allocations are necessary to avoid stack overflow
- // FIXME: Solve with storing global per-thread temp buffers if there's
- // a performance problem with this solution...
- bool bTempAllocationNecessary = ((height + 1) * (width + 1)) > SINGLE_BRUSH_MAP;
+ CUtlVector<sample_t> samples;
+ samples.SetCount( SINGLEMAP );
+ sample_t *pSamples = samples.Base();
- Vector worldPointBuffer[SINGLE_BRUSH_MAP];
- sample_t sampleBuffer[SINGLE_BRUSH_MAP*2];
-
- Vector *pWorldPoints = worldPointBuffer;
- sample_t *pSamples = sampleBuffer;
- if (bTempAllocationNecessary)
- {
- pWorldPoints = new Vector[ SINGLEMAP ];
- pSamples = new sample_t[ SINGLEMAP ];
- }
+ CUtlVector<Vector> worldPoints;
+ worldPoints.SetCount( SINGLEMAP );
+ Vector *pWorldPoints = worldPoints.Base();
for( ndxV = 0; ndxV < ( height + 1 ); ndxV++ )
{
@@ -1607,7 +1599,6 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace }
}
-
for( ndxV = 0; ndxV < height; ndxV++ )
{
for( ndxU = 0; ndxU < width; ndxU++ )
@@ -1660,7 +1651,7 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace pFaceLight->numsamples = width * height;
pFaceLight->sample = ( sample_t* )calloc( pFaceLight->numsamples, sizeof( *pFaceLight->sample ) );
if( !pFaceLight->sample )
- goto buildDispSamplesError;
+ return false;
memcpy( pFaceLight->sample, pSamples, pFaceLight->numsamples * sizeof( *pFaceLight->sample ) );
@@ -1669,23 +1660,8 @@ bool CVRadDispMgr::BuildDispSamples( lightinfo_t *pLightInfo, facelight_t *pFace {
Msg( "BuildDispSamples: WARNING - no samples %d\n", pLightInfo->face - g_pFaces );
}
-
- if (bTempAllocationNecessary)
- {
- delete[] pWorldPoints;
- delete[] pSamples;
- }
return true;
-
-buildDispSamplesError:
- if (bTempAllocationNecessary)
- {
- delete[] pWorldPoints;
- delete[] pSamples;
- }
-
- return false;
}
diff --git a/mp/src/vpc_scripts/groups.vgc b/mp/src/vpc_scripts/groups.vgc index 93f7b2c5..c4786f55 100644 --- a/mp/src/vpc_scripts/groups.vgc +++ b/mp/src/vpc_scripts/groups.vgc @@ -23,10 +23,16 @@ $Group "game" "vgui_controls"
}
+$Group "shaders"
+{
+ "game_shader_dx9"
+}
+
$Group "everything"
{
"captioncompiler"
"client"
+ "game_shader_dx9"
"glview"
"height2normal"
"mathlib"
diff --git a/mp/src/vpc_scripts/projects.vgc b/mp/src/vpc_scripts/projects.vgc index 649cd85b..9ce86546 100644 --- a/mp/src/vpc_scripts/projects.vgc +++ b/mp/src/vpc_scripts/projects.vgc @@ -19,6 +19,11 @@ $Project "client" "game\client\client_hl2mp.vpc" [($WIN32||$POSIX) && $HL2MP]
}
+$Project "game_shader_dx9"
+{
+ "materialsystem\stdshaders\game_shader_dx9_hl2mp.vpc" [$HL2MP]
+}
+
$Project "glview"
{
"utils\glview\glview.vpc" [$WIN32]
diff --git a/mp/src/vpc_scripts/source_base.vpc b/mp/src/vpc_scripts/source_base.vpc index 074b850c..fc70c2e5 100644 --- a/mp/src/vpc_scripts/source_base.vpc +++ b/mp/src/vpc_scripts/source_base.vpc @@ -10,8 +10,8 @@ // This is one file we expect to be different between branches and so it must be merged carefully
// Staging branch:
-//$Macro STAGING_ONLY "1"
+//$Conditional STAGING_ONLY "1"
// rel/tf_beta branch:
-//$Macro TF_BETA "1"
+//$Conditional TF_BETA "1"
diff --git a/mp/src/vpc_scripts/source_dll_win32_base.vpc b/mp/src/vpc_scripts/source_dll_win32_base.vpc index 77f577e2..4382efaa 100644 --- a/mp/src/vpc_scripts/source_dll_win32_base.vpc +++ b/mp/src/vpc_scripts/source_dll_win32_base.vpc @@ -130,7 +130,7 @@ $Project $CustomBuildStep
{
// General
- $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE"
+ $CommandLine "$QUOTE$(VCInstallDir)bin\ml.exe$QUOTE /safeseh /c /Cp /Zi /Fo$QUOTE$(IntDir)\$(InputName).obj$QUOTE $QUOTE$(InputPath)$QUOTE"
$Description "Compiling pointeroverride.asm"
$Outputs "$(IntDir)\$(InputName).obj"
}
diff --git a/mp/src/vpc_scripts/source_video_base.vpc b/mp/src/vpc_scripts/source_video_base.vpc index b1baa408..dd7f3653 100644 --- a/mp/src/vpc_scripts/source_video_base.vpc +++ b/mp/src/vpc_scripts/source_video_base.vpc @@ -31,7 +31,7 @@ $Macro GL "1" [!$DEDICATED && !$WIN32 && !$WIN64]
// If we're using OpenGL, we're implicitly using SDL.
-$Macro SDL "1" [$GL && !$OSXALL && !$DEDICATED]
+$Macro SDL "1" [$GL && !$DEDICATED]
$Configuration
{
@@ -57,5 +57,14 @@ $Configuration $PreprocessorDefinitions "$BASE;USE_SDL" [$SDL]
$AdditionalIncludeDirectories "$BASE;$SRCDIR\thirdparty\SDL2" [$SDL || $DEDICATED]
}
+
+}
+
+$Project
+{
+ $Folder "Link Libraries" [$OSXALL && $SDL]
+ {
+ $DynamicFile "$SRCDIR\lib\public\$PLATFORM\$_IMPLIB_PREFIXSDL2$_IMPLIB_EXT"
+ }
}
diff --git a/mp/src/vpc_scripts/source_win32_base.vpc b/mp/src/vpc_scripts/source_win32_base.vpc index 8be3bcf6..04ef53b8 100644 --- a/mp/src/vpc_scripts/source_win32_base.vpc +++ b/mp/src/vpc_scripts/source_win32_base.vpc @@ -60,10 +60,6 @@ $Configuration $PreprocessorDefinitions "$BASE;WIN64;_WIN64;COMPILER_MSVC64" [$WIN64]
$PreprocessorDefinitions "$BASE;COMPILER_MSVC32" [$WIN32]
- // The VS 2012 compiler keeps hitting internal compiler errors during /analyze. In order to get these
- // fixed we need to report them.
- $AdditionalOptions "$BASE /errorReport:send" [$ANALYZE]
-
// Pass on appropriate branch define to preprocessor
$PreprocessorDefinitions "$BASE;STAGING_ONLY" [$STAGING_ONLY]
$PreprocessorDefinitions "$BASE;TF_BETA" [$TF_BETA]
|