⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps1.0_program.cpp

📁 赫赫大名的 OGRE 游戏引擎
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "ps1.0_program.h"

#include "nvparse_errors.h"
#include "nvparse_externs.h"

#include <OgreGLPrerequisites.h>

#include <string>
#include <map>
#include <algorithm>
#include <string.h>
#include <set>


using namespace std;
using namespace ps10;
struct ltstr
{
	bool operator()(const char* s1, const char* s2) const
	{
		return strcmp(s1, s2) < 0;
	}
};

#define DBG_MESG(msg, line)  	errors.set(msg, line)
//#define DBG_MESG(msg, line)
namespace ps10
{
	std::map<int, std::pair<int,int> > constToStageAndConstMap;
	std::vector<int> constToStageArray;
	std::map<int, int> stageToConstMap; // to keep track of which constants have been used up for this stage.
		// r-value of 0 means none, r-value of 1 means c0 used, and r-value of 2 means both used.
	//std::map<int, int> constToStageMap;
	std::map<int, GLenum> stageToTargetMap;
	std::set<const char*, ltstr> alphaBlueRegisters; // Keeps track of whether the result of a register
		// was a dp3, if a register is in this set, it means that if it is used a source for the alpha 
		// component the blue component should be used, and not the alpha component.
	void SetFinalCombinerStage();
}

void RemoveFromAlphaBlue(std::string s)
{
	std::set<const char*, ltstr>::iterator iter = 
		ps10::alphaBlueRegisters.find(s.c_str());
	if (iter != alphaBlueRegisters.end())
		alphaBlueRegisters.erase(iter);
}

/*
void AddToMap(string s, int stage)
{
	const char* cstr = s.c_str();
	if (cstr[0] == 'c')
	{
		int constNum = atoi(&cstr[1]);
		if (constNum < 0 || constNum > 7)
			return;
		constToStageMap[constNum] = stage;
	}
}
*/

bool AddToMap(string s, int stage, GLenum& constVal)
{
	const char* cstr = s.c_str();
	if (cstr[0] == 'c')
	{
		int constNum = atoi(&cstr[1]);
		std::map<int, int>::iterator iter = stageToConstMap.find(stage);
		if (iter == stageToConstMap.end())
		{
			// no constants used for this stage. 
			std::pair<int, int> temp;
			temp.first = stage;
			temp.second = 0;
			constToStageAndConstMap[constNum] = temp;
			stageToConstMap[stage] = 0;
			constVal = 0;
			constToStageArray.push_back(constNum);
			constToStageArray.push_back(stage);
			constToStageArray.push_back(constVal);
		}
		else
		{
			int constUsed = (*iter).second;
			if (constUsed >= 1)
				return false;
			else // const0 has been used, so use const1 for this stage.
			{
				std::pair<int,int> temp;
				temp.first = stage;
				temp.second = 1;
				constToStageAndConstMap[constNum] = temp;
				stageToConstMap[stage] = 1;
				constVal = 1;
				constToStageArray.push_back(constNum);
				constToStageArray.push_back(stage);
				constToStageArray.push_back(constVal);
			}
			
		}
	}
	constVal += GL_CONSTANT_COLOR0_NV;
	return true;
}

bool IsLegalTarget(int target)
{
	if (target == GL_TEXTURE_CUBE_MAP_ARB)
		return true;
	if (target == GL_TEXTURE_3D)
		return true;
#if defined(GL_EXT_texture_rectangle)
	if (target == GL_TEXTURE_RECTANGLE_EXT)
		return true;
#elif defined(GL_NV_texture_rectangle)
        if (target == GL_TEXTURE_RECTANGLE_NV)
                return true;
#endif
	if (target == GL_TEXTURE_2D)
		return true;
	if (target == GL_TEXTURE_1D)
		return true;
	return false;
}

bool ps10_set_map(const std::vector<int>& argv)
{
	if (argv.size() % 2 != 0)
	{
		errors.set("Odd number of arguments for texture target map.");
		return false;
	}
	for (unsigned int i=0;i<argv.size();i=i+2)
	{
		int stage = argv[i];
		int target = argv[i+1];
		if (!IsLegalTarget(target))
		{
			errors.set("Illegal target in texture target map.");
			return false;
		}
		ps10::stageToTargetMap[stage] = target;
	}
	return true;
}

int const_to_combiner_reg_mapping[32][3]; // each 3 tuple is: (constant#, stage #, reg #)
int const_to_combiner_reg_mapping_count = 0;


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[1] = c.g;
			cval[2] = c.b;
			cval[3] = c.a;
			glCombinerStageParameterfvNV_ptr(stage, cclr, cval);
		}
	};

	GLenum get_tex_target(int stage)
	{
		std::map<int, GLenum>::iterator iter = stageToTargetMap.find(stage);
		if (iter != stageToTargetMap.end())
			return (*iter).second;
		// If no mapping set, use the current state. This will not work correctly, in general,
		// if nvparse was invoked within a display list.
		if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
			return GL_TEXTURE_CUBE_MAP_ARB;
		if(glIsEnabled(GL_TEXTURE_3D))
			return GL_TEXTURE_3D;
#if defined(GL_EXT_texture_rectangle)
		if(glIsEnabled(GL_TEXTURE_RECTANGLE_EXT))
			return GL_TEXTURE_RECTANGLE_EXT;
#elif defined(GL_NV_texture_rectangle)
                if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV))
                        return GL_TEXTURE_RECTANGLE_NV;
#endif
		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(vector<constdef> * cdef)
		{
			for(stage = 0; stage < 4; stage++)
			{
				glActiveTextureARB_ptr(GL_TEXTURE0_ARB + stage);
				glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
			}
			stage = 0;
			c = cdef;
		}

		void operator() (vector<string> & instr)
		{
			if(stage > 3)
				return;
			glActiveTextureARB_ptr(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(stage));
			}
			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;
				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -