mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
Added better code to compile shaders
This commit is contained in:
parent
4b58cb8500
commit
23b0c5d850
@ -1773,7 +1773,10 @@ ConditionalWriteFile(PREFIX+'/include/dtool_config.h',conf)
|
||||
##########################################################################################
|
||||
|
||||
CONFAUTOPRC=ReadFile("makepanda/confauto.in")
|
||||
CONFIGPRC=ReadFile("makepanda/config.in")
|
||||
if (os.path.isfile("makepanda/myconfig.in")):
|
||||
CONFIGPRC=ReadFile("makepanda/myconfig.in")
|
||||
else:
|
||||
CONFIGPRC=ReadFile("makepanda/config.in")
|
||||
|
||||
if (sys.platform != "win32"):
|
||||
CONFAUTOPRC = CONFAUTOPRC.replace("aux-display pandadx9","")
|
||||
|
@ -1,42 +1,42 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="makepanda71"
|
||||
ProjectGUID="{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}"
|
||||
Keyword="MakeFileProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="0">
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="cd .. & makepanda\makepanda --everything --installer"
|
||||
Output="..\built\bin\ppython.exe"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="makepanda71"
|
||||
ProjectGUID="{F4935D7A-20AD-4132-B3CB-ADFF4F928D25}"
|
||||
Keyword="MakeFileProj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="0">
|
||||
<Tool
|
||||
Name="VCNMakeTool"
|
||||
BuildCommandLine="cd .. & makepanda\makepanda --everything --installer"
|
||||
Output="..\built\python\python.exe"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
@ -68,10 +68,6 @@
|
||||
#include "shader.h"
|
||||
#include "shaderMode.h"
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
#include "Cg/cgGL.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
|
||||
@ -859,16 +855,6 @@ reset() {
|
||||
|
||||
_error_count = 0;
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
_cg_context = cgCreateContext();
|
||||
if (_cg_context != 0) {
|
||||
_cg_vprofile = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||
_cg_fprofile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||
} else {
|
||||
cerr << "Warning: could not create Cg context.\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
@ -1944,7 +1930,10 @@ release_geom(GeomContext *gc) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ShaderContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_shader(Shader *shader) {
|
||||
return new CLP(ShaderContext)(this, shader);
|
||||
CLP(ShaderContext) *result = new CLP(ShaderContext)(shader);
|
||||
if (result->valid()) return result;
|
||||
delete result;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -2620,7 +2609,7 @@ issue_shader(const ShaderAttrib *attrib) {
|
||||
_shader_context = 0;
|
||||
}
|
||||
if (context != 0) {
|
||||
context->bind(mode);
|
||||
context->bind(mode, this);
|
||||
_shader_context = context;
|
||||
}
|
||||
_shader_mode = mode;
|
||||
@ -4762,12 +4751,6 @@ finish_modify_state() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
free_pointers() {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -41,10 +41,6 @@
|
||||
#include "shader.h"
|
||||
#include "shaderMode.h"
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
#include "Cg/cgGL.h"
|
||||
#endif
|
||||
|
||||
class PlaneNode;
|
||||
class Light;
|
||||
|
||||
@ -389,12 +385,6 @@ public:
|
||||
typedef pvector<GLuint> DeletedDisplayLists;
|
||||
DeletedDisplayLists _deleted_display_lists;
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
CGcontext _cg_context;
|
||||
CGprofile _cg_vprofile;
|
||||
CGprofile _cg_fprofile;
|
||||
#endif
|
||||
|
||||
static PStatCollector _load_display_list_pcollector;
|
||||
static PStatCollector _primitive_batches_display_list_pcollector;
|
||||
static PStatCollector _vertices_display_list_pcollector;
|
||||
|
@ -17,29 +17,19 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::bind
|
||||
// Function: GLShaderContext::valid
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
// Description: Returns true if the shader is "valid", ie, if the
|
||||
// compilation was successful. The compilation could
|
||||
// fail if there is a syntax error in the shader, or
|
||||
// if the current video card isn't shader-capable,
|
||||
// or if no shader languages are compiled into panda.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CLP(ShaderContext)::
|
||||
bind(ShaderMode *m) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::unbind
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CLP(ShaderContext)::
|
||||
unbind() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::rebind
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void CLP(ShaderContext)::
|
||||
rebind(ShaderMode *oldmode, ShaderMode *newmode) {
|
||||
INLINE bool CLP(ShaderContext)::
|
||||
valid() {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context) return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,44 +24,95 @@ TypeHandle CLP(ShaderContext)::_type_handle;
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLP(ShaderContext)::
|
||||
CLP(ShaderContext)(CLP(GraphicsStateGuardian) *gsg, Shader *s) : ShaderContext(s) {
|
||||
CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
|
||||
string header;
|
||||
_gsg = gsg;
|
||||
_valid = false;
|
||||
s->parse_init();
|
||||
s->parse_line(header, true, true);
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
_cg_vprogram = 0;
|
||||
_cg_fprogram = 0;
|
||||
_cg_context = (CGcontext)0;
|
||||
_cg_profile[VERT_SHADER] = (CGprofile)0;
|
||||
_cg_profile[FRAG_SHADER] = (CGprofile)0;
|
||||
_cg_program[VERT_SHADER] = (CGprogram)0;
|
||||
_cg_program[FRAG_SHADER] = (CGprogram)0;
|
||||
|
||||
if (header == "Cg") {
|
||||
if (_gsg->_cg_context == 0) {
|
||||
cerr << "Cannot compile shader, no Cg context\n";
|
||||
return;
|
||||
}
|
||||
string commentary, vs, fs;
|
||||
s->parse_upto(commentary, "---*---", false);
|
||||
s->parse_upto(vs, "---*---", false);
|
||||
s->parse_upto(fs, "---*---", false);
|
||||
|
||||
_cg_vprogram = cgCreateProgram(_gsg->_cg_context, CG_SOURCE,
|
||||
vs.c_str(), _gsg->_cg_vprofile,
|
||||
"main", (const char**)NULL);
|
||||
_cg_fprogram = cgCreateProgram(_gsg->_cg_context, CG_SOURCE,
|
||||
fs.c_str(), _gsg->_cg_fprofile,
|
||||
"main", (const char**)NULL);
|
||||
|
||||
if ((_cg_vprogram==0)||(_cg_fprogram == 0)) {
|
||||
if (_cg_vprogram != 0) cgDestroyProgram(_cg_vprogram);
|
||||
if (_cg_fprogram != 0) cgDestroyProgram(_cg_fprogram);
|
||||
cerr << "Invalid Cg program" << s->_file << "\n";
|
||||
CGerror err;
|
||||
_cg_context = cgCreateContext();
|
||||
if (_cg_context == 0) {
|
||||
release_resources();
|
||||
cerr << "Cg not supported by this video card.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
_cg_profile[VERT_SHADER] = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||
_cg_profile[FRAG_SHADER] = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||
if ((_cg_profile[VERT_SHADER] == CG_PROFILE_UNKNOWN)||
|
||||
(_cg_profile[FRAG_SHADER] == CG_PROFILE_UNKNOWN)) {
|
||||
release_resources();
|
||||
cerr << "Cg not supported by this video card II\n";
|
||||
return;
|
||||
}
|
||||
cgGetError();
|
||||
|
||||
string commentary, stext[2];
|
||||
s->parse_upto(commentary, "---*---", false);
|
||||
_cg_linebase[0] = s->parse_lineno();
|
||||
s->parse_upto(stext[0], "---*---", false);
|
||||
_cg_linebase[1] = s->parse_lineno();
|
||||
s->parse_upto(stext[1], "---*---", false);
|
||||
|
||||
for (int progindex=0; progindex<2; progindex++) {
|
||||
_cg_program[progindex] =
|
||||
cgCreateProgram(_cg_context, CG_SOURCE, stext[progindex].c_str(),
|
||||
_cg_profile[progindex], "main", (const char**)NULL);
|
||||
err = cgGetError();
|
||||
if (err != CG_NO_ERROR) {
|
||||
if (err == CG_COMPILER_ERROR) {
|
||||
string listing = cgGetLastListing(_cg_context);
|
||||
vector_string errlines;
|
||||
tokenize(listing, errlines, "\n");
|
||||
for (int i=0; i<(int)errlines.size(); i++) {
|
||||
string line = trim(errlines[i]);
|
||||
if (line != "") {
|
||||
cerr << s->_file << " " << (_cg_linebase[progindex]-1) << "+" << errlines[i] << "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cerr << s->_file << ": " << cgGetErrorString(err) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((_cg_program[VERT_SHADER]==0)||(_cg_program[FRAG_SHADER]==0)) {
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
CGparameter parameter;
|
||||
for (int progindex=0; progindex<2; progindex++) {
|
||||
for (parameter = cgGetFirstLeafParameter(_cg_program[progindex],CG_PROGRAM);
|
||||
parameter != 0;
|
||||
parameter = cgGetNextLeafParameter(parameter)) {
|
||||
success &= compile_cg_parameter(parameter);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
release_resources();
|
||||
return;
|
||||
}
|
||||
|
||||
cgGLLoadProgram(_cg_program[VERT_SHADER]);
|
||||
cgGLLoadProgram(_cg_program[FRAG_SHADER]);
|
||||
|
||||
cerr << s->_file << ": compiled ok.\n";
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
cerr << "Unrecognized shader language " << header << "\n";
|
||||
|
||||
cerr << s->_file << ": unrecognized shader language " << header << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -71,5 +122,512 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *gsg, Shader *s) : ShaderContext(s
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CLP(ShaderContext)::
|
||||
~CLP(ShaderContext)() {
|
||||
release_resources();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::release_resources
|
||||
// Access: Public
|
||||
// Description: Should deallocate all system resources (such as
|
||||
// vertex program handles or Cg contexts).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
release_resources() {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = (CGcontext)0;
|
||||
_cg_profile[VERT_SHADER] = (CGprofile)0;
|
||||
_cg_profile[FRAG_SHADER] = (CGprofile)0;
|
||||
_cg_program[VERT_SHADER] = (CGprogram)0;
|
||||
_cg_program[FRAG_SHADER] = (CGprogram)0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::bind
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
bind(ShaderMode *m, GraphicsStateGuardianBase *gsg) {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context != 0) {
|
||||
LVector4d tvec;
|
||||
|
||||
// Assign the uniform Auto-Matrices
|
||||
for (int i=0; i<(int)_cg_autobind.size(); i++) {
|
||||
cgGLSetStateMatrixParameter(_cg_autobind[i].parameter,
|
||||
_cg_autobind[i].matrix,
|
||||
_cg_autobind[i].orientation);
|
||||
}
|
||||
|
||||
// Bind the shaders.
|
||||
cgGLEnableProfile(_cg_profile[VERT_SHADER]);
|
||||
cgGLBindProgram(_cg_program[VERT_SHADER]);
|
||||
cgGLEnableProfile(_cg_profile[FRAG_SHADER]);
|
||||
cgGLBindProgram(_cg_program[FRAG_SHADER]);
|
||||
|
||||
// Pass in uniform sampler2d parameters.
|
||||
for (int i=0; i<(int)_cg_tbind2d.size(); i++) {
|
||||
int index = _cg_tbind2d[i].argindex;
|
||||
if (index >= (int)m->_args.size()) continue;
|
||||
if (m->_args[index]._type != ShaderModeArg::SAT_TEXTURE) continue;
|
||||
Texture *tex = m->_args[index]._tvalue;
|
||||
TextureContext *tc = tex->prepare_now(gsg->get_prepared_objects(),gsg);
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
cgGLSetTextureParameter(_cg_tbind2d[i].parameter, gtc->_index);
|
||||
cgGLEnableTextureParameter(_cg_tbind2d[i].parameter);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::unbind
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
unbind() {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context != 0) {
|
||||
// Disable texture parameters.
|
||||
for (int i=0; i<(int)_cg_tbind2d.size(); i++)
|
||||
cgGLDisableTextureParameter(_cg_tbind2d[i].parameter);
|
||||
|
||||
cgGLDisableProfile(_cg_profile[VERT_SHADER]);
|
||||
cgGLDisableProfile(_cg_profile[FRAG_SHADER]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::rebind
|
||||
// Access: Public
|
||||
// Description: xyz
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
rebind(ShaderMode *oldmode, ShaderMode *newmode) {
|
||||
}
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_words
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter contains
|
||||
// the specified number of words. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_words(CGparameter p, int len)
|
||||
{
|
||||
vector_string words;
|
||||
tokenize(cgGetParameterName(p), words, "_");
|
||||
if (words.size() != len) {
|
||||
errchk_cg_output(p, "parameter name has wrong number of words");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_direction
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct direction. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_direction(CGparameter p, CGenum dir)
|
||||
{
|
||||
if (cgGetParameterDirection(p) != dir) {
|
||||
if (dir == CG_IN) errchk_cg_output(p, "parameter should be declared 'in'");
|
||||
if (dir == CG_OUT) errchk_cg_output(p, "parameter should be declared 'out'");
|
||||
if (dir == CG_INOUT) errchk_cg_output(p, "parameter should be declared 'inout'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_variance
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct variance. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_variance(CGparameter p, CGenum var)
|
||||
{
|
||||
if (cgGetParameterVariability(p) != var) {
|
||||
if (var == CG_UNIFORM)
|
||||
errchk_cg_output(p, "parameter should be declared 'uniform'");
|
||||
if (var == CG_VARYING)
|
||||
errchk_cg_output(p, "parameter should be declared 'varying'");
|
||||
if (var == CG_CONSTANT)
|
||||
errchk_cg_output(p, "parameter should be declared 'const'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_prog
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter is a part
|
||||
// of the correct program. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_prog(CGparameter p, CGprogram prog, const string &msg)
|
||||
{
|
||||
if (cgGetParameterProgram(p) != prog) {
|
||||
string fmsg = "parameter can only be used in a ";
|
||||
errchk_cg_output(p, fmsg+msg+" program");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_semantic
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct semantic string. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_semantic(CGparameter p, const string &semantic)
|
||||
{
|
||||
if (semantic != cgGetParameterSemantic(p)) {
|
||||
if (semantic == "") {
|
||||
errchk_cg_output(p, "parameter should have no semantic string");
|
||||
} else {
|
||||
string msg = "parameter should have the semantic string ";
|
||||
errchk_cg_output(p, msg + semantic);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_type
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct type. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_type(CGparameter p, CGtype dt)
|
||||
{
|
||||
if (cgGetParameterType(p) != dt) {
|
||||
string msg = "parameter should be of type ";
|
||||
errchk_cg_output(p, msg + cgGetTypeString(dt));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_float
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has
|
||||
// a floating point type. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_float(CGparameter p)
|
||||
{
|
||||
CGtype t = cgGetParameterType(p);
|
||||
if ((t != CG_FLOAT1)&&(t != CG_FLOAT2)&&(t != CG_FLOAT3)&&(t != CG_FLOAT4)) {
|
||||
errchk_cg_output(p, "parameter should have a float type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_sampler
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has
|
||||
// a texture type. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
errchk_cg_parameter_sampler(CGparameter p)
|
||||
{
|
||||
CGtype t = cgGetParameterType(p);
|
||||
if (t != CG_SAMPLER2D) {
|
||||
errchk_cg_output(p, "parameter should have a 'sampler' type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_direction
|
||||
// Access: Public, Static
|
||||
// Description: Print an error message including a description
|
||||
// of the specified Cg parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
errchk_cg_output(CGparameter p, const string &msg)
|
||||
{
|
||||
string vstr;
|
||||
CGenum v = cgGetParameterVariability(p);
|
||||
if (v == CG_UNIFORM) vstr = "uniform ";
|
||||
if (v == CG_VARYING) vstr = "varying ";
|
||||
if (v == CG_CONSTANT) vstr = "const ";
|
||||
|
||||
string dstr;
|
||||
CGenum d = cgGetParameterDirection(p);
|
||||
if (d == CG_IN) dstr = "in ";
|
||||
if (d == CG_OUT) dstr = "out ";
|
||||
if (d == CG_INOUT) dstr = "inout ";
|
||||
|
||||
const char *ts = cgGetTypeString(cgGetParameterType(p));
|
||||
const char *ss = cgGetParameterSemantic(p);
|
||||
|
||||
string err;
|
||||
string fn = _shader->_file;
|
||||
if (ss) {
|
||||
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ":" + ss + ")\n";
|
||||
} else {
|
||||
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
|
||||
}
|
||||
cerr << err << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::compile_cg_parameter
|
||||
// Access: Public
|
||||
// Description: Analyzes a Cg parameter and decides how to
|
||||
// bind the parameter to some part of panda's
|
||||
// internal state. Updates one of the cg bind
|
||||
// arrays to cause the binding to occur.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ShaderContext)::
|
||||
compile_cg_parameter(CGparameter p)
|
||||
{
|
||||
string pname = cgGetParameterName(p);
|
||||
if (pname.size() == 0) return true;
|
||||
if (pname[0] == '$') return true;
|
||||
vector_string pieces;
|
||||
tokenize(pname, pieces, "_");
|
||||
|
||||
if (pieces[0] == "vtx") {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_VARYING)) ||
|
||||
(!errchk_cg_parameter_prog(p, _cg_program[VERT_SHADER], "vertex")))
|
||||
return false;
|
||||
if (pieces[1] == "position") {
|
||||
if (!errchk_cg_parameter_semantic(p,"POSITION")) return false;
|
||||
if (!errchk_cg_parameter_float(p)) return false;
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
if (pieces[1] == "normal") {
|
||||
if (!errchk_cg_parameter_semantic(p,"NORMAL")) return false;
|
||||
if (!errchk_cg_parameter_float(p)) return false;
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
if (pieces[1] == "color") {
|
||||
if (!errchk_cg_parameter_semantic(p,"COLOR")) return false;
|
||||
if (!errchk_cg_parameter_float(p)) return false;
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
if (pieces[1].substr(0,8) == "texcoord") {
|
||||
string ss = upcase(pieces[1]);
|
||||
if (!errchk_cg_parameter_semantic(p,ss)) return false;
|
||||
if (!errchk_cg_parameter_float(p)) return false;
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
// Handle an arbitrary column taken from the vertex array.
|
||||
// IMPLEMENT ME.
|
||||
errchk_cg_output(p, "Arbitrary vertex fields not implemented yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pieces[0] == "trans")||
|
||||
(pieces[0] == "tpose")||
|
||||
(pieces[0] == "row0")||
|
||||
(pieces[0] == "row1")||
|
||||
(pieces[0] == "row2")||
|
||||
(pieces[0] == "row3")||
|
||||
(pieces[0] == "col0")||
|
||||
(pieces[0] == "col1")||
|
||||
(pieces[0] == "col2")||
|
||||
(pieces[0] == "col3")||
|
||||
(pieces[0] == "xvec")||
|
||||
(pieces[0] == "yvec")||
|
||||
(pieces[0] == "zvec")||
|
||||
(pieces[0] == "pos")) {
|
||||
if ((!errchk_cg_parameter_words(p,4)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||
(!errchk_cg_parameter_semantic(p, "")))
|
||||
return false;
|
||||
if (pieces[2] != "rel") {
|
||||
errchk_cg_output(p, "syntax error");
|
||||
return false;
|
||||
}
|
||||
ShaderTransBind bind;
|
||||
bind.parameter = p;
|
||||
|
||||
if (pieces[0]=="trans") bind.trans_piece = TRANS_NORMAL;
|
||||
else if (pieces[0]=="tpose") bind.trans_piece = TRANS_TPOSE;
|
||||
else if (pieces[0]=="row0") bind.trans_piece = TRANS_ROW0;
|
||||
else if (pieces[0]=="row1") bind.trans_piece = TRANS_ROW1;
|
||||
else if (pieces[0]=="row2") bind.trans_piece = TRANS_ROW2;
|
||||
else if (pieces[0]=="row3") bind.trans_piece = TRANS_ROW3;
|
||||
else if (pieces[0]=="col0") bind.trans_piece = TRANS_COL0;
|
||||
else if (pieces[0]=="col1") bind.trans_piece = TRANS_COL1;
|
||||
else if (pieces[0]=="col2") bind.trans_piece = TRANS_COL2;
|
||||
else if (pieces[0]=="col3") bind.trans_piece = TRANS_COL3;
|
||||
else if (pieces[0]=="xvec") bind.trans_piece = TRANS_ROW0;
|
||||
else if (pieces[0]=="yvec") bind.trans_piece = TRANS_ROW1;
|
||||
else if (pieces[0]=="zvec") bind.trans_piece = TRANS_ROW2;
|
||||
else if (pieces[0]=="pos") bind.trans_piece = TRANS_ROW3;
|
||||
|
||||
if (pieces[1] == "world") bind.src_argindex = ARGINDEX_WORLD;
|
||||
else if (pieces[1] == "camera") bind.src_argindex = ARGINDEX_CAMERA;
|
||||
else if (pieces[1] == "model") bind.src_argindex = ARGINDEX_MODEL;
|
||||
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
||||
if (pieces[3] == "world") bind.rel_argindex = ARGINDEX_WORLD;
|
||||
else if (pieces[3] == "camera") bind.rel_argindex = ARGINDEX_CAMERA;
|
||||
else if (pieces[3] == "model") bind.rel_argindex = ARGINDEX_MODEL;
|
||||
else bind.rel_argindex = _shader->arg_index(pieces[3]);
|
||||
|
||||
if ((bind.trans_piece == TRANS_NORMAL)||(bind.trans_piece == TRANS_TPOSE)) {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||
} else {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||
}
|
||||
|
||||
_cg_trans_bind.push_back(bind);
|
||||
if ((bind.src_argindex == ARGINDEX_MODEL) ||
|
||||
(bind.rel_argindex == ARGINDEX_MODEL)) {
|
||||
_cg_trans_rebind.push_back(bind);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((pieces[0]=="mstrans")||
|
||||
(pieces[0]=="cstrans")||
|
||||
(pieces[0]=="wstrans")||
|
||||
(pieces[0]=="mspos")||
|
||||
(pieces[0]=="cspos")||
|
||||
(pieces[0]=="wspos")) {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||
(!errchk_cg_parameter_semantic(p, "")))
|
||||
return false;
|
||||
ShaderTransBind bind;
|
||||
bind.parameter = p;
|
||||
|
||||
if (pieces[0]=="wstrans") { bind.rel_argindex = ARGINDEX_WORLD; bind.trans_piece = TRANS_NORMAL; }
|
||||
else if (pieces[0]=="cstrans") { bind.rel_argindex = ARGINDEX_CAMERA; bind.trans_piece = TRANS_NORMAL; }
|
||||
else if (pieces[0]=="mstrans") { bind.rel_argindex = ARGINDEX_MODEL; bind.trans_piece = TRANS_NORMAL; }
|
||||
else if (pieces[0]=="wspos") { bind.rel_argindex = ARGINDEX_WORLD; bind.trans_piece = TRANS_ROW3; }
|
||||
else if (pieces[0]=="cspos") { bind.rel_argindex = ARGINDEX_CAMERA; bind.trans_piece = TRANS_ROW3; }
|
||||
else if (pieces[0]=="mspos") { bind.rel_argindex = ARGINDEX_MODEL; bind.trans_piece = TRANS_ROW3; }
|
||||
|
||||
if (pieces[1] == "world") bind.src_argindex = ARGINDEX_WORLD;
|
||||
else if (pieces[1] == "camera") bind.src_argindex = ARGINDEX_CAMERA;
|
||||
else if (pieces[1] == "model") bind.src_argindex = ARGINDEX_MODEL;
|
||||
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
||||
|
||||
if ((bind.trans_piece == TRANS_NORMAL)||(bind.trans_piece == TRANS_TPOSE)) {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||
} else {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||
}
|
||||
_cg_trans_bind.push_back(bind);
|
||||
if ((bind.src_argindex == ARGINDEX_MODEL) ||
|
||||
(bind.rel_argindex == ARGINDEX_MODEL)) {
|
||||
_cg_trans_rebind.push_back(bind);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((pieces[0]=="mat")||
|
||||
(pieces[0]=="inv")||
|
||||
(pieces[0]=="tps")||
|
||||
(pieces[0]=="itp")) {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||
(!errchk_cg_parameter_type(p, CG_FLOAT4x4)))
|
||||
return false;
|
||||
ShaderAutoBind bind;
|
||||
bind.parameter = p;
|
||||
if (pieces[1] == "modelview") bind.matrix = CG_GL_MODELVIEW_MATRIX;
|
||||
else if (pieces[1] == "projection") bind.matrix = CG_GL_PROJECTION_MATRIX;
|
||||
else if (pieces[1] == "texmatrix") bind.matrix = CG_GL_TEXTURE_MATRIX;
|
||||
else if (pieces[1] == "modelproj") bind.matrix = CG_GL_MODELVIEW_PROJECTION_MATRIX;
|
||||
else {
|
||||
errchk_cg_output(p, "unrecognized matrix name");
|
||||
return false;
|
||||
}
|
||||
if (pieces[0]=="mat") bind.orientation = CG_GL_MATRIX_IDENTITY;
|
||||
else if (pieces[0]=="inv") bind.orientation = CG_GL_MATRIX_INVERSE;
|
||||
else if (pieces[0]=="tps") bind.orientation = CG_GL_MATRIX_TRANSPOSE;
|
||||
else if (pieces[0]=="itp") bind.orientation = CG_GL_MATRIX_INVERSE_TRANSPOSE;
|
||||
_cg_autobind.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "tex") {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||
(!errchk_cg_parameter_sampler(p)))
|
||||
return false;
|
||||
if (cgGetParameterSemantic(p)[0]!=0) {
|
||||
string texunit = "TEX"+upcase(pieces[1]);
|
||||
if (!errchk_cg_parameter_semantic(p, texunit)) return false;
|
||||
}
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
|
||||
if (pieces[0] == "k") {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
|
||||
return false;
|
||||
ShaderArgBind bind;
|
||||
bind.parameter = p;
|
||||
bind.argindex = _shader->arg_index(pieces[1]);
|
||||
switch (cgGetParameterType(p)) {
|
||||
case CG_FLOAT1: _cg_vbind1.push_back(bind); break;
|
||||
case CG_FLOAT2: _cg_vbind2.push_back(bind); break;
|
||||
case CG_FLOAT3: _cg_vbind3.push_back(bind); break;
|
||||
case CG_FLOAT4: _cg_vbind4.push_back(bind); break;
|
||||
case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
|
||||
case CG_SAMPLER3D: _cg_tbind3d.push_back(bind); break;
|
||||
case CG_FLOAT4x4: _cg_npbind.push_back(bind); break;
|
||||
default:
|
||||
errchk_cg_output(p, "Invalid type for a k-parameter");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pieces[0] == "l") {
|
||||
// IMPLEMENT THE ERROR CHECKING
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
|
||||
if (pieces[0] == "o") {
|
||||
// IMPLEMENT THE ERROR CHECKING
|
||||
return true; // Cg handles this automatically.
|
||||
}
|
||||
|
||||
errchk_cg_output(p, "unrecognized parameter name");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -21,8 +21,7 @@
|
||||
#ifdef HAVE_CGGL
|
||||
#include "Cg/cgGL.h"
|
||||
#endif
|
||||
|
||||
class CLP(GraphicsStateGuardian);
|
||||
#include "string_utils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLShaderContext
|
||||
@ -31,23 +30,81 @@ class CLP(GraphicsStateGuardian);
|
||||
|
||||
class EXPCL_GL CLP(ShaderContext): public ShaderContext {
|
||||
public:
|
||||
CLP(ShaderContext)(CLP(GraphicsStateGuardian) *gsg, Shader *shader);
|
||||
CLP(ShaderContext)(Shader *s);
|
||||
~CLP(ShaderContext)();
|
||||
|
||||
INLINE void bind(ShaderMode *mode);
|
||||
INLINE void unbind();
|
||||
INLINE void rebind(ShaderMode *oldmode, ShaderMode *newmode);
|
||||
INLINE bool valid(void);
|
||||
void bind(ShaderMode *mode, GraphicsStateGuardianBase *gsg);
|
||||
void unbind();
|
||||
void rebind(ShaderMode *oldmode, ShaderMode *newmode);
|
||||
|
||||
bool _valid;
|
||||
|
||||
private:
|
||||
CLP(GraphicsStateGuardian) *_gsg;
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
CGprogram _cg_vprogram;
|
||||
CGprogram _cg_fprogram;
|
||||
enum {
|
||||
ARGINDEX_WORLD =-1,
|
||||
ARGINDEX_CAMERA=-2,
|
||||
ARGINDEX_MODEL =-3
|
||||
};
|
||||
enum {
|
||||
TRANS_NORMAL,
|
||||
TRANS_TPOSE,
|
||||
TRANS_ROW0,
|
||||
TRANS_ROW1,
|
||||
TRANS_ROW2,
|
||||
TRANS_ROW3,
|
||||
TRANS_COL0,
|
||||
TRANS_COL1,
|
||||
TRANS_COL2,
|
||||
TRANS_COL3,
|
||||
};
|
||||
struct ShaderAutoBind {
|
||||
CGparameter parameter;
|
||||
CGGLenum matrix;
|
||||
CGGLenum orientation;
|
||||
};
|
||||
struct ShaderArgBind {
|
||||
CGparameter parameter;
|
||||
int argindex;
|
||||
};
|
||||
struct ShaderTransBind {
|
||||
CGparameter parameter;
|
||||
int src_argindex;
|
||||
int rel_argindex;
|
||||
int trans_piece;
|
||||
};
|
||||
CGcontext _cg_context;
|
||||
CGprofile _cg_profile[2];
|
||||
CGprogram _cg_program[2];
|
||||
int _cg_linebase[2];
|
||||
|
||||
// These arrays contain lists of "bindings." They
|
||||
// tell us how to fill the shader's input parameters.
|
||||
vector <ShaderAutoBind> _cg_autobind;
|
||||
vector <ShaderArgBind> _cg_tbind2d;
|
||||
vector <ShaderArgBind> _cg_tbind3d;
|
||||
vector <ShaderArgBind> _cg_vbind1;
|
||||
vector <ShaderArgBind> _cg_vbind2;
|
||||
vector <ShaderArgBind> _cg_vbind3;
|
||||
vector <ShaderArgBind> _cg_vbind4;
|
||||
vector <ShaderArgBind> _cg_npbind;
|
||||
vector <ShaderTransBind> _cg_trans_bind;
|
||||
vector <ShaderTransBind> _cg_trans_rebind;
|
||||
|
||||
bool compile_cg_parameter(CGparameter p);
|
||||
bool errchk_cg_parameter_words(CGparameter p, int len);
|
||||
bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);
|
||||
bool errchk_cg_parameter_variance(CGparameter p, CGenum var);
|
||||
bool errchk_cg_parameter_prog(CGparameter p, CGprogram prog, const string &msg);
|
||||
bool errchk_cg_parameter_semantic(CGparameter p, const string &semantic);
|
||||
bool errchk_cg_parameter_type(CGparameter p, CGtype dt);
|
||||
bool errchk_cg_parameter_float(CGparameter p);
|
||||
bool errchk_cg_parameter_sampler(CGparameter p);
|
||||
void errchk_cg_output(CGparameter p, const string &msg);
|
||||
#endif
|
||||
|
||||
void release_resources(void);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -115,6 +115,19 @@ parse_rest(string &result) {
|
||||
result = _text.substr(_parse, _text.size() - _parse);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::parse_lineno
|
||||
// Access: Public
|
||||
// Description: Returns the line number of the current parse pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Shader::
|
||||
parse_lineno() {
|
||||
int result = 1;
|
||||
for (int i=0; i<_parse; i++)
|
||||
if (_text[i] == '\n') result += 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::parse_eof
|
||||
// Access: Public
|
||||
@ -277,3 +290,4 @@ void Shader::
|
||||
register_with_read_factory() {
|
||||
// IMPLEMENT ME
|
||||
}
|
||||
|
||||
|
@ -61,13 +61,17 @@ PUBLISHED:
|
||||
int release_all();
|
||||
|
||||
PUBLISHED:
|
||||
// These routines help split the shader into sections,
|
||||
// for those shader implementations that need to do so.
|
||||
void parse_init();
|
||||
void parse_line(string &result, bool rt, bool lt);
|
||||
void parse_upto(string &result, string pattern, bool include);
|
||||
void parse_rest(string &result);
|
||||
int parse_lineno();
|
||||
bool parse_eof();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
INLINE int arg_count();
|
||||
int arg_index(const string &id);
|
||||
|
||||
|
@ -41,6 +41,12 @@ public:
|
||||
INLINE ShaderContext(Shader *shader);
|
||||
|
||||
Shader *_shader;
|
||||
|
||||
enum {
|
||||
VERT_SHADER=0,
|
||||
FRAG_SHADER=1,
|
||||
BOTH_SHADER=2,
|
||||
};
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user