This commit is contained in:
romkazvo
2023-08-07 19:29:24 +08:00
commit 34d6c5d489
4832 changed files with 1389451 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
typedef union
{
int ival;
float fval;
string * sval;
constdef * cdef;
std::vector<constdef> * consts;
std::vector<string> * line;
std::list<std::vector<string> > * lines;
} YYSTYPE;
#define HEADER 257
#define NEWLINE 258
#define NUMBER 259
#define REG 260
#define DEF 261
#define ADDROP 262
#define BLENDOP 263
extern YYSTYPE ps10_lval;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
typedef union {
int ival;
float fval;
RegisterEnum registerEnum;
BiasScaleEnum biasScaleEnum;
MappedRegisterStruct mappedRegisterStruct;
ConstColorStruct constColorStruct;
GeneralPortionStruct generalPortionStruct;
GeneralFunctionStruct generalFunctionStruct;
OpStruct opStruct;
GeneralCombinerStruct generalCombinerStruct;
GeneralCombinersStruct generalCombinersStruct;
FinalProductStruct finalProductStruct;
FinalRgbFunctionStruct finalRgbFunctionStruct;
FinalAlphaFunctionStruct finalAlphaFunctionStruct;
FinalCombinerStruct finalCombinerStruct;
CombinersStruct combinersStruct;
} YYSTYPE;
#define regVariable 257
#define constVariable 258
#define color_sum 259
#define final_product 260
#define expandString 261
#define halfBiasString 262
#define unsignedString 263
#define unsignedInvertString 264
#define muxString 265
#define sumString 266
#define rgb_portion 267
#define alpha_portion 268
#define openParen 269
#define closeParen 270
#define openBracket 271
#define closeBracket 272
#define semicolon 273
#define comma 274
#define dot 275
#define times 276
#define minus 277
#define equals 278
#define plus 279
#define bias_by_negative_one_half_scale_by_two 280
#define bias_by_negative_one_half 281
#define scale_by_one_half 282
#define scale_by_two 283
#define scale_by_four 284
#define clamp_color_sum 285
#define lerp 286
#define fragment_rgb 287
#define fragment_alpha 288
#define floatValue 289
extern YYSTYPE rc10_lval;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
typedef union {
float fval;
InstPtr inst;
InstListPtr instList;
MappedVariablePtr variable;
} YYSTYPE;
#define floatValue 257
#define gequal 258
#define less 259
#define texVariable 260
#define expandString 261
#define openParen 262
#define closeParen 263
#define semicolon 264
#define comma 265
#define nop 266
#define texture_1d 267
#define texture_2d 268
#define texture_rectangle 269
#define texture_3d 270
#define texture_cube_map 271
#define cull_fragment 272
#define pass_through 273
#define offset_2d_scale 274
#define offset_2d 275
#define offset_rectangle_scale 276
#define offset_rectangle 277
#define offset_projective_2d_scale 278
#define offset_projective_2d 279
#define offset_projective_rectangle_scale 280
#define offset_projective_rectangle 281
#define dependent_ar 282
#define dependent_gb 283
#define dot_product_2d_1of2 284
#define dot_product_2d_2of2 285
#define dot_product_rectangle_1of2 286
#define dot_product_rectangle_2of2 287
#define dot_product_depth_replace_1of2 288
#define dot_product_depth_replace_2of2 289
#define dot_product_3d_1of3 290
#define dot_product_3d_2of3 291
#define dot_product_3d_3of3 292
#define dot_product_cube_map_1of3 293
#define dot_product_cube_map_2of3 294
#define dot_product_cube_map_3of3 295
#define dot_product_reflect_cube_map_eye_from_qs_1of3 296
#define dot_product_reflect_cube_map_eye_from_qs_2of3 297
#define dot_product_reflect_cube_map_eye_from_qs_3of3 298
#define dot_product_reflect_cube_map_const_eye_1of3 299
#define dot_product_reflect_cube_map_const_eye_2of3 300
#define dot_product_reflect_cube_map_const_eye_3of3 301
#define dot_product_cube_map_and_reflect_cube_map_eye_from_qs_1of3 302
#define dot_product_cube_map_and_reflect_cube_map_eye_from_qs_2of3 303
#define dot_product_cube_map_and_reflect_cube_map_eye_from_qs_3of3 304
#define dot_product_cube_map_and_reflect_cube_map_const_eye_1of3 305
#define dot_product_cube_map_and_reflect_cube_map_const_eye_2of3 306
#define dot_product_cube_map_and_reflect_cube_map_const_eye_3of3 307
extern YYSTYPE ts10_lval;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
typedef union {
int ival;
unsigned int lval;
float fval;
char mask[4];
char *comment;
VS10Reg reg;
VS10InstPtr inst;
VS10InstListPtr instList;
} YYSTYPE;
#define VERTEX_SHADER 257
#define ADD_INSTR 258
#define DP3_INSTR 259
#define DP4_INSTR 260
#define DST_INSTR 261
#define EXP_INSTR 262
#define EXPP_INSTR 263
#define FRC_INSTR 264
#define LIT_INSTR 265
#define LOG_INSTR 266
#define LOGP_INSTR 267
#define M3X2_INSTR 268
#define M3X3_INSTR 269
#define M3X4_INSTR 270
#define M4X3_INSTR 271
#define M4X4_INSTR 272
#define MAD_INSTR 273
#define MAX_INSTR 274
#define MIN_INSTR 275
#define MOV_INSTR 276
#define MUL_INSTR 277
#define NOP_INSTR 278
#define RCP_INSTR 279
#define RSQ_INSTR 280
#define SGE_INSTR 281
#define SLT_INSTR 282
#define SUB_INSTR 283
#define ILLEGAL 284
#define UNKNOWN_STRING 285
#define INTVAL 286
#define REGISTER 287
#define XYZW_MODIFIER 288
#define COMMENT 289
extern YYSTYPE vs10_lval;

View File

@@ -0,0 +1,44 @@
#ifdef _WIN32
#include <io.h>
#else
#include <ctype.h>
#endif
typedef struct MACROTEXT {
MACROTEXT *next;
MACROTEXT *prev;
char *macroText;
} MACROTEXT;
typedef struct MACROENTRY
{
MACROENTRY *next;
MACROENTRY *prev;
char *macroName;
MACROTEXT *firstMacroParms;
MACROTEXT *lastMacroParms;
MACROTEXT *firstMacroLines;
MACROTEXT *lastMacroLines;
unsigned int numParms;
char *fileName;
unsigned int lineNo;
unsigned int nLines;
bool bIsDefine;
} MACROENTRY;
#define MAX_IFDEF_DEPTH 1024
typedef struct IFDEFINFO
{
bool lastbProcessingIFDEF; // save off for if we were processing #ifdef
bool lastbIFDEF; // wether ifdef was true or not
bool lastbCompareDefine; // wether we compare #ifdef or #ifndef
unsigned int lastIfDefStartLine; // where we started for this #ifdef
} IFDEFINFO;
typedef void (*MACROFUNCTIONPTR)(char *, unsigned int *, char **);
typedef struct MACROFUNCTIONS
{
char *name;
MACROFUNCTIONPTR function;
} MACROFUNCTIONS;

View File

@@ -0,0 +1,158 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include <string>
//void yyinit(char*);
//int yyparse(void);
#include "rc1.0_general.h"
// RC1.0 -- register combiners 1.0 configuration
bool rc10_init(char *);
int rc10_parse();
bool is_rc10(const char *);
// TS1.0 -- texture shader 1.0 configuration
bool ts10_init(char *);
int ts10_parse();
bool is_ts10(const char *);
// VP1.0 -- vertex program
bool vp10_init(char *);
int vp10_parse();
bool is_vp10(const char *);
// VSP1.0 -- vertex state program
bool vsp10_init(char *);
int vsp10_parse(int vspid);
bool is_vsp10(const char *);
// VCP1.0 -- vertex constant program
bool vcp10_init(char *);
int vcp10_parse();
bool is_vcp10(const char *);
// DX8 stuff
// PS1.0 -- DX8 Pixel Shader 1.0 configuration
bool ps10_init(char *);
int ps10_parse();
bool is_ps10(const char *);
// VS1.0 -- DX8 Vertex Shader 1.0
bool vs10_init(char *);
int vs10_parse();
bool is_vs10(const char *);
void vs10_load_program();
nvparse_errors errors;
int line_number;
char * myin = 0;
TArray<SCGBindConst> gParseConsts;
void nvparse(bool bPerStage, const char * input_string, ...)
{
if (NULL == input_string)
{
errors.set("NULL string passed to nvparse");
return;
}
int len = strlen(input_string)+1;
char * instring = new char [len];
memcpy(instring, input_string, len);
// vertex constant program
if(is_vcp10(instring))
{
if(vcp10_init(instring))
{
vcp10_parse();
}
}
// vertex state program
else if(is_vsp10(instring))
{
if(vsp10_init(instring))
{
va_list ap;
va_start(ap, input_string);
int vspid = va_arg(ap,int);
va_end(ap);
vsp10_parse(vspid);
}
}
// vertex program
else if(is_vp10(instring))
{
if(vp10_init(instring))
{
vp10_parse();
}
}
// register combiners (1 and 2)
else if(is_rc10(instring))
{
if(rc10_init(instring))
{
gParseConsts.Free();
rc10_parse();
}
}
// texture shader
else if(is_ts10(instring))
{
if(ts10_init(instring))
{
ts10_parse();
}
}
// DX8 vertex shader
else if ( is_vs10(instring) )
{
if(vs10_init(instring))
{
vs10_parse();
vs10_load_program();
}
}
else if (is_ps10(instring))
{
if(ps10_init(instring))
{
ps10_parse();
}
}
else
{
errors.set("invalid string.\n \
first characters must be: !!VP1.0 or !!VSP1.0 or !!RC1.0 or !!TS1.0\n \
or it must be a valid DirectX 8.0 Vertex Shader");
}
delete [] instring;
}
char * const * const nvparse_get_errors()
{
return errors.get_errors();
}
char * const * const nvparse_print_errors(FILE * errfp)
{
for (char * const * ep = nvparse_get_errors(); *ep; ep++)
{
const char * errstr = *ep;
fprintf(errfp, errstr);
}
return nvparse_get_errors();
}

View File

@@ -0,0 +1,17 @@
#ifndef NVPARSE_H
#define NVPARSE_H
#define NVPARSE 1
#include "nvparse_errors.h"
#include "nvparse_externs.h"
#include "../GL_Renderer.h"
void nvparse(bool m_bPerStage, const char * input_string, ...);
char * const * const nvparse_get_errors();
extern TArray<SCGBindConst> gParseConsts;
//======================================================================
#endif

View File

@@ -0,0 +1,56 @@
#include "RenderPCH.h"
#include "nvparse.h"
nvparse_errors::nvparse_errors()
{
num_errors = 0;
reset();
}
nvparse_errors::~nvparse_errors()
{
reset();
}
void nvparse_errors::reset()
{
for(int i=0; i < num_errors; i++)
free(elist[i]);//FIXME detail_nmap something is writing 0x2 to elist[1] blah!
for(int j=0; j <= NVPARSE_MAX_ERRORS; j++)
elist[j] = 0;
num_errors = 0;
}
extern char *gShObjectNotFound;
void nvparse_errors::set(const char * e)
{
if(num_errors < NVPARSE_MAX_ERRORS)
{
char buf[512];
if (gShObjectNotFound)
{
sprintf(buf, "(%s) %s", gShObjectNotFound, e);
elist[num_errors++] = Cry_strdup(buf);
}
else
{
elist[num_errors++] = Cry_strdup(e);
}
}
}
void nvparse_errors::set(const char * e, int line_number)
{
char buff[256];
sprintf(buff, "error on line %d: %s", line_number, e);
if(num_errors < NVPARSE_MAX_ERRORS)
elist[num_errors++] = Cry_strdup(buff);
}
char * const * const nvparse_errors::get_errors()
{
return elist;
}

View File

@@ -0,0 +1,22 @@
#ifndef _NVPARSE_ERRORS_H_
#define _NVPARSE_ERRORS_H_
#pragma warning(disable:4786) // symbol size limitation
#define NVPARSE_MAX_ERRORS 32
class nvparse_errors
{
public:
nvparse_errors();
~nvparse_errors();
void reset();
void set(const char * e);
void set(const char * e, int line_number);
char * const * const get_errors();
inline int get_num_errors() { return num_errors; }
private:
char* elist [NVPARSE_MAX_ERRORS+1];
int num_errors;
};
#endif

View File

@@ -0,0 +1,9 @@
#ifndef NVPARSE_EXTERNS_H
#define NVPARSE_EXTERNS_H
extern nvparse_errors errors;
extern int line_number;
extern char * myin;
#endif

View File

@@ -0,0 +1,743 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "ps1.0_program.h"
//using namespace std;
using namespace ps10;
#define DBG_MESG(msg, line) errors.set(msg, line)
//#define DBG_MESG(msg, line)
namespace
{
struct set_constants
{
void operator() (constdef c)
{
if(c.reg[0] != 'c' && c.reg.size() != 2)
DBG_MESG("def line must use constant registers", 0);
int reg = c.reg[1] - '0';
GLenum stage = GL_COMBINER0_NV + (reg / 2);
GLenum cclr = GL_CONSTANT_COLOR0_NV + (reg % 2);
GLfloat cval[4];
cval[0] = c.r;
cval[0] = c.g;
cval[0] = c.b;
cval[0] = c.a;
glCombinerStageParameterfvNV(stage, cclr, cval);
}
};
GLenum get_tex_target()
{
if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
return GL_TEXTURE_CUBE_MAP_ARB;
if(glIsEnabled(GL_TEXTURE_3D))
return GL_TEXTURE_3D;
if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV))
return GL_TEXTURE_RECTANGLE_NV;
if(glIsEnabled(GL_TEXTURE_2D))
return GL_TEXTURE_2D;
if(glIsEnabled(GL_TEXTURE_1D))
return GL_TEXTURE_1D;
//otherwise make the op none...
return GL_NONE;
}
struct set_texture_shaders
{
set_texture_shaders(std::vector<constdef> * cdef)
{
for(stage = 0; stage < 4; stage++)
{
glActiveTextureARB(GL_TEXTURE0_ARB + stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
}
stage = 0;
c = cdef;
}
void operator() (std::vector<string> & instr)
{
if(stage > 3)
return;
glActiveTextureARB(GL_TEXTURE0_ARB + stage);
string op = instr[0];
if(op == "tex")
{
if(instr.size() != 2)
fprintf(stderr,"incorrect \"tex\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, get_tex_target());
}
else if(op == "texbem")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texbeml")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV);
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texcoord")
{
if(instr.size() != 2)
fprintf(stderr,"incorrect \"texcoord\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV);
}
else if(op == "texkill")
{
if(instr.size() != 2)
fprintf(stderr,"incorrect \"texkill\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV);
}
else if(op == "texm3x2pad")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texm3x2tex")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texm3x3pad")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texm3x3tex")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texm3x3spec")
{
if(instr.size() != 4 || stage == 0)
fprintf(stderr,"incorrect \"texm3x3spec\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
if(! c)
return;
constdef cd;
for(int i = c->size()-1; i >= 0; i--)
{
cd = (*c)[i];
if(cd.reg == "c0")
break;
}
if(cd.reg != string("c0") || instr[3] != string("c0"))
return;
GLfloat eye[4];
eye[0] = cd.r;
eye[1] = cd.g;
eye[2] = cd.b;
eye[3] = cd.a;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, eye);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texm3x3vspec")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texm3x3vspec\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV);
if(instr[2].find("_bx2") != string::npos)
{
instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
}
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texreg2ar")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV);
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
else if(op == "texreg2gb")
{
if(instr.size() != 3 || stage == 0)
fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
reg2stage[instr[1]] = stage;
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV);
if(reg2stage.count(instr[2]) == 0)
fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
}
stage++;
}
std::map<string, int> reg2stage;
int stage;
std::vector<constdef> * c;
};
GLenum reg_enum(string s)
{
if(s == "c0")
return GL_CONSTANT_COLOR0_NV;
else if(s == "c1")
return GL_CONSTANT_COLOR1_NV;
else if(s == "c2")
return GL_CONSTANT_COLOR0_NV;
else if(s == "c3")
return GL_CONSTANT_COLOR1_NV;
else if(s == "c4")
return GL_CONSTANT_COLOR0_NV;
else if(s == "c5")
return GL_CONSTANT_COLOR1_NV;
else if(s == "c6")
return GL_CONSTANT_COLOR0_NV;
else if(s == "c7")
return GL_CONSTANT_COLOR1_NV;
else if(s == "t0")
return GL_TEXTURE0_ARB;
else if(s == "t1")
return GL_TEXTURE1_ARB;
else if(s == "t2")
return GL_TEXTURE2_ARB;
else if(s == "t3")
return GL_TEXTURE3_ARB;
else if(s == "v0")
return GL_PRIMARY_COLOR_NV;
else if(s == "v1")
return GL_SECONDARY_COLOR_NV;
else if(s == "r0")
return GL_SPARE0_NV;
else if(s == "r1")
return GL_SPARE1_NV;
else // ??
return GL_DISCARD_NV;
}
struct src
{
src(string s)
{
init(s);
}
void init(string s)
{
arg = s;
comp = GL_RGB;
map = GL_SIGNED_IDENTITY_NV;
int offset;
if((offset = s.find(".a")) != string::npos)
{
comp = GL_ALPHA;
s.erase(offset, offset+2);
}
bool negate = false;
if(s[0] == '1')
{
s.erase(0, 1);
while(s[0] == ' ')
s.erase(0,1);
if(s[0] == '-')
s.erase(0,1);
while(s[0] == ' ')
s.erase(0,1);
map = GL_UNSIGNED_INVERT_NV;
}
else if(s[0] == '-')
{
s.erase(0, 1);
while(s[0] == ' ')
s.erase(0,1);
negate = true;
map = GL_UNSIGNED_INVERT_NV;
}
bool half_bias = false;
bool expand = false;
if(s.find("_bias") != string::npos)
{
s.erase(s.find("_bias"), 5);
half_bias = true;
}
else if(s.find("_bx2") != string::npos)
{
s.erase(s.find("_bx2"), 4);
expand = true;
}
if(expand)
{
if(negate)
map = GL_EXPAND_NEGATE_NV;
else
map = GL_EXPAND_NORMAL_NV;
}
else if(half_bias)
{
if(negate)
map = GL_HALF_BIAS_NEGATE_NV;
else
map = GL_HALF_BIAS_NORMAL_NV;
}
reg = reg_enum(s);
}
string arg;
GLenum reg;
GLenum map;
GLenum comp;
};
struct set_register_combiners
{
set_register_combiners()
{
combiner = 0;
}
void operator() (std::vector<string> & instr)
{
string op;
GLenum scale;
bool op_sat = false;
op = instr[0];
int offset;
if((offset = op.find("_x2")) != string::npos)
{
scale = GL_SCALE_BY_TWO_NV;
op.erase(op.begin()+offset, op.begin()+offset+3);
}
else if((offset = op.find("_x4")) != string::npos)
{
scale = GL_SCALE_BY_FOUR_NV;
op.erase(op.begin()+offset, op.begin()+offset+3);
}
else if((offset = op.find("_d2")) != string::npos)
{
scale = GL_SCALE_BY_ONE_HALF_NV;
op.erase(op.begin()+offset, op.begin()+offset+3);
}
if((offset = op.find("_sat")) != string::npos)
{
// need to actually use this...
op_sat = true;
op.erase(op.begin()+offset, op.begin()+offset+4);
}
string dst = instr[1];
int mask = GL_RGBA;
if((offset = dst.find(".rgba")) != string::npos)
{
dst.erase(offset, offset + 5);
}
else if((offset = dst.find(".rgb")) != string::npos)
{
dst.erase(offset, offset + 4);
mask = GL_RGB;
}
else if((offset = dst.find(".a")) != string::npos)
{
dst.erase(offset, offset + 2);
mask = GL_ALPHA;
}
GLenum dreg = reg_enum(dst);
GLenum C = GL_COMBINER0_NV + combiner;
if(op == "add" || op == "sub")
{
src a(instr[2]);
src b(instr[3]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
if(op == "add")
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
else
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB);
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, GL_ALPHA);
if(op == "add")
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
else
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "cnd")
{
src a(instr[3]);
src b(instr[4]);
if(instr[2] != string("r0.a"))
{} // bad
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_TRUE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_TRUE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "dp3")
{
src a(instr[2]);
src b(instr[3]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
// ooh.. what to do here?
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
// todo -- make next ref to dst.a actually ref dst.b since combiners can't write dp3 to the alpha channel
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "lrp")
{
src a(instr[2]);
src b(instr[3]);
src c(instr[4]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "mad")
{
src a(instr[2]);
src b(instr[3]);
src c(instr[4]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "mov")
{
src a(instr[2]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
else if(op == "mul")
{
src a(instr[2]);
src b(instr[3]);
if(mask == GL_RGBA || mask == GL_RGB)
{
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mask == GL_RGBA || mask == GL_ALPHA)
{
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, GL_ALPHA);
glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, GL_ALPHA);
glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
else
{
glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
GL_FALSE, GL_FALSE, GL_FALSE);
}
}
}
int combiner;
};
}
void ps10::invoke(std::vector<constdef> * c,
std::list<std::vector<string> > * a,
std::list<std::vector<string> > * b)
{
glEnable(GL_PER_STAGE_CONSTANTS_NV); // should we require apps to do this?
if(c)
std::for_each(c->begin(), c->end(), set_constants());
if(a)
std::for_each(a->begin(), a->end(), set_texture_shaders(c));
if(b)
std::for_each(b->begin(), b->end(), set_register_combiners());
}
// simple identification - just look for magic substring
// -- easy to break...
bool is_ps10(const char * s)
{
if(strstr(s, "ps.1.0"))
return true;
if(strstr(s, "Ps.1.0"))
return true;
return false;
}
bool ps10::init_extensions()
{
// register combiners
static bool rcinit = false;
if(rcinit == false)
{
if(!SUPPORTS_GL_NV_register_combiners)
{
errors.set("unable to initialize GL_NV_register_combiners\n");
return false;
}
else
{
rcinit = true;
}
}
// register combiners 2
static bool rc2init = false;
if(rc2init == false)
{
if( !SUPPORTS_GL_NV_register_combiners2)
{
errors.set("unable to initialize GL_NV_register_combiners2\n");
return false;
}
else
{
rc2init = true;
}
}
static bool tsinit = 0;
if (tsinit == false )
{
if(!SUPPORTS_GL_NV_texture_shader || !SUPPORTS_GL_ARB_multitexture)
{
errors.set("unable to initialize GL_NV_texture_shader\n");
return false;
}
else
{
tsinit = true;
}
}
return true;
}

View File

@@ -0,0 +1,21 @@
#ifndef _PS10_PROGRAM_H
#define _PS10_PROGRAM_H
namespace ps10
{
struct constdef
{
string reg;
float r,g,b,a;
};
void invoke(std::vector<constdef> * c,
std::list<std::vector<string> > * a,
std::list<std::vector<string> > * b);
bool init_extensions();
}
#endif

View File

@@ -0,0 +1,56 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "rc1.0_combiners.h"
void CombinersStruct::Validate()
{
if (2 == numConsts &&
cc[0].reg.bits.name == cc[1].reg.bits.name)
errors.set("global constant set twice");
generals.Validate(numConsts, &cc[0]);
final.Validate();
}
void CombinersStruct::Invoke()
{
for (int i = 0; i < numConsts; i++)
glCombinerParameterfvNV(cc[i].reg.bits.name, &(cc[i].v[0]));
generals.Invoke();
final.Invoke();
}
bool is_rc10(const char * s)
{
return ! strncmp(s, "!!RC1.0", 7);
}
bool rc10_init_more()
{
bool rcinit = false;
if(rcinit == false)
{
if(!SUPPORTS_GL_NV_register_combiners && !SUPPORTS_GL_ATI_fragment_shader)
{
errors.set("unable to initialize GL_NV_register_combiners or GL_ATI_fragment_shader\n");
return false;
}
else
{
rcinit = true;
}
}
bool rc2init = true;
errors.reset();
line_number = 1;
return true;
}

View File

@@ -0,0 +1,24 @@
#ifndef _RC10_COMBINERS_H
#define _RC10_COMBINERS_H
#include "rc1.0_general.h"
#include "rc1.0_final.h"
class CombinersStruct {
public:
void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0, ConstColorStruct _cc1)
{ generals = _gcs; final = _fc; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2;}
void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0)
{ generals = _gcs; final = _fc; cc[0] = _cc0; numConsts = 1;}
void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc)
{ generals = _gcs; final = _fc; numConsts = 0;}
void Validate();
void Invoke();
private:
GeneralCombinersStruct generals;
FinalCombinerStruct final;
ConstColorStruct cc[2];
int numConsts;
};
#endif

View File

@@ -0,0 +1,159 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "rc1.0_final.h"
#include "rc1.0_general.h"
void FinalRgbFunctionStruct::ZeroOut()
{
RegisterEnum zero;
zero.word = RCP_ZERO;
a.Init(zero, GL_UNSIGNED_IDENTITY_NV);
b.Init(zero, GL_UNSIGNED_IDENTITY_NV);
c.Init(zero, GL_UNSIGNED_IDENTITY_NV);
d.Init(zero, GL_UNSIGNED_IDENTITY_NV);
}
void FinalAlphaFunctionStruct::ZeroOut()
{
RegisterEnum zero;
zero.word = RCP_ZERO;
g.Init(zero, GL_UNSIGNED_IDENTITY_NV);
}
void FinalProductStruct::ZeroOut()
{
RegisterEnum zero;
zero.word = RCP_ZERO;
e.Init(zero, GL_UNSIGNED_IDENTITY_NV);
f.Init(zero, GL_UNSIGNED_IDENTITY_NV);
}
void FinalCombinerStruct::Validate()
{
if (hasProduct &&
(GL_E_TIMES_F_NV == product.e.reg.bits.name ||
GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.e.reg.bits.name ||
GL_DISCARD_NV == product.e.reg.bits.name ||
GL_E_TIMES_F_NV == product.f.reg.bits.name ||
GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.f.reg.bits.name ||
GL_DISCARD_NV == product.f.reg.bits.name))
errors.set("invalid input register for final_product");
if (hasProduct &&
(RCP_BLUE == product.e.reg.bits.channel ||
RCP_BLUE == product.f.reg.bits.channel))
errors.set("blue register used in final_product");
if (GL_E_TIMES_F_NV == alpha.g.reg.bits.name ||
GL_SPARE0_PLUS_SECONDARY_COLOR_NV == alpha.g.reg.bits.name ||
GL_DISCARD_NV == alpha.g.reg.bits.name)
errors.set("invalid input register for final alpha");
if (RCP_RGB == alpha.g.reg.bits.channel)
errors.set("rgb register used in final alpha");
if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name &&
GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.b.reg.bits.name &&
GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map)
{
MappedRegisterStruct temp;
temp = rgb.a;
rgb.a = rgb.b;
rgb.b = temp;
}
if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name &&
GL_ZERO == rgb.b.reg.bits.name && GL_UNSIGNED_INVERT_NV == rgb.b.map &&
GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map &&
GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.d.reg.bits.name)
{
MappedRegisterStruct temp;
temp = rgb.a;
rgb.a = rgb.d;
rgb.d = temp;
}
if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name ||
GL_DISCARD_NV == rgb.a.reg.bits.name ||
GL_DISCARD_NV == rgb.b.reg.bits.name ||
GL_DISCARD_NV == rgb.c.reg.bits.name ||
GL_DISCARD_NV == rgb.d.reg.bits.name)
errors.set("invalid input register for final rgb");
if (RCP_BLUE == rgb.a.reg.bits.channel ||
RCP_BLUE == rgb.b.reg.bits.channel ||
RCP_BLUE == rgb.c.reg.bits.channel ||
RCP_BLUE == rgb.d.reg.bits.channel)
errors.set("blue register used in final rgb");
if ((GL_E_TIMES_F_NV == rgb.a.reg.bits.name ||
GL_E_TIMES_F_NV == rgb.b.reg.bits.name ||
GL_E_TIMES_F_NV == rgb.c.reg.bits.name ||
GL_E_TIMES_F_NV == rgb.d.reg.bits.name) && !hasProduct)
errors.set("final_product used but not set");
if (RCP_NONE == rgb.a.reg.bits.channel)
rgb.a.reg.bits.channel = RCP_RGB;
if (RCP_NONE == rgb.b.reg.bits.channel)
rgb.b.reg.bits.channel = RCP_RGB;
if (RCP_NONE == rgb.c.reg.bits.channel)
rgb.c.reg.bits.channel = RCP_RGB;
if (RCP_NONE == rgb.d.reg.bits.channel)
rgb.d.reg.bits.channel = RCP_RGB;
if (RCP_NONE == product.e.reg.bits.channel)
product.e.reg.bits.channel = RCP_RGB;
if (RCP_NONE == product.f.reg.bits.channel)
product.f.reg.bits.channel = RCP_RGB;
if (RCP_NONE == alpha.g.reg.bits.channel)
alpha.g.reg.bits.channel = RCP_ALPHA;
}
void FinalCombinerStruct::Invoke()
{
if(clamp)
glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_TRUE);
else
glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_FALSE);
glFinalCombinerInputNV(
GL_VARIABLE_A_NV,
rgb.a.reg.bits.name,
rgb.a.map,
MAP_CHANNEL(rgb.a.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_B_NV,
rgb.b.reg.bits.name,
rgb.b.map,
MAP_CHANNEL(rgb.b.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_C_NV,
rgb.c.reg.bits.name,
rgb.c.map,
MAP_CHANNEL(rgb.c.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_D_NV,
rgb.d.reg.bits.name,
rgb.d.map,
MAP_CHANNEL(rgb.d.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_E_NV,
product.e.reg.bits.name,
product.e.map,
MAP_CHANNEL(product.e.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_F_NV,
product.f.reg.bits.name,
product.f.map,
MAP_CHANNEL(product.f.reg.bits.channel));
glFinalCombinerInputNV(
GL_VARIABLE_G_NV,
alpha.g.reg.bits.name,
alpha.g.map,
MAP_CHANNEL(alpha.g.reg.bits.channel));
}

View File

@@ -0,0 +1,48 @@
#ifndef _RC10_FINAL_H
#define _RC10_FINAL_H
#include "rc1.0_register.h"
class FinalAlphaFunctionStruct {
public:
void Init(MappedRegisterStruct _g) { g = _g; }
void ZeroOut();
MappedRegisterStruct g;
};
class FinalRgbFunctionStruct {
public:
void Init(MappedRegisterStruct _a, MappedRegisterStruct _b, MappedRegisterStruct _c, MappedRegisterStruct _d)
{ a = _a; b = _b; c = _c; d = _d; }
void ZeroOut();
MappedRegisterStruct a;
MappedRegisterStruct b;
MappedRegisterStruct c;
MappedRegisterStruct d;
};
class FinalProductStruct {
public:
void Init(MappedRegisterStruct _e, MappedRegisterStruct _f) { e = _e; f = _f; }
void ZeroOut();
MappedRegisterStruct e;
MappedRegisterStruct f;
};
class FinalCombinerStruct {
public:
void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp, FinalProductStruct _product)
{ rgb = _rgb; alpha = _alpha; clamp = _clamp; product = _product; hasProduct = true;}
void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp)
{ rgb = _rgb; alpha = _alpha; clamp = _clamp; hasProduct = false; product.ZeroOut();}
int hasProduct;
FinalProductStruct product;
int clamp;
FinalRgbFunctionStruct rgb;
FinalAlphaFunctionStruct alpha;
void Validate();
void Invoke();
};
#endif

View File

@@ -0,0 +1,334 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "rc1.0_general.h"
void GeneralCombinersStruct::Validate(int numConsts, ConstColorStruct *pcc)
{
GLint maxGCs;
if (SUPPORTS_GL_ATI_fragment_shader)
maxGCs = 8;
else
glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &maxGCs);
if (num > maxGCs)
{
char buffer[256];
sprintf(buffer, "%d general combiners specified, only %d supported", num, maxGCs);
errors.set(buffer);
num = maxGCs;
}
if (0 == num) {
// Setup a "fake" general combiner 0
general[0].ZeroOut();
num = 1;
}
localConsts = 0;
int i;
for (i = 0; i < num; i++)
localConsts += general[i].numConsts;
if (localConsts > 0)
if (NULL == glCombinerStageParameterfvNV)
errors.set("local constant(s) specified, but not supported -- ignored");
else
for (i = 0; i < num; i++)
general[i].SetUnusedLocalConsts(numConsts, pcc);
for (i = 0; i < num; i++)
general[i].Validate(i);
for (; i < maxGCs; i++)
general[i].ZeroOut();
}
void GeneralCombinersStruct::Invoke()
{
if (SUPPORTS_GL_NV_register_combiners)
glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, num);
int i;
for (i = 0; i < num; i++)
{
general[i].Invoke(i);
}
/*if (NULL != glCombinerStageParameterfvNV)
{
if (localConsts > 0)
glEnable(GL_PER_STAGE_CONSTANTS_NV);
else
glDisable(GL_PER_STAGE_CONSTANTS_NV);
}*/
}
void GeneralCombinerStruct::ZeroOut()
{
numPortions = 2;
numConsts = 0;
portion[0].ZeroOut();
portion[0].designator = RCP_RGB;
portion[1].ZeroOut();
portion[1].designator = RCP_ALPHA;
}
void GeneralCombinerStruct::SetUnusedLocalConsts(int numGlobalConsts, ConstColorStruct *globalCCs)
{
int i;
for (i = 0; i < numGlobalConsts; i++)
{
bool constUsed = false;
int j;
for (j = 0; j < numConsts; j++)
constUsed |= (cc[j].reg.bits.name == globalCCs[i].reg.bits.name);
if (!constUsed)
cc[numConsts++] = globalCCs[i];
}
}
void GeneralCombinerStruct::Validate(int stage)
{
if (2 == numConsts &&
cc[0].reg.bits.name == cc[1].reg.bits.name)
errors.set("local constant set twice");
switch (numPortions)
{
case 0:
portion[0].designator = RCP_RGB;
// Fallthru
case 1:
portion[1].designator = ((RCP_RGB == portion[0].designator) ? RCP_ALPHA : RCP_RGB);
// Fallthru
case 2:
if (portion[0].designator == portion[1].designator)
errors.set("portion declared twice");
break;
}
int i;
for (i = 0; i < numPortions; i++)
portion[i].Validate(stage);
for (; i < 2; i++)
portion[i].ZeroOut();
}
void GeneralCombinerStruct::Invoke(int stage)
{
int i;
if (NULL != glCombinerStageParameterfvNV)
{
for (i = 0; i < numConsts; i++)
{
SCGBindConst cg;
cg.m_nBindComponents = 1;
cg.m_Val[0] = cc[i].v[0];
cg.m_Val[1] = cc[i].v[1];
cg.m_Val[2] = cc[i].v[2];
cg.m_Val[3] = cc[i].v[3];
int nReg = cc[i].reg.bits.name - GL_CONSTANT_COLOR0_NV;
cg.m_dwBind = nReg + ((stage+1)<<28);
gParseConsts.AddElem(cg);
//glCombinerStageParameterfvNV(GL_COMBINER0_NV + stage, cc[i].reg.bits.name, &(cc[i].v[0]));
}
}
for (i = 0; i < 2; i++)
{
portion[i].Invoke(stage);
}
}
void GeneralPortionStruct::Validate(int stage)
{
gf.Validate(stage, designator);
}
void GeneralPortionStruct::Invoke(int stage)
{
gf.Invoke(stage, designator, bs);
}
void GeneralPortionStruct::ZeroOut()
{
gf.ZeroOut();
bs.word = RCP_SCALE_BY_ONE;
}
void GeneralFunctionStruct::ZeroOut()
{
// Create mapped registers for zero and discard
MappedRegisterStruct unsignedZero;
RegisterEnum zero;
zero.word = RCP_ZERO;
unsignedZero.Init(zero);
MappedRegisterStruct unsignedDiscard;
RegisterEnum discard;
discard.word = RCP_DISCARD;
unsignedDiscard.Init(discard);
numOps = 3;
op[0].op = RCP_MUL;
op[0].reg[0] = unsignedDiscard;
op[0].reg[1] = unsignedZero;
op[0].reg[2] = unsignedZero;
op[1].op = RCP_MUL;
op[1].reg[0] = unsignedDiscard;
op[1].reg[1] = unsignedZero;
op[1].reg[2] = unsignedZero;
op[2].op = RCP_SUM;
op[2].reg[0] = unsignedDiscard;
}
void GeneralFunctionStruct::Validate(int stage, int portion)
{
int i;
for (i = 0; i < numOps; i++)
op[i].Validate(stage, portion);
// Check if multiple ops are writing to same register (and it's not DISCARD)
if (numOps > 1 &&
op[0].reg[0].reg.bits.name == op[1].reg[0].reg.bits.name &&
GL_DISCARD_NV != op[0].reg[0].reg.bits.name)
errors.set("writing to same register twice");
if (numOps > 2 &&
(op[0].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name ||
op[1].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name) &&
GL_DISCARD_NV != op[2].reg[0].reg.bits.name)
errors.set("writing to same register twice");
// Set unused outputs to discard, unused inputs to zero/unsigned_identity
if (numOps < 2) {
// Set C input to zero
op[1].reg[1].reg.bits.name = GL_ZERO;
op[1].reg[1].map = GL_UNSIGNED_IDENTITY_NV;
op[1].reg[1].reg.bits.channel = portion;
// Set D input to zero
op[1].reg[2].reg.bits.name = GL_ZERO;
op[1].reg[2].map = GL_UNSIGNED_IDENTITY_NV;
op[1].reg[2].reg.bits.channel = portion;
// Discard CD output
op[1].op = false;
op[1].reg[0].reg.bits.name = GL_DISCARD_NV;
}
if (numOps < 3) {
// Discard muxSum output
op[2].reg[0].reg.bits.name = GL_DISCARD_NV;
op[2].op = RCP_SUM;
}
}
void GeneralFunctionStruct::Invoke(int stage, int portion, BiasScaleEnum bs)
{
GLenum portionEnum = (RCP_RGB == portion) ? GL_RGB : GL_ALPHA;
int chan = op[0].reg[1].reg.bits.channel;
if (chan == RCP_NONE)
chan = portion;
glCombinerInputNV(GL_COMBINER0_NV + stage,
portionEnum,
GL_VARIABLE_A_NV,
op[0].reg[1].reg.bits.name,
op[0].reg[1].map,
MAP_CHANNEL(chan));
chan = op[0].reg[2].reg.bits.channel;
if (chan == RCP_NONE)
chan = portion;
glCombinerInputNV(GL_COMBINER0_NV + stage,
portionEnum,
GL_VARIABLE_B_NV,
op[0].reg[2].reg.bits.name,
op[0].reg[2].map,
MAP_CHANNEL(chan));
chan = op[1].reg[1].reg.bits.channel;
if (chan == RCP_NONE)
chan = portion;
glCombinerInputNV(GL_COMBINER0_NV + stage,
portionEnum,
GL_VARIABLE_C_NV,
op[1].reg[1].reg.bits.name,
op[1].reg[1].map,
MAP_CHANNEL(chan));
chan = op[1].reg[2].reg.bits.channel;
if (chan == RCP_NONE)
chan = portion;
glCombinerInputNV(GL_COMBINER0_NV + stage,
portionEnum,
GL_VARIABLE_D_NV,
op[1].reg[2].reg.bits.name,
op[1].reg[2].map,
MAP_CHANNEL(chan));
glCombinerOutputNV(GL_COMBINER0_NV + stage,
portionEnum,
op[0].reg[0].reg.bits.name,
op[1].reg[0].reg.bits.name,
op[2].reg[0].reg.bits.name,
bs.bits.scale,
bs.bits.bias,
op[0].op,
op[1].op,
(op[2].op == RCP_MUX) ? true : false);
}
// This helper function assigns a channel to an undesignated input register
static void ConvertRegister(RegisterEnum& reg, int portion)
{
if (RCP_NONE == reg.bits.channel) {
reg.bits.channel = portion;
if (GL_FOG == reg.bits.name && RCP_ALPHA == portion)
// Special case where fog alpha is final only, but RGB is not
reg.bits.finalOnly = true;
}
}
void OpStruct::Validate(int stage, int portion)
{
int args = 1;
if (RCP_DOT == op || RCP_MUL == op)
args = 3;
else
args = 1;
if (reg[0].reg.bits.readOnly)
errors.set("writing to a read-only register");
if (RCP_ALPHA == portion &&
RCP_DOT == op)
errors.set("dot used in alpha portion");
int i;
for (i = 0; i < args; i++) {
ConvertRegister(reg[i].reg, portion);
if (reg[i].reg.bits.finalOnly)
errors.set("final register used in general combiner");
if (RCP_RGB == portion &&
RCP_BLUE == reg[i].reg.bits.channel)
errors.set("blue register usedin rgb portion");
if (RCP_ALPHA == portion &&
RCP_RGB == reg[i].reg.bits.channel)
errors.set("rgb register used in alpha portion");
if (i > 0 &&
GL_DISCARD_NV == reg[i].reg.bits.name)
errors.set("reading from discard");
}
}

View File

@@ -0,0 +1,107 @@
#ifndef _RC10_GENERAL_H
#define _RC10_GENERAL_H
#include "rc1.0_register.h"
#include "nvparse_errors.h"
#include "nvparse_externs.h"
enum {
RCP_MUL = 0,
RCP_DOT,
RCP_MUX,
RCP_SUM
};
class ConstColorStruct {
public:
void Init(RegisterEnum _reg, float _v0, float _v1, float _v2, float _v3)
{ reg = _reg; v[0] = _v0; v[1] = _v1; v[2] = _v2; v[3] = _v3; }
RegisterEnum reg;
float v[4];
};
class OpStruct {
public:
void Init(int _op, RegisterEnum _reg0, MappedRegisterStruct _reg1, MappedRegisterStruct _reg2)
{ op = _op; reg[0].reg = _reg0; reg[1] = _reg1; reg[2] = _reg2; }
void Init(int _op, RegisterEnum _reg0)
{ op = _op; reg[0].reg = _reg0; }
int op;
MappedRegisterStruct reg[3];
void Validate(int stage, int portion);
};
class GeneralFunctionStruct {
public:
void Init(OpStruct _op0, OpStruct _op1, OpStruct _op2) { op[0] = _op0; op[1] = _op1; op[2] = _op2; numOps = 3; }
void Init(OpStruct _op0, OpStruct _op1) { op[0] = _op0; op[1] = _op1; numOps = 2; }
void Init(OpStruct _op0) { op[0] = _op0; numOps = 1; }
void Validate(int stage, int portion);
void Invoke(int stage, int portion, BiasScaleEnum bs);
void ZeroOut();
int numOps;
OpStruct op[3];
};
class GeneralPortionStruct {
public:
void Init(int _designator, GeneralFunctionStruct _gf, BiasScaleEnum _bs)
{ designator = _designator; gf = _gf; bs = _bs; }
void Validate(int stage);
void Invoke(int stage);
void ZeroOut();
int designator;
GeneralFunctionStruct gf;
BiasScaleEnum bs;
};
class GeneralCombinerStruct {
public:
void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0, ConstColorStruct _cc1)
{ portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; }
void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0)
{ portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; numConsts = 1; }
void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1)
{ portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; numConsts = 0; }
void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0, ConstColorStruct _cc1)
{ portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; }
void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0)
{ portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; numConsts = 1; }
void Init(GeneralPortionStruct _portion0)
{ portion[0] = _portion0; numPortions = 1; numConsts = 0; }
void Validate(int stage);
void SetUnusedLocalConsts(int numGlobalConsts, ConstColorStruct *globalCCs);
void Invoke(int stage);
void ZeroOut();
GeneralPortionStruct portion[2];
int numPortions;
ConstColorStruct cc[2];
int numConsts;
};
class GeneralCombinersStruct {
public:
void Init() {num = 0;}
void Init(GeneralCombinerStruct _gc) { num = 1; general[0] = _gc; }
GeneralCombinersStruct& operator+=(GeneralCombinerStruct& _gc)
{
if (num < RCP_NUM_GENERAL_COMBINERS)
general[num++] = _gc;
else
errors.set("Too many general combiners.");
return *this;
}
void Validate(int numConsts, ConstColorStruct *cc);
void Invoke();
GeneralCombinerStruct general[RCP_NUM_GENERAL_COMBINERS];
int num;
private:
int localConsts;
};
#endif

View File

@@ -0,0 +1,206 @@
#ifndef _RC10_REGISTER_H
#define _RC10_REGISTER_H
#ifdef _WIN32
# include <windows.h>
# define BYTE_ORDER !BIG_ENDIAN
#endif
#include <stdlib.h>
#define RCP_NUM_GENERAL_COMBINERS 8
#define RCP_RGB 0
#define RCP_ALPHA 1
#define RCP_BLUE 2
#define RCP_NONE 3
typedef union _RegisterEnum {
struct {
#if BYTE_ORDER != BIG_ENDIAN
unsigned int name :16; // OpenGL enum for register
unsigned int channel : 2; // RCP_RGB, RCP_ALPHA, etc
unsigned int readOnly : 1; // true or false
unsigned int finalOnly : 1; // true or false
unsigned int unused :12;
#else
unsigned int unused :12;
unsigned int finalOnly : 1; // true or false
unsigned int readOnly : 1; // true or false
unsigned int channel : 2; // RCP_RGB, RCP_ALPHA, RCP_BLUE, RCP_NONE
unsigned int name :16; // OpenGL enum for register
#endif
} bits;
unsigned int word;
} RegisterEnum;
// No need for writeOnly flag, since DISCARD is the only register in that category
// WARNING: Don't monkey with the above structure or this macro
// unless you're absolutely sure of what you're doing!
// This constant allocation makes validation *much* cleaner.
#define RCP_SET_REGISTER_ENUM(name, channel, readonly, finalonly) \
((finalonly << 19) | (readonly << 18) | (channel << 16) | name)
#define RCP_FOG_RGB RCP_SET_REGISTER_ENUM(GL_FOG, RCP_RGB, 1, 0)
#define RCP_FOG_ALPHA RCP_SET_REGISTER_ENUM(GL_FOG, RCP_ALPHA, 1, 1)
#define RCP_FOG_BLUE RCP_SET_REGISTER_ENUM(GL_FOG, RCP_BLUE, 1, 0)
#define RCP_FOG RCP_SET_REGISTER_ENUM(GL_FOG, RCP_NONE, 1, 0)
#define RCP_PRIMARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_RGB, 0, 0)
#define RCP_PRIMARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_ALPHA, 0, 0)
#define RCP_PRIMARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_BLUE, 0, 0)
#define RCP_PRIMARY_COLOR RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_NONE, 0, 0)
#define RCP_SECONDARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_RGB, 0, 0)
#define RCP_SECONDARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_ALPHA, 0, 0)
#define RCP_SECONDARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_BLUE, 0, 0)
#define RCP_SECONDARY_COLOR RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_NONE, 0, 0)
#define RCP_SPARE0_RGB RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_RGB, 0, 0)
#define RCP_SPARE0_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_ALPHA, 0, 0)
#define RCP_SPARE0_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_BLUE, 0, 0)
#define RCP_SPARE0 RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_NONE, 0, 0)
#define RCP_SPARE1_RGB RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_RGB, 0, 0)
#define RCP_SPARE1_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_ALPHA, 0, 0)
#define RCP_SPARE1_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_BLUE, 0, 0)
#define RCP_SPARE1 RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_NONE, 0, 0)
#define RCP_TEXTURE0_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_RGB, 0, 0)
#define RCP_TEXTURE0_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_ALPHA, 0, 0)
#define RCP_TEXTURE0_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_BLUE, 0, 0)
#define RCP_TEXTURE0 RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_NONE, 0, 0)
#define RCP_TEXTURE1_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_RGB, 0, 0)
#define RCP_TEXTURE1_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_ALPHA, 0, 0)
#define RCP_TEXTURE1_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_BLUE, 0, 0)
#define RCP_TEXTURE1 RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_NONE, 0, 0)
#define RCP_TEXTURE2_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_RGB, 0, 0)
#define RCP_TEXTURE2_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_ALPHA, 0, 0)
#define RCP_TEXTURE2_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_BLUE, 0, 0)
#define RCP_TEXTURE2 RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_NONE, 0, 0)
#define RCP_TEXTURE3_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_RGB, 0, 0)
#define RCP_TEXTURE3_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_ALPHA, 0, 0)
#define RCP_TEXTURE3_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_BLUE, 0, 0)
#define RCP_TEXTURE3 RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_NONE, 0, 0)
#define RCP_CONST_COLOR0_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_RGB, 1, 0)
#define RCP_CONST_COLOR0_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_ALPHA, 1, 0)
#define RCP_CONST_COLOR0_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_BLUE, 1, 0)
#define RCP_CONST_COLOR0 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_NONE, 1, 0)
#define RCP_CONST_COLOR1_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_RGB, 1, 0)
#define RCP_CONST_COLOR1_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_ALPHA, 1, 0)
#define RCP_CONST_COLOR1_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_BLUE, 1, 0)
#define RCP_CONST_COLOR1 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_NONE, 1, 0)
#define RCP_ZERO_RGB RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_RGB, 1, 0)
#define RCP_ZERO_ALPHA RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_ALPHA, 1, 0)
#define RCP_ZERO_BLUE RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_BLUE, 1, 0)
#define RCP_ZERO RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_NONE, 1, 0)
#define RCP_ONE_RGB RCP_SET_REGISTER_ENUM(GL_ONE, RCP_RGB, 1, 0)
#define RCP_ONE_ALPHA RCP_SET_REGISTER_ENUM(GL_ONE, RCP_ALPHA, 1, 0)
#define RCP_ONE_BLUE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_BLUE, 1, 0)
#define RCP_ONE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_NONE, 1, 0)
#define RCP_DISCARD RCP_SET_REGISTER_ENUM(GL_DISCARD_NV, RCP_NONE, 0, 0)
#define RCP_FINAL_PRODUCT RCP_SET_REGISTER_ENUM(GL_E_TIMES_F_NV, RCP_NONE, 1, 1)
#define RCP_COLOR_SUM RCP_SET_REGISTER_ENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV, RCP_NONE, 1, 1)
#define MAP_CHANNEL(channel) ((RCP_RGB == (channel)) ? GL_RGB : (RCP_ALPHA == (channel) ? GL_ALPHA : GL_BLUE))
typedef union _BiasScaleEnum {
struct {
#if BYTE_ORDER != BIG_ENDIAN
unsigned int bias :16; // OpenGL enum for bias
unsigned int scale :16; // OpenGL enum for scale
#else
unsigned int scale :16; // OpenGL enum for scale
unsigned int bias :16; // OpenGL enum for bias
#endif
} bits;
unsigned int word;
} BiasScaleEnum;
// WARNING: Don't monkey with the above structure or this macro
// unless you're absolutely sure of what you're doing!
// This constant allocation makes validation *much* cleaner.
#define RCP_SET_BIAS_SCALE_ENUM(bias, scale) ((scale << 16) | bias)
#define RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_SCALE_BY_TWO_NV)
#define RCP_BIAS_BY_NEGATIVE_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_NONE)
#define RCP_SCALE_BY_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_ONE_HALF_NV)
#define RCP_SCALE_BY_ONE RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_NONE)
#define RCP_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_TWO_NV)
#define RCP_SCALE_BY_FOUR RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_FOUR_NV)
class MappedRegisterStruct {
public:
void Init(RegisterEnum _reg, int _map = GL_UNSIGNED_IDENTITY_NV)
{
if (RCP_ONE == _reg.bits.name) {
_reg.bits.name = RCP_ZERO;
switch (_map) {
case GL_UNSIGNED_IDENTITY_NV:
_map = GL_UNSIGNED_INVERT_NV;
break;
case GL_UNSIGNED_INVERT_NV:
_map = GL_UNSIGNED_IDENTITY_NV;
break;
case GL_EXPAND_NORMAL_NV:
_map = GL_UNSIGNED_INVERT_NV;
break;
case GL_EXPAND_NEGATE_NV:
_map = GL_EXPAND_NORMAL_NV;
break;
case GL_HALF_BIAS_NORMAL_NV:
_map = GL_HALF_BIAS_NEGATE_NV;
break;
case GL_HALF_BIAS_NEGATE_NV:
_map = GL_HALF_BIAS_NORMAL_NV;
break;
case GL_SIGNED_IDENTITY_NV:
_map = GL_UNSIGNED_INVERT_NV;
break;
case GL_SIGNED_NEGATE_NV:
_map = GL_EXPAND_NORMAL_NV;
break;
}
}
map = _map;
reg = _reg;
}
int map;
RegisterEnum reg;
};
#ifdef TEST_BIT_FIELDS
class RegisterEnumTest {
public:
RegisterEnumTest()
{
RegisterEnum reg;
bool error = false;
if (sizeof(reg.bits) != sizeof(reg.word))
error = true;
reg.word = 0; reg.bits.name = 0xFFFF;
if (RCP_SET_REGISTER_ENUM(0xFFFF, 0, 0, 0) != reg.word)
error = true;
reg.word = 0; reg.bits.channel = 3;
if (RCP_SET_REGISTER_ENUM(0, 3, 0, 0) != reg.word)
error = true;
reg.word = 0; reg.bits.readOnly = true;
if (RCP_SET_REGISTER_ENUM(0, 0, 1, 0) != reg.word)
error = true;
reg.word = 0; reg.bits.finalOnly = true;
if (RCP_SET_REGISTER_ENUM(0, 0, 0, 1) != reg.word)
error = true;
if (error) {
fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n");
exit(1);
}
}
};
static RegisterEnumTest registerEnumTest;
#endif
#endif

View File

@@ -0,0 +1,311 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "ts1.0_inst.h"
Inst::Inst(int inst, float arg0, float arg1, float arg2, float arg3, float arg4, float arg5, float arg6)
{
opcode.word = inst;
expand = 0;
args[0] = arg0;
args[1] = arg1;
args[2] = arg2;
args[3] = arg3;
args[4] = arg4;
args[5] = arg5;
args[6] = arg6;
}
Inst::Inst(int inst, MappedVariablePtr arg0, float arg1, float arg2, float arg3, float arg4, float arg5, float arg6)
{
opcode.word = inst;
expand = arg0->expand;
args[0] = arg0->var;
args[1] = arg1;
args[2] = arg2;
args[3] = arg3;
args[4] = arg4;
args[5] = arg5;
args[6] = arg6;
}
void Inst::Invoke()
{
switch(opcode.word) {
case TSP_NOP:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
break;
case TSP_TEXTURE_1D:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_1D);
break;
case TSP_TEXTURE_2D:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
break;
case TSP_TEXTURE_RECTANGLE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_RECTANGLE_NV);
break;
case TSP_TEXTURE_3D:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
break;
case TSP_TEXTURE_CUBE_MAP:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
break;
case TSP_CULL_FRAGMENT:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV, &args[0]);
break;
case TSP_PASS_THROUGH:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV);
break;
case TSP_OFFSET_2D_SCALE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]);
break;
case TSP_OFFSET_PROJECTIVE_2D_SCALE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]);
break;
case TSP_OFFSET_2D:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
break;
case TSP_OFFSET_PROJECTIVE_2D:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
break;
case TSP_OFFSET_RECTANGLE_SCALE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]);
break;
case TSP_OFFSET_PROJECTIVE_RECTANGLE_SCALE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]);
glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]);
break;
case TSP_OFFSET_RECTANGLE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
break;
case TSP_OFFSET_PROJECTIVE_RECTANGLE:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]);
break;
case TSP_DEPENDENT_AR:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DEPENDENT_GB:
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_2D_1_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_2D_2_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_RECTANGLE_1_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_RECTANGLE_2_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_3D_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_3D_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_3D_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
break;
case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3:
if (expand)
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
else
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV);
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]);
break;
}
}

View File

@@ -0,0 +1,146 @@
#ifndef _INST_H
#define _INST_H
#define TSP_MAX_ARGS 7
#define TSP_NUM_TEXTURE_UNITS 4
#ifdef _WIN32
# define BYTE_ORDER !BIG_ENDIAN
#endif
#include <stdlib.h>
typedef union _InstructionEnum {
struct {
#if BYTE_ORDER != BIG_ENDIAN
unsigned int instruction :10; // instruction id
unsigned int stage : 4; // stage number
unsigned int dependent : 1; // dependent operation
unsigned int noOutput : 1; // no RGBA output
#else
unsigned int noOutput : 1;
unsigned int dependent : 1;
unsigned int stage : 4;
unsigned int instruction :10;
#endif
} bits;
unsigned int word;
} InstructionEnum;
// WARNING: Don't monkey with the above structure or this macro
// unless you're absolutely sure of what you're doing!
// This constant allocation makes validation *much* cleaner.
#define TSP_SET_INSTRUCTION_ENUM(inst, st, dep, noout) \
((noout << 15) | (dep << 14) | (st << 10) | inst)
#define TSP_NOP TSP_SET_INSTRUCTION_ENUM(0, 0, 0, 1)
#define TSP_TEXTURE_1D TSP_SET_INSTRUCTION_ENUM(1, 0, 0, 0)
#define TSP_TEXTURE_2D TSP_SET_INSTRUCTION_ENUM(2, 0, 0, 0)
#define TSP_TEXTURE_RECTANGLE TSP_SET_INSTRUCTION_ENUM(3, 0, 0, 0)
#define TSP_TEXTURE_3D TSP_SET_INSTRUCTION_ENUM(4, 0, 0, 0)
#define TSP_TEXTURE_CUBE_MAP TSP_SET_INSTRUCTION_ENUM(5, 0, 0, 0)
#define TSP_CULL_FRAGMENT TSP_SET_INSTRUCTION_ENUM(6, 0, 0, 1)
#define TSP_PASS_THROUGH TSP_SET_INSTRUCTION_ENUM(7, 0, 0, 0)
#define TSP_DEPENDENT_AR TSP_SET_INSTRUCTION_ENUM(8, 0, 1, 0)
#define TSP_DEPENDENT_GB TSP_SET_INSTRUCTION_ENUM(9, 0, 1, 0)
#define TSP_OFFSET_2D TSP_SET_INSTRUCTION_ENUM(10, 0, 1, 0)
#define TSP_OFFSET_2D_SCALE TSP_SET_INSTRUCTION_ENUM(11, 0, 1, 0)
#define TSP_OFFSET_RECTANGLE TSP_SET_INSTRUCTION_ENUM(12, 0, 1, 0)
#define TSP_OFFSET_RECTANGLE_SCALE TSP_SET_INSTRUCTION_ENUM(13, 0, 1, 0)
#define TSP_DOT_PRODUCT_2D_1_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 0, 1, 1)
#define TSP_DOT_PRODUCT_2D_2_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 1, 1, 0)
#define TSP_DOT_PRODUCT_RECTANGLE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 0, 1, 1)
#define TSP_DOT_PRODUCT_RECTANGLE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 1, 1, 0)
#define TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 0, 1, 1)
#define TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 1, 1, 0)
#define TSP_DOT_PRODUCT_3D_1_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 0, 1, 1)
#define TSP_DOT_PRODUCT_3D_2_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 1, 1, 1)
#define TSP_DOT_PRODUCT_3D_3_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 2, 1, 0)
#define TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 0, 1, 1)
#define TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 1, 1, 1)
#define TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 2, 1, 0)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 0, 1, 1)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 1, 1, 1)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 2, 1, 0)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 0, 1, 1)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 1, 1, 1)
#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 2, 1, 0)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 0, 1, 1)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 1, 1, 0)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 2, 1, 0)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 0, 1, 1)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 1, 1, 0)
#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 2, 1, 0)
#define TSP_OFFSET_PROJECTIVE_2D TSP_SET_INSTRUCTION_ENUM(23, 0, 1, 0)
#define TSP_OFFSET_PROJECTIVE_2D_SCALE TSP_SET_INSTRUCTION_ENUM(24, 0, 1, 0)
#define TSP_OFFSET_PROJECTIVE_RECTANGLE TSP_SET_INSTRUCTION_ENUM(25, 0, 1, 0)
#define TSP_OFFSET_PROJECTIVE_RECTANGLE_SCALE TSP_SET_INSTRUCTION_ENUM(26, 0, 1, 0)
typedef struct _MappedVariable {
float var;
int expand;
} MappedVariable, *MappedVariablePtr;
typedef class Inst {
public:
Inst(int inst, float arg0 = 0., float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.);
Inst(int inst, MappedVariablePtr arg0, float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.);
void Invoke();
InstructionEnum opcode;
float args[TSP_MAX_ARGS];
private:
int expand;
} *InstPtr;
#ifdef TEST_BIT_FIELDS
#include <stdio.h>
class InstructionEnumTest {
public:
InstructionEnumTest()
{
InstructionEnum inst;
bool error = false;
if (sizeof(inst.bits) != sizeof(inst.word))
error = true;
inst.word = 0; inst.bits.instruction = 0x3FF;
if (TSP_SET_INSTRUCTION_ENUM(0x3FF, 0, 0, 0) != inst.word)
error = true;
inst.word = 0; inst.bits.stage = 0x0F;
if (TSP_SET_INSTRUCTION_ENUM(0, 0x0F, 0, 0) != inst.word)
error = true;
inst.word = 0; inst.bits.dependent = true;
if (TSP_SET_INSTRUCTION_ENUM(0, 0, 1, 0) != inst.word)
error = true;
inst.word = 0; inst.bits.noOutput = true;
if (TSP_SET_INSTRUCTION_ENUM(0, 0, 0, 1) != inst.word)
error = true;
if (error) {
fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n");
_asm {int 3}
exit(1);
}
}
};
static InstructionEnumTest instructionEnumTest;
#endif /* TEST_BIT_FIELDS */
#endif

View File

@@ -0,0 +1,103 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "ts1.0_inst_list.h"
const int instListInc = 4;
InstList::InstList()
{
size = 0;
max = instListInc;
list = (InstPtr)malloc(sizeof(Inst) * max);
}
InstList::~InstList()
{
free(list);
}
int InstList::Size()
{
return size;
}
InstList& InstList::operator+=(InstPtr t)
{
if (size == max) {
/* Extend list size by instListInc amount */
max += instListInc;
list = (InstPtr)realloc(list, sizeof(Inst) * max);
}
list[size++] = *t;
return *this;
}
void InstList::Invoke()
{
int i;
for (i = 0; i < size; i++) {
// set active texture
glActiveTextureARB(GL_TEXTURE0_ARB + i);
list[i].Invoke();
}
// Reset active texture to unit 0
// Could do a glGet to figure out what the initial active texunit was,
// and reset to that, but the glGet would not behave well within
// a display list...
glActiveTextureARB(GL_TEXTURE0_ARB);
}
void InstList::Validate()
{
if (size > TSP_NUM_TEXTURE_UNITS)
errors.set("too many instructions");
int i;
for (i = 0; i < size; i++) {
int stage = list[i].opcode.bits.stage;
if (stage > i)
errors.set("prior stage missing");
if (list[i].opcode.bits.instruction != list[i - stage].opcode.bits.instruction)
errors.set("stage mismatch");
if (list[i].opcode.bits.dependent) {
int previousTexture = (int)list[i].args[0];
if (previousTexture >= i - stage)
errors.set("invalid texture reference");
if (list[previousTexture].opcode.bits.noOutput)
errors.set("no output on referenced texture");
}
}
// Assign remaining undesignated texture units to nop
for (; i < TSP_NUM_TEXTURE_UNITS; i++) {
InstPtr nopInst = new Inst(TSP_NOP);
*this += nopInst;
delete nopInst;
}
}
bool is_ts10(const char * s)
{
return ! strncmp(s, "!!TS1.0", 7);
}
bool ts10_init_more()
{
static bool tsinit = false;
if (tsinit == false )
{
if(!SUPPORTS_GL_NV_texture_shader || !SUPPORTS_GL_ARB_multitexture)
{
errors.set("unable to initialize GL_NV_texture_shader\n");
return false;
}
else
{
tsinit = true;
}
}
errors.reset();
line_number = 1;
return true;
}

View File

@@ -0,0 +1,20 @@
#ifndef _InstList_h
#define _InstList_h
#include "ts1.0_inst.h"
typedef class InstList {
public:
InstList();
~InstList();
int Size();
InstList& operator+=(InstPtr t);
void Validate();
void Invoke();
private:
InstPtr list;
int size;
int max;
} *InstListPtr;
#endif

View File

@@ -0,0 +1,5 @@
// to make flex and vc++ play nice together
#ifndef _WIN32
#error
//this thing was getting me for hours! "why can't I close the bloody file!"
#endif

View File

@@ -0,0 +1,341 @@
#include "RenderPCH.h"
#include "nvparse.h"
namespace
{
void ParseVertexProgramConstants( GLenum target, char *instring);
GLuint LookupTrackMatrix(char *matrixName);
GLuint LookupTrackMatrixTransform(char *matrixTransformName);
}
bool is_vcp10(const char * s)
{
return ! strncmp(s, "!!VCP1.0", 8);
}
bool vcp10_init(char * s)
{
static int vpinit = 0;
if (vpinit == 0 )
{
if(!SUPPORTS_GL_NV_vertex_program)
{
errors.set("unable to initialize GL_NV_vertex_program");
return false;
}
else
{
vpinit = 1;
}
}
errors.reset();
line_number = 1;
myin = s;
return true;
}
int vcp10_parse()
{
// parse the constant declarations, setting their values in the GL.
ParseVertexProgramConstants( GL_VERTEX_PROGRAM_NV, myin);
return 0;
}
namespace
{
//.----------------------------------------------------------------------------.
//| Function : ParseVertexProgramConstants |
//| Description: Parse and set VP1.0 constant memory based on const |
//| directives. |
//| |
//| Format : constXX = (x, y, z, w); # where XXX is an integer 0-95. |
//| : constXX = TRACK(matrix, transform); # track a matrix |
//.----------------------------------------------------------------------------.
void ParseVertexProgramConstants(GLenum target, char *instring)
{
// don't overwrite the original string.
char *tmpstring = new char[strlen(instring)+1];
strcpy(tmpstring, instring);
char lineSeparator[] = "\n";
char wordSeparator[] = " \t";
char error[256];
char dummy[256];
char *token;
//iterate over the lines in the string
token = strtok(tmpstring, lineSeparator);
// we assume the first line is the "!!VP1.0 line".
if (token != NULL)
{
token = strtok(NULL, lineSeparator);
}
int iLineCount = 1; // skip first line
while (token != NULL)
{
iLineCount++;
// if the first non-whitespace character is a #, this is a comment. Skip.
if (!sscanf(token, " #%s", dummy))
{ // not a comment. Is it a constant?
// strip whitespace from the beginning of the string
int i;
for (i = 0; i < (int)strlen(token) && isspace(token[i]); i++);
token += i;
if (strlen(token) > 0 && // this is not a blank line and
!strnicmp(token, "c[", 2)) // the first word is of the form "c[xx]", so its a constant.
{
int iConstID;
int iNumValuesAssigned;
char c[6];
iNumValuesAssigned = sscanf(token, " %c [ %d ] = %s ", &c[0], &iConstID, dummy);
if (3 != iNumValuesAssigned || toupper(c[0]) != 'C')
{ // error in constant directive.
sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
errors.set(error);
}
else if (!strnicmp(dummy, "track", 5))
{ // this is a TrackMatrix directive
char matrixName[256], matrixTransformName[256];
// the series of %c's are to make sure "track(" doesn't get glommed onto the matrixName
iNumValuesAssigned = sscanf(token,
" %c [ %d ] = %c%c%c%c%c ( %s %s ) ;",
&c[0], &iConstID, &c[1], &c[2], &c[3], &c[4], &c[5],
matrixName, matrixTransformName);
if (iNumValuesAssigned < 8)
{
sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
errors.set(error);
}
else
{
char *buffer;
if (9 == iNumValuesAssigned)
{
// just need to remove any junk from the matrix names and IDs.
if (buffer = strstr(matrixName, ","))
buffer[0] = 0;
if (buffer = strstr(matrixTransformName, ")"))
buffer[0] = 0;
}
else // 8 == iNumValuesAssigned
{
// have to split the two names, since they both were put into the matrixName
if (buffer = strstr(matrixName, ","))
{
strcpy(matrixTransformName, buffer + 1);
buffer[0] = 0;
// get rid of paren at end of transform name, if it is there
if (buffer = strstr(matrixTransformName, ")"))
{
buffer[0] = 0;
}
}
else
{
sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
errors.set(error);
}
}
// constant ID must be modulo 4.
if (0 != (iConstID % 4))
{
sprintf(error,
"error at line %d \n\"%s\"\n\tglTrackMatrixNV address must be modulo 4\n",
iLineCount, token);
errors.set(error);
}
else if (iConstID < 0 || iConstID > 95)
{
sprintf(error,
"error at line %d \n\"%s\"\n\tConstant address out of range\n",
iLineCount, token);
errors.set(error);
}
else
{
// get the enum values for the specified matrices
GLuint iMatrixID = LookupTrackMatrix(matrixName);
GLuint iTransformID = LookupTrackMatrixTransform(matrixTransformName);
if (0 == iMatrixID)
{
sprintf(error,
"error at line %d \n\"%s\"\n\tInvalid Matrix parameter in glTrackMatrixNV.\n",
iLineCount, token);
errors.set(error);
}
else if (0 == iTransformID)
{
sprintf(error,
"error at line %d \n\"%s\"\n\tInvalid Transform parameter in glTrackMatrixNV\n",
iLineCount, token);
errors.set(error);
}
else
{
// untrack any currently tracked matrix
glTrackMatrixNV(target, iConstID, GL_NONE, GL_IDENTITY_NV);
// tell GL the matrix to track
glTrackMatrixNV(target, iConstID, iMatrixID, iTransformID);
}
}
}
}
else // this is a constant directive
{
float xyzw[4] = {0, 0, 0, 0};
iNumValuesAssigned = sscanf(token,
" %c [ %d ] = ( %f , %f , %f , %f ) ; ",
&c, &iConstID, xyzw, xyzw + 1, xyzw + 2, xyzw + 3);
if (6 != iNumValuesAssigned)
{ // error in constant directive.
sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
errors.set(error);
}
else if (iConstID < 0 || iConstID > 95)
{
sprintf(error,
"error at line %d \n\"%s\"\n\tConstant address out of range\n",
iLineCount, token);
errors.set(error);
}
else
{
// Always set the closest matrix location to tracking NONE to avoid errors!
glTrackMatrixNV(target, iConstID - (iConstID % 4), GL_NONE, GL_IDENTITY_NV);
// tell GL the constant values
glProgramParameter4fvNV(target, iConstID, xyzw);
}
}
}
}
// get the next line
token = strtok(NULL, lineSeparator);
}
}
struct MatrixLookupEntry
{
string name;
GLuint ID;
};
//.----------------------------------------------------------------------------.
//| Function : LookupTrackMatrix |
//| Description: Returns the enumerated matrix name given a valid string |
//| or 0 if an unknown matrix is requested. |
//.----------------------------------------------------------------------------.
GLuint LookupTrackMatrix(char *matrixName)
{
static bool bFirstTime = true;
static int iNumEntries = 14;
static MatrixLookupEntry* matrixLookupTable = new MatrixLookupEntry[iNumEntries];
if (bFirstTime) // build the lookup table
{
matrixLookupTable[0].name = "GL_NONE";
matrixLookupTable[0].ID = GL_NONE;
matrixLookupTable[1].name = "GL_MODELVIEW";
matrixLookupTable[1].ID = GL_MODELVIEW;
matrixLookupTable[2].name = "GL_PROJECTION";
matrixLookupTable[2].ID = GL_PROJECTION;
matrixLookupTable[3].name = "GL_TEXTURE";
matrixLookupTable[3].ID = GL_TEXTURE;
matrixLookupTable[4].name = "GL_COLOR";
matrixLookupTable[4].ID = GL_COLOR;
matrixLookupTable[5].name = "GL_MODELVIEW_PROJECTION_NV";
matrixLookupTable[5].ID = GL_MODELVIEW_PROJECTION_NV;
matrixLookupTable[6].name = "GL_MATRIX0_NV";
matrixLookupTable[6].ID = GL_MATRIX0_NV;
matrixLookupTable[7].name = "GL_MATRIX1_NV";
matrixLookupTable[7].ID = GL_MATRIX1_NV;
matrixLookupTable[8].name = "GL_MATRIX2_NV";
matrixLookupTable[8].ID = GL_MATRIX2_NV;
matrixLookupTable[9].name = "GL_MATRIX3_NV";
matrixLookupTable[9].ID = GL_MATRIX3_NV;
matrixLookupTable[10].name = "GL_MATRIX4_NV";
matrixLookupTable[10].ID = GL_MATRIX4_NV;
matrixLookupTable[11].name = "GL_MATRIX5_NV";
matrixLookupTable[11].ID = GL_MATRIX5_NV;
matrixLookupTable[12].name = "GL_MATRIX6_NV";
matrixLookupTable[12].ID = GL_MATRIX6_NV;
matrixLookupTable[13].name = "GL_MATRIX7_NV";
matrixLookupTable[13].ID = GL_MATRIX7_NV;
bFirstTime = false;
}
for (int i = 0; i < iNumEntries; i++)
{
if (!strcmp(matrixName, matrixLookupTable[i].name.c_str()))
{
return matrixLookupTable[i].ID;
}
}
return 0;
}
//.----------------------------------------------------------------------------.
//| Function : LookupTrackMatrixTransform |
//| Description: Returns the enumerated matrix transform name given a valid |
//| string name or 0 if an unknown transform is requested. |
//.----------------------------------------------------------------------------.
GLuint LookupTrackMatrixTransform(char *matrixTransformName)
{
static bool bFirstTime = true;
static int iNumEntries = 4;
static MatrixLookupEntry* transformLookupTable = new MatrixLookupEntry[iNumEntries];
if (bFirstTime)
{
transformLookupTable[0].name = "GL_IDENTITY_NV";
transformLookupTable[0].ID = GL_IDENTITY_NV;
transformLookupTable[1].name = "GL_INVERSE_NV";
transformLookupTable[1].ID = GL_INVERSE_NV;
transformLookupTable[2].name = "GL_TRANSPOSE_NV";
transformLookupTable[2].ID = GL_TRANSPOSE_NV;
transformLookupTable[3].name = "GL_INVERSE_TRANSPOSE_NV";
transformLookupTable[3].ID = GL_INVERSE_TRANSPOSE_NV;
bFirstTime = false;
}
for (int i = 0; i < iNumEntries; i++)
{
if (!strcmp( matrixTransformName, transformLookupTable[i].name.c_str()))
{
return transformLookupTable[i].ID;
}
}
return 0;
}
}

View File

@@ -0,0 +1,163 @@
#include "RenderPCH.h"
#include "nvparse.h"
//using namespace std;
namespace
{
void LoadProgram( GLenum target, GLuint id, char *instring );
void StrToUpper(char * string);
int vpid;
}
bool is_vp10(const char * s)
{
return ! strncmp(s, "!!VP1.0", 7);
}
bool vp10_init(char * s)
{
static bool vpinit = false;
if (vpinit == false )
{
if(!SUPPORTS_GL_NV_vertex_program)
{
errors.set("unable to initialize GL_NV_vertex_program");
return false;
}
else
{
vpinit = true;
}
}
errors.reset();
line_number = 1;
myin = s;
glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid );
if ( vpid == 0 )
{
char str[128];
sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", vpid );
errors.set( str );
return false;
}
return true;
}
int vp10_parse()
{
LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, myin );
return 0;
}
namespace
{
//.----------------------------------------------------------------------------.
//| Function : LoadProgram |
//| Description: Load a program into GL, and report any errors encountered. |
//.----------------------------------------------------------------------------.
void LoadProgram( GLenum target, GLuint id, char *instring )
{
GLint errPos;
GLenum errCode;
const GLubyte *errString;
int len = strlen(instring);
glLoadProgramNV( target, id, len, (const GLubyte *) instring );
if ( (errCode = glGetError()) != GL_NO_ERROR )
{
errString = gluErrorString( errCode );
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos );
int nlines = 1;
int nchar = 1;
int i;
for ( i = 0; i < errPos; i++ )
{
if ( instring[i] == '\n' )
{
nlines++;
nchar = 1;
}
else
{
nchar++;
}
}
int start;
int end;
int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0;
for ( i = errPos; i >= 0; i-- )
{
start = i;
if ( flag && (start >= errPos-1) )
continue;
if ( instring[i] == ';' )
{
if ( !flag )
{
start = i+1;
if ( instring[start] == '\n' )
start++;
}
break;
}
}
for ( i = errPos; i < len; i++ )
{
end = i;
if ( instring[i] == ';' && end > start)
{
break;
}
}
if ( errPos - start > 30 )
{
start = errPos - 30;
}
if ( end - errPos > 30 )
{
end = errPos + 30;
}
char substring[96];
memset( substring, 0, 96 );
strncpy( substring, &(instring[start]), end-start+1 );
char str[256];
//sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring );
sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring );
int width = errPos-start;
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "|\n" );
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "^\n" );
errors.set( str );
}
}
//.----------------------------------------------------------------------------.
//| Function : StrToUpper |
//| Description: Converts all lowercase chars in a string to uppercase. |
//.----------------------------------------------------------------------------.
void StrToUpper(char *string)
{
for (unsigned int i = 0; i < strlen(string); i++)
string[i] = toupper(string[i]);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
#ifndef _VS10INST_H
#define _VS10INST_H
#define VS10_ADD 1
#define VS10_DP3 2
#define VS10_DP4 3
#define VS10_DST 4
#define VS10_EXP 5
#define VS10_EXPP 6
#define VS10_FRC 7
#define VS10_LIT 8
#define VS10_LOG 9
#define VS10_LOGP 10
#define VS10_M3X2 11
#define VS10_M3X3 12
#define VS10_M3X4 13
#define VS10_M4X3 14
#define VS10_M4X4 15
#define VS10_MAD 16
#define VS10_MAX 17
#define VS10_MIN 18
#define VS10_MOV 19
#define VS10_MUL 20
#define VS10_NOP 21
#define VS10_RCP 22
#define VS10_RSQ 23
#define VS10_SGE 24
#define VS10_SLT 25
#define VS10_SUB 26
#define VS10_COMMENT 27
#define VS10_HEADER 28
#define TYPE_TEMPORARY_REG 1
#define TYPE_VERTEX_ATTRIB_REG 2
#define TYPE_ADDRESS_REG 3
#define TYPE_CONSTANT_MEM_REG 4
#define TYPE_CONSTANT_A0_REG 5
#define TYPE_CONSTANT_A0_OFFSET_REG 6
#define TYPE_POSITION_RESULT_REG 7
#define TYPE_COLOR_RESULT_REG 8
#define TYPE_TEXTURE_RESULT_REG 9
#define TYPE_FOG_RESULT_REG 10
#define TYPE_POINTS_RESULT_REG 11
class VS10Reg {
public:
// VS10Reg();
// VS10Reg(const VS10Reg &r);
// VS10Reg& operator=(const VS10Reg &r);
void Init();
void Translate();
int type;
int index;
int sign;
char mask[4];
int ValidateIndex();
};
typedef class VS10Inst {
public:
~VS10Inst();
VS10Inst();
VS10Inst(int currline);
VS10Inst(const VS10Inst &inst);
VS10Inst& operator=(const VS10Inst &inst);
VS10Inst(int currline, int inst);
VS10Inst(int currline, int inst, char *cmt);
VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0);
VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1);
VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2);
void Validate( int &vsflag );
int Translate();
VS10Reg dst;
VS10Reg src[3];
private:
int line;
int instid;
char *comment;
void ValidateRegIndices();
void ValidateDestMask();
void ValidateSrcMasks();
void ValidateDestWritable();
void ValidateSrcReadable();
void ValidateReadPorts();
} *VS10InstPtr;
#endif

View File

@@ -0,0 +1,297 @@
#include "RenderPCH.h"
#include "nvparse.h"
#include "vs1.0_inst_list.h"
extern string vs10_transstring;
#define MAX_NUM_INSTRUCTIONS 128
#define INSTRUCTION_LIST_INC 128
VS10InstList::VS10InstList()
{
size = 0;
max = INSTRUCTION_LIST_INC;
list = new VS10Inst[max];
}
VS10InstList::~VS10InstList()
{
delete [] list;
}
int VS10InstList::Size()
{
return size;
}
VS10InstList& VS10InstList::operator+=(VS10InstPtr t)
{
if (size == max) {
// Extend list size by increment amount.
VS10InstPtr newlist;
max += INSTRUCTION_LIST_INC;
newlist = new VS10Inst[max];
for ( int i = 0; i < size; i++ )
newlist[i] = list[i];
delete [] list;
list = newlist;
}
list[size++] = *t;
return *this;
}
void VS10InstList::Translate()
{
int ntranslated = 0;
vs10_transstring.append( "!!VP1.0\n" );
for (int i = 0; i < size; i++)
{
ntranslated += list[i].Translate();
}
vs10_transstring.append( "END\n" );
if ( ntranslated > 128 )
{
char str[256];
sprintf( str, "Vertex Shader had more than 128 instructions. (Converted to: %d)\n", ntranslated );
errors.set( str );
}
//fprintf( stderr, "Converted vertex shader to vertex program with %d instructions.\n\n", ntranslated );
}
void VS10InstList::Validate()
{
int vsflag = 0;
for ( int i = 0; i < size; i++ )
{
list[i].Validate( vsflag );
}
}
namespace
{
void LoadProgram( GLenum target, GLuint id, char *instring );
void StrToUpper(char * string);
int vpid;
}
bool is_vs10(const char *s)
{
int len;
char *temp;
bool vshader_flag;
temp = NULL;
len = strlen(s);
if ( len > 0 )
temp = new char [len+1];
for ( int k = 0; k < len; k++ )
{
temp[k] = (char) tolower( (char) s[k] );
}
if ( len == 0 )
vshader_flag = false;
else
{
vshader_flag = ( NULL != strstr(temp, "vs.1.0") );
delete [] temp;
}
return vshader_flag;
}
bool vs10_init_more()
{
static bool vpinit = false;
if (vpinit == false )
{
if(!SUPPORTS_GL_NV_vertex_program)
{
errors.set("unable to initialize GL_NV_vertex_program");
return false;
}
else
{
vpinit = true;
}
}
glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid );
if ( vpid == 0 )
{
char str[128];
sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", vpid );
errors.set( str );
return false;
}
errors.reset();
line_number = 1;
vs10_transstring = "";
return true;
}
void vs10_load_program()
{
// Only load the program if no errors occurred.
if ( errors.get_num_errors() == 0 )
LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, (char *) vs10_transstring.c_str() );
}
namespace
{
//.----------------------------------------------------------------------------.
//| Function : LoadProgram |
//| Description: Load a program into GL, and report any errors encountered. |
//.----------------------------------------------------------------------------.
void LoadProgram( GLenum target, GLuint id, char *instring )
{
GLint errPos;
GLenum errCode;
const GLubyte *errString;
int len = strlen(instring);
glLoadProgramNV( target, id, len, (const GLubyte *) instring );
if ( (errCode = glGetError()) != GL_NO_ERROR )
{
errString = gluErrorString( errCode );
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos );
int nlines = 1;
int nchar = 1;
int i;
for ( i = 0; i < errPos; i++ )
{
if ( instring[i] == '\n' )
{
nlines++;
nchar = 1;
}
else
{
nchar++;
}
}
int start;
int end;
int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0;
for ( i = errPos; i >= 0; i-- )
{
start = i;
if ( flag && (start >= errPos-1) )
continue;
if ( instring[i] == ';' )
{
if ( !flag )
{
start = i+1;
if ( instring[start] == '\n' )
start++;
}
break;
}
}
for ( i = errPos; i < len; i++ )
{
end = i;
if ( instring[i] == ';' && end > start)
{
break;
}
}
if ( errPos - start > 30 )
{
start = errPos - 30;
}
if ( end - errPos > 30 )
{
end = errPos + 30;
}
char substring[96];
memset( substring, 0, 96 );
strncpy( substring, &(instring[start]), end-start+1 );
char str[256];
//sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring );
sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring );
int width = errPos-start;
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "|\n" );
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "^\n" );
errors.set( str );
}
}
//.----------------------------------------------------------------------------.
//| Function : StrToUpper |
//| Description: Converts all lowercase chars in a string to uppercase. |
//.----------------------------------------------------------------------------.
void StrToUpper(char *string)
{
for (unsigned int i = 0; i < strlen(string); i++)
string[i] = toupper(string[i]);
}
}
/*
else if ( is_vs10(instring) )
{
if (vpinit == 0 )
{
if(! glh_init_extensions("GL_NV_vertex_program"))
{
errors.set("unable to initialize GL_NV_vertex_program");
free(instring);
return;
}
else
{
vpinit = 1;
}
}
if ( glGetError() != GL_NO_ERROR )
{
errors.set( "Previous GL_ERROR prior to vertex shader parsing.\n" );
}
int vpid;
glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid );
if ( vpid == 0 )
{
char str[128];
sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", vpid );
errors.set( str );
}
else
{
errors.reset();
line_number = 1;
vs10_init(instring);
vs10_transstring = "";
vs10_parse();
//fprintf( stderr, "Converted text:\n%s\n\n\n", vs10_transstring.c_str() );
LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, (char *) vs10_transstring.c_str() );
}
}
*/

View File

@@ -0,0 +1,25 @@
#ifndef _VS10_H
#define _VS10_H
#define WRITEMASK_X 0x01
#define WRITEMASK_Y 0x02
#define WRITEMASK_Z 0x04
#define WRITEMASK_W 0x08
#include "vs1.0_inst.h"
typedef class VS10InstList {
public:
VS10InstList();
~VS10InstList();
int Size();
VS10InstList& operator+=(VS10InstPtr t);
void Validate();
void Translate();
private:
VS10InstPtr list;
int size;
int max;
} *VS10InstListPtr;
#endif

View File

@@ -0,0 +1,152 @@
#include "RenderPCH.h"
#include "nvparse.h"
//using namespace std;
namespace
{
void LoadProgram( GLenum target, GLuint id, char *instring );
void StrToUpper(char * string);
}
bool is_vsp10(const char * s)
{
return ! strncmp(s, "!!VSP1.0", 8);
}
bool vsp10_init(char * s)
{
static bool vpinit = false;
if (vpinit == false )
{
if(!SUPPORTS_GL_NV_vertex_program)
{
errors.set("unable to initialize GL_NV_vertex_program");
return false;
}
else
{
vpinit = true;
}
}
errors.reset();
line_number = 1;
myin = s;
return true;
}
int vsp10_parse(int vpsid)
{
LoadProgram( GL_VERTEX_STATE_PROGRAM_NV, vpsid, myin );
return 0;
}
namespace
{
//.----------------------------------------------------------------------------.
//| Function : LoadProgram |
//| Description: Load a program into GL, and report any errors encountered. |
//.----------------------------------------------------------------------------.
void LoadProgram( GLenum target, GLuint id, char *instring )
{
GLint errPos;
GLenum errCode;
const GLubyte *errString;
int len = strlen(instring);
glLoadProgramNV( target, id, len, (const GLubyte *) instring );
if ( (errCode = glGetError()) != GL_NO_ERROR )
{
errString = gluErrorString( errCode );
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos );
int nlines = 1;
int nchar = 1;
int i;
for ( i = 0; i < errPos; i++ )
{
if ( instring[i] == '\n' )
{
nlines++;
nchar = 1;
}
else
{
nchar++;
}
}
int start;
int end;
int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0;
for ( i = errPos; i >= 0; i-- )
{
start = i;
if ( flag && (start >= errPos-1) )
continue;
if ( instring[i] == ';' )
{
if ( !flag )
{
start = i+1;
if ( instring[start] == '\n' )
start++;
}
break;
}
}
for ( i = errPos; i < len; i++ )
{
end = i;
if ( instring[i] == ';' && end > start)
{
break;
}
}
if ( errPos - start > 30 )
{
start = errPos - 30;
}
if ( end - errPos > 30 )
{
end = errPos + 30;
}
char substring[96];
memset( substring, 0, 96 );
strncpy( substring, &(instring[start]), end-start+1 );
char str[256];
//sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring );
sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring );
int width = errPos-start;
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "|\n" );
for ( i = 0; i < width; i++ )
{
strcat( str, " " );
}
strcat( str, "^\n" );
errors.set( str );
}
}
//.----------------------------------------------------------------------------.
//| Function : StrToUpper |
//| Description: Converts all lowercase chars in a string to uppercase. |
//.----------------------------------------------------------------------------.
void StrToUpper(char *string)
{
for (unsigned int i = 0; i < strlen(string); i++)
string[i] = toupper(string[i]);
}
}