Add some files from old nevrax shader code for exposing pixel programs in the drivers

This commit is contained in:
kaetemi 2013-06-19 01:14:30 +02:00
parent ad6cc747b9
commit fd42d61af9
4 changed files with 1006 additions and 0 deletions

View file

@ -0,0 +1,86 @@
/** \file pixel_program.h
* Pixel program definition
*
* $Id: pixel_program.h,v 1.1.2.3 2007/07/06 15:58:45 legallo Exp $
*/
/* Copyright, 2000, 2001 Nevrax Ltd.
*
* This file is part of NEVRAX NEL.
* NEVRAX NEL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* NEVRAX NEL is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with NEVRAX NEL; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef NL_PIXEL_PROGRAM_H
#define NL_PIXEL_PROGRAM_H
#include "program.h"
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include <list>
#define PIXEL_SHADER_PROFILE "ps_2_0"
namespace NL3D {
// List typedef.
class IDriver;
class IPixelProgramDrvInfos;
typedef std::list<IPixelProgramDrvInfos*> TPixelPrgDrvInfoPtrList;
typedef TPixelPrgDrvInfoPtrList::iterator ItPixelPrgDrvInfoPtrList;
// Class for interaction of pixel program with Driver.
// IPixelProgramDrvInfos represent the real data of the pixel program, stored into the driver.
class IPixelProgramDrvInfos : public NLMISC::CRefCount
{
private:
IDriver *_Driver;
ItPixelPrgDrvInfoPtrList _DriverIterator;
public:
IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it);
// The virtual dtor is important.
virtual ~IPixelProgramDrvInfos(void);
};
//-------------------------------------------------------------------------------
class CPixelProgram : public IProgram
{
public:
/// Constructor
CPixelProgram (const char* program, bool isEffectPrg=false);
/// Destructor
virtual ~CPixelProgram ();
/// The driver informations. For the driver implementation only.
NLMISC::CRefPtr<IPixelProgramDrvInfos> _DrvInfo;
const char * getASMProfile() { return PIXEL_SHADER_PROFILE; } ;
static const char * getPixelASMProfile() { return PIXEL_SHADER_PROFILE; } ;
};
} // NL3D
#endif // NL_PIXEL_PROGRAM_H
/* End of vertex_program.h */

View file

@ -0,0 +1,305 @@
/** \file driver_direct3d_pixel_program.cpp
* Direct 3d driver implementation
*
* $Id: driver_direct3d_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:26:35 legallo Exp $
*
* \todo manage better the init/release system (if a throw occurs in the init, we must release correctly the driver)
*/
/* Copyright, 2000 Nevrax Ltd.
*
* This file is part of NEVRAX NEL.
* NEVRAX NEL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* NEVRAX NEL is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with NEVRAX NEL; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "stddirect3d.h"
#include "driver_direct3d.h"
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D)
Shader = NULL;
}
// ***************************************************************************
CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D()
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgramDrvInfosD3DDtor)
if (Shader)
Shader->Release();
}
// ***************************************************************************
bool CDriverD3D::isPixelProgramSupported () const
{
H_AUTO_D3D(CDriverD3D_isPixelProgramSupported )
return _PixelProgram;
}
// ***************************************************************************
bool CDriverD3D::activePixelProgram(CPixelProgram *program)
{
H_AUTO_D3D(CDriverD3D_activePixelProgram )
if (_DisableHardwarePixelProgram)
return false;
// Setup or unsetup ?
if (program)
{
// Program setuped ?
if (program->_DrvInfo==NULL)
{
_PixelPrgDrvInfos.push_front (NULL);
ItPixelPrgDrvInfoPtrList itPix = _PixelPrgDrvInfos.begin();
*itPix = new CPixelProgramDrvInfosD3D(this, itPix);
// Create a driver info structure
program->_DrvInfo = *itPix;
std::string dest;
if(program->isEffectProgram())
{
dest = program->getProgram();
}
LPD3DXBUFFER pShader;
LPD3DXBUFFER pErrorMsgs;
if (D3DXAssembleShader (dest.c_str(), dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
{
if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK)
return false;
}
else
{
nlwarning ("Can't assemble pixel program:");
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
return false;
}
}
}
// Set the pixel program
if (program)
{
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IPixelProgramDrvInfos*)program->_DrvInfo);
setPixelShader (info->Shader);
float z = 0;
float o = 1;
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&o)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&z)));
}
else
{
setPixelShader (NULL);
// Set the old fog range
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&_FogEnd)));
}
return true;
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant)
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {f0, f1, f2, f3};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {(float)d0, (float)d1, (float)d2, (float)d3};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVector& value)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {value.x, value.y, value.z, 0};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
const float tabl[4] = {(float)value.x, (float)value.y, (float)value.z, 0};
setPixelShaderConstant (index, tabl);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, uint num, const float *src)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
uint i;
for (i=0; i<num; i++)
setPixelShaderConstant (index+i, src+i*4);
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstant (uint index, uint num, const double *src)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstant )
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
uint i;
for (i=0; i<num; i++)
{
const float tabl[4] = {(float)src[0], (float)src[1], (float)src[2], (float)src[3]};
setPixelShaderConstant (index+i, tabl);
src += 4;
}
}
// ***************************************************************************
void CDriverD3D::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_D3D(CDriverD3D_setPixelProgramConstantMatrix)
if (!_PixelProgram)
{
#ifdef NL_DEBUG
nlwarning("No pixel programs available!!");
#endif
return;
}
D3DXMATRIX mat;
D3DXMATRIX *matPtr;
switch (matrix)
{
case IDriver::ModelView:
matPtr = &_D3DModelView;
break;
case IDriver::Projection:
matPtr = &(_MatrixCache[remapMatrixIndex (D3DTS_PROJECTION)].Matrix);
break;
case IDriver::ModelViewProjection:
matPtr = &_D3DModelViewProjection;
break;
}
if (transform != IDriver::Identity)
{
mat = *matPtr;
matPtr = &mat;
switch(transform)
{
case IDriver::Inverse:
D3DXMatrixInverse (&mat, NULL, &mat);
break;
case IDriver::Transpose:
D3DXMatrixTranspose (&mat, &mat);
break;
case IDriver::InverseTranspose:
D3DXMatrixInverse (&mat, NULL, &mat);
D3DXMatrixTranspose (&mat, &mat);
break;
}
}
setPixelProgramConstant (index, matPtr->_11, matPtr->_21, matPtr->_31, matPtr->_41);
setPixelProgramConstant (index+1, matPtr->_12, matPtr->_22, matPtr->_32, matPtr->_42);
setPixelProgramConstant (index+2, matPtr->_13, matPtr->_23, matPtr->_33, matPtr->_43);
setPixelProgramConstant (index+3, matPtr->_14, matPtr->_24, matPtr->_34, matPtr->_44);
}
// ***************************************************************************
void CDriverD3D::disableHardwarePixelProgram()
{
H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram)
_DisableHardwarePixelProgram = true;
_PixelProgram = false;
}
// ***************************************************************************
uint CDriverD3D::getMaxTexturesForEffects() const
{
H_AUTO_D3D(CDriverD3D_getMaxTexturesForEffects)
// we use ps_2_0 profile for direct3D ASM pixel program, then 16 texture samplers are available
if(!strcmp(CPixelProgram::getPixelASMProfile(), "ps_2_0"))
return 16;
return 0;
}
} // NL3D

View file

@ -0,0 +1,553 @@
/** \file driver_opengl_pixel_program.cpp
* OpenGL driver implementation for pixel program manipulation.
*
* $Id: driver_opengl_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:29:00 legallo Exp $
*
* \todo manage better the init/release system (if a throw occurs in the init, we must release correctly the driver)
*/
/* Copyright, 2000 Nevrax Ltd.
*
* This file is part of NEVRAX NEL.
* NEVRAX NEL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* NEVRAX NEL is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with NEVRAX NEL; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "stdopengl.h"
#include "driver_opengl.h"
#include "../../index_buffer.h"
#include "../../vertex_program.h"
//#include "../../vertex_program_parse.h"
#include "../../program_parse_D3D.h"
#include <algorithm>
// tmp
#include "nel/misc/file.h"
using namespace std;
using namespace NLMISC;
//#define DEBUG_SETUP_EXT_VERTEX_SHADER
namespace NL3D
{
// ***************************************************************************
CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it)
{
H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL)
// Extension must exist
nlassert(drv->_Extensions.ARBFragmentProgram);
if (drv->_Extensions.ARBFragmentProgram) // ARB implementation
{
nglGenProgramsARB(1, &ID);
}
}
// ***************************************************************************
bool CDriverGL::isPixelProgramSupported () const
{
H_AUTO_OGL(CPixelProgamDrvInfosGL_isPixelProgramSupported)
return _Extensions.ARBFragmentProgram;
}
// ***************************************************************************
bool CDriverGL::activePixelProgram(CPixelProgram *program)
{
H_AUTO_OGL(CDriverGL_activePixelProgram)
if (_Extensions.ARBFragmentProgram)
{
return activeARBPixelProgram(program);
}
return false;
}
// ***************************************************************************
bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
{
H_AUTO_OGL(CDriverGL_activeARBPixelProgram)
// Setup or unsetup ?
if (program)
{
// Driver info
CPixelProgamDrvInfosGL *drvInfo;
// Program setuped ?
if (program->_DrvInfo==NULL)
{
// Insert into driver list. (so it is deleted when driver is deleted).
ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end());
// Create a driver info
*it = drvInfo = new CPixelProgamDrvInfosGL (this, it);
// Set the pointer
program->_DrvInfo=drvInfo;
std::string asmProgram;
CPixelProgramParser::CPProgram parsedProgram;
if(program->isEffectProgram())
{
asmProgram = program->getProgram();
CPPParserD3D parser;
// try to parse the program
std::string errorOutput;
bool result = parser.parse(asmProgram.c_str(), parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a pixel program.");
#ifdef NL_DEBUG
nlerror(errorOutput.c_str());
#endif
return false;
}
}
if(!setupARBPixelProgram(parsedProgram, drvInfo->ID))
{
delete drvInfo;
program->_DrvInfo = NULL;
_PixelPrgDrvInfos.erase(it);
return false;
}
}
else
{
// Cast the driver info pointer
drvInfo=safe_cast<CPixelProgamDrvInfosGL*>((IPixelProgramDrvInfos*)program->_DrvInfo);
}
glEnable( GL_FRAGMENT_PROGRAM_ARB );
_PixelProgramEnabled = true;
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID );
glDisable( GL_COLOR_SUM_ARB ); // no specular written
_LastSetuppedPP = program;
}
else
{
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_COLOR_SUM_ARB );
_PixelProgramEnabled = false;
}
return true;
}
// ***************************************************************************
bool CDriverGL::setupARBPixelProgram (const CPixelProgramParser::CPProgram &inParsedProgram, GLuint id/*, bool &specularWritten*/)
{
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
// convert from proprietary format to ARB_pixel_program code
CPixelProgramConversionARB vpConvertARB;
std::string code;
if(!vpConvertARB.convert(inParsedProgram, code)) return false;
//
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id);
glGetError();
nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() );
GLenum err = glGetError();
if (err != GL_NO_ERROR)
{
if (err == GL_INVALID_OPERATION)
{
GLint position;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position);
nlassert(position != -1) // there was an error..
nlassert(position < (GLint) code.size());
uint line = 0;
const char *lineStart = code.c_str();
for(uint k = 0; k < (uint) position; ++k)
{
if (code[k] == '\n')
{
lineStart = code.c_str() + k;
++line;
}
}
nlwarning("ARB fragment program parse error at line %d.", (int) line);
// search end of line
const char *lineEnd = code.c_str() + code.size();
for(uint k = position; k < code.size(); ++k)
{
if (code[k] == '\n')
{
lineEnd = code.c_str() + k;
break;
}
}
nlwarning(std::string(lineStart, lineEnd).c_str());
// display the gl error msg
const GLubyte *errorMsg = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
nlassert((const char *) errorMsg);
nlwarning((const char *) errorMsg);
}
nlassert(0);
return false;
}
return true;
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3);
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3);
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& value)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
{
for(uint k = 0; k < num; ++k)
{
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
}
}
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
{
for(uint k = 0; k < num; ++k)
{
nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
}
}
}
}
// ***************************************************************************
void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
{
H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix)
if(_LastSetuppedVP && _LastSetuppedVP->isEffectProgram())
{
if (_Extensions.ARBFragmentProgram)
{
// First, ensure that the render setup is correctly setuped.
refreshRenderSetup();
CMatrix mat;
switch (matrix)
{
case IDriver::ModelView:
mat = _ModelViewMatrix;
break;
case IDriver::Projection:
{
refreshProjMatrixFromGL();
mat = _GLProjMat;
}
break;
case IDriver::ModelViewProjection:
refreshProjMatrixFromGL();
mat = _GLProjMat * _ModelViewMatrix;
break;
default:
break;
}
switch(transform)
{
case IDriver::Identity: break;
case IDriver::Inverse:
mat.invert();
break;
case IDriver::Transpose:
mat.transpose();
break;
case IDriver::InverseTranspose:
mat.invert();
mat.transpose();
break;
default:
break;
}
mat.transpose();
float matDatas[16];
mat.get(matDatas);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8);
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12);
}
}
}
// ***************************************************************************
uint CDriverGL::getMaxTexturesForEffects() const
{
H_AUTO_OGL(CDriverGL_getMaxTexturesForEffects)
uint texSamplerNb = 0;
if (_Extensions.ARBFragmentProgram) // ARB implementation
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, (int*)(&texSamplerNb));
return texSamplerNb;
}
// ***************************************************************************
// ***************** CPixelProgramConversionARB *****************************
// ***************************************************************************
const char * CPixelProgramConversionARB::ARBPixelProgramInputRegisterToName[CPPOperand::InputRegisterCount] =
{
"color.primary",
"color.secondary",
"texcoord[0]",
"texcoord[1]",
"texcoord[2]",
"texcoord[3]",
"texcoord[4]",
"texcoord[5]",
"texcoord[6]",
"texcoord[7]",
};
// ***************************************************************************
const char * CPixelProgramConversionARB::ARBPixelProgramOutputRegisterToName[CPPOperand::OutputRegisterCount] =
{
"color",
"depth"
};
// ***************************************************************************
bool CPixelProgramConversionARB::convert(const CPixelProgramParser::CPProgram &inParsedProgram, std::string & code)
{
CPixelProgramParser::TPProgram parsedProgram = inParsedProgram._Program;
//
code = "!!ARBfp1.0\n";
// declare temporary registers
GLint glMaxTempVar;
nglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &glMaxTempVar);
uint usedTempVar = inParsedProgram.getUsedVariablesNb();
if(usedTempVar>glMaxTempVar)
{
nlwarning(" Used temporary registers number is superior to maximum ARB_FRAGMENT_PROGRAM temporaries registers.");
return false;
}
ARBProgramTemporaryRegisters(code, usedTempVar);
// declare constant register
if(!CProgramConversionARB::constantRegisters(inParsedProgram._Constants, code)) return false;
for(uint k = 0; k < parsedProgram.size(); ++k)
{
std::string instr;
ARBPixelProgramDumpInstr(parsedProgram[k], instr);
code += instr + "\r\n";
}
code += "END\n";
return true;
}
// ***************************************************************************
// Dump an instruction in a string
void CPixelProgramConversionARB::ARBPixelProgramDumpInstr(const CPPInstruction &instr, std::string &out)
{
nlassert(instr.Opcode.PPOp < CPPInstruction::OpcodeCount);
// Special case for EXP with a scalar output argument (y component) -> translate to FRC
out = std::string();
switch(instr.Opcode.PPOp)
{
case CPPInstruction::ADD:
out = "ADD";
break;
case CPPInstruction::DP3:
out = "DP3";
break;
case CPPInstruction::DP4:
out = "DP4";
break;
case CPPInstruction::EXP:
out = "EXP";
break;
case CPPInstruction::FRC:
out = "FRC";
break;
case CPPInstruction::LOG:
out = "LOG";
break;
case CPPInstruction::MAD:
out = "MAD";
break;
case CPPInstruction::MAX:
out = "MAX";
break;
case CPPInstruction::MIN:
out = "MIN";
break;
case CPPInstruction::MOV:
out = "MOV";
break;
case CPPInstruction::MUL:
out = "MUL";
break;
case CPPInstruction::RCP:
out = "RCP";
break;
case CPPInstruction::RSQ:
out = "RSQ";
break;
case CPPInstruction::SUB:
out = "SUB";
break;
case CPPInstruction::ABS:
out = "ABS";
break;
case CPPInstruction::CMP:
out = "CMP";
break;
case CPPInstruction::CRS:
out = "XPD";
break;
case CPPInstruction::LRP:
out = "LRP";
break;
case CPPInstruction::POW:
out = "POW";
break;
case CPPInstruction::TEX:
out = "TEX";
break;
case CPPInstruction::TEXB:
out = "TXB";
break;
case CPPInstruction::TEXP:
out = "TXP";
break;
default:
nlwarning("no match with a ARB Pixel Program Operator");
break;
}
if(instr.Sat) out += "_SAT";
out += " ";
uint nbOp = instr.getNumUsedSrc();
std::string destOperand;
ARBPixelProgramDumpOperand(instr.Dest, true, destOperand);
out += destOperand;
for(uint k = 0; k < nbOp; ++k)
{
out += ", ";
std::string srcOperand;
ARBPixelProgramDumpOperand(instr.getSrc(k), false, srcOperand);
out += srcOperand;
}
out +="; \n";
}
// ***************************************************************************
void CPixelProgramConversionARB::ARBPixelProgramDumpOperand(const CPPOperand &op, bool destOperand, std::string &out)
{
out = op.Negate ? " -" : " ";
switch(op.Type)
{
case CPPOperand::Variable: out += "R" + NLMISC::toString(op.Value.VariableValue); break;
case CPPOperand::Constant:
out += "c[";
out += NLMISC::toString(op.Value.ConstantValue) + "]";
break;
case CPPOperand::InputRegister: out += string("fragment.") + ARBPixelProgramInputRegisterToName[(uint) op.Value.InputRegisterValue]; break;
case CPPOperand::OutputRegister:
nlassert(op.Value.OutputRegisterValue < CVPOperand::OutputRegisterCount);
out += "result." + std::string(ARBPixelProgramOutputRegisterToName[op.Value.OutputRegisterValue]);
break;
case CPPOperand::Sampler2DRegister:
out += string("texture[") + op.Value.SamplerValue + "], 2D";
break;
case CPPOperand::Sampler3DRegister:
out += string("texture[") + op.Value.SamplerValue + "], 3D";
break;
default:
break;
}
ARBProgramSuffix(op, destOperand, out);
}
} // NL3D

View file

@ -0,0 +1,62 @@
/** \file pixel_program.cpp
* Pixel program definition
*
* $Id: pixel_program.cpp,v 1.1.2.1 2007/04/27 17:35:07 legallo Exp $
*/
/* Copyright, 2000, 2001 Nevrax Ltd.
*
* This file is part of NEVRAX NEL.
* NEVRAX NEL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* NEVRAX NEL is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with NEVRAX NEL; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "std3d.h"
#include "pixel_program.h"
#include "driver.h"
namespace NL3D
{
// ***************************************************************************
IPixelProgramDrvInfos::IPixelProgramDrvInfos (IDriver *drv, ItPixelPrgDrvInfoPtrList it)
{
_Driver= drv;
_DriverIterator= it;
}
// ***************************************************************************
IPixelProgramDrvInfos::~IPixelProgramDrvInfos ()
{
_Driver->removePixelPrgDrvInfoPtr (_DriverIterator);
}
// ***************************************************************************
CPixelProgram::CPixelProgram(const char* program, bool isEffectPrg)
:IProgram(program, isEffectPrg)
{
}
// ***************************************************************************
CPixelProgram::~CPixelProgram()
{
}
} // NL3D