Files
FC1/RenderDll/XRenderOGL/NVParse/ps1.0_program.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

743 lines
23 KiB
C++

#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;
}