open_toontown_panda3d/panda/src/effects/cgShader.cxx

404 lines
14 KiB
C++
Executable File

// Filename: cgShader.cxx
// Created by: sshodhan (10Jul04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#ifdef HAVE_CG
#include "cgShader.h"
#include "config_effects.h"
TypeHandle CgShader::_type_handle;
#include <Cg/cg.h>
////////////////////////////////////////////////////////////////////
// Function: CgShader::init_cg
// Access: Published
// Description: Create a cgContext. Note that this is completely
// different from Panda's CgShaderContext and its
// derived GLCgShaderContext (or Dx9CgShaderContext)
// This is a Cg API specific context.
////////////////////////////////////////////////////////////////////
bool CgShader::
init_cg() {
// Create a new context for our Cg Program(s)
cgContext = cgCreateContext();
if (cgContext == NULL) {
cerr << "COULD NOT CREATE CG CONTEXT" << "\n" ;
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CgShader::load_shaders
// Access: Published
// Description: this is called after the instantiating a
// CgShaderContext because we need the profiles
// which are initiated by a GL or DX specific
// CgShaderContext.
////////////////////////////////////////////////////////////////////
bool CgShader::
load_shaders(){
// Load And Compile the shaders from file
cgVertexProgram = cgCreateProgramFromFile(cgContext,
CG_SOURCE, _vertex_shader.c_str(), cgVertexProfile, "main", 0);
cgFragmentProgram = cgCreateProgramFromFile(cgContext,
CG_SOURCE, _fragment_shader.c_str(), cgFragmentProfile, "main", 0);
// Validate Success
if (cgVertexProgram == NULL) {
// We Need To Determine What Went Wrong
CGerror Error = cgGetError();
printf("VERTEX SHADER ERROR %s",cgGetErrorString(Error));
return false;
}
if (cgFragmentProgram == NULL) {
// We Need To Determine What Went Wrong
CGerror Error = cgGetError();
printf("PIXEL SHADER ERROR %s",cgGetErrorString(Error));
return false;
}
// Now that our programs are loaded we can actually
// access their handles with cgGetNamedParameter
// The python programmer specifies parameter names and
// handle names when he calles add_param
// So lets go through all the handles and associate them with
// CGparameter objects
HANDLES::const_iterator param_iter; // Use this to go through all params
// Matrix handles
// Vertex
for (param_iter = _vertex_matrix_handles.begin();
param_iter !=_vertex_matrix_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_matrix_params.insert(vert_param);
}
// Fragment
for (param_iter = _fragment_matrix_handles.begin();
param_iter != _fragment_matrix_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_matrix_params.insert(frag_param);
}
// Texture handles
// Vertex
for (param_iter = _vertex_texture_handles.begin();
param_iter != _vertex_texture_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_texture_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_texture_handles.begin();
param_iter != _fragment_texture_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_texture_params.insert(frag_param);
}
// 1F handles
// Vertex
for (param_iter = _vertex_1f_handles.begin();
param_iter != _vertex_1f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_1f_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_1f_handles.begin();
param_iter != _fragment_1f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_1f_params.insert(frag_param);
}
// 2F handles
// Vertex
for (param_iter = _vertex_2f_handles.begin();
param_iter != _vertex_2f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_2f_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_2f_handles.begin();
param_iter != _fragment_2f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_2f_params.insert(frag_param);
}
// 3F handles
// Vertex
for (param_iter = _vertex_3f_handles.begin();
param_iter != _vertex_3f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_3f_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_3f_handles.begin();
param_iter != _fragment_3f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_3f_params.insert(frag_param);
}
// 4F handles
// Vertex
for (param_iter = _vertex_4f_handles.begin();
param_iter != _vertex_4f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_4f_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_4f_handles.begin();
param_iter != _fragment_4f_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_4f_params.insert(frag_param);
}
// 1D handles
// Vertex
for (param_iter = _vertex_1d_handles.begin();
param_iter != _vertex_1d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_1d_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_1d_handles.begin();
param_iter != _fragment_1d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_1d_params.insert(frag_param);
}
// 2D handles
// Vertex
for (param_iter = _vertex_2d_handles.begin();
param_iter != _vertex_2d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_2d_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_2d_handles.begin();
param_iter != _fragment_2d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_2d_params.insert(frag_param);
}
// 3D handles
// Vertex
for (param_iter = _vertex_3d_handles.begin();
param_iter != _vertex_3d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_3d_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_3d_handles.begin();
param_iter != _fragment_3d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_3d_params.insert(frag_param);
}
// 4D handles
// Vertex
for (param_iter = _vertex_4d_handles.begin();
param_iter != _vertex_4d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgVertexProgram, param_iter->second.c_str());
CGPARAMETER::value_type vert_param(param_iter->first, p);
_vertex_4d_params.insert(vert_param);
}
//Fragment
for (param_iter = _fragment_4d_handles.begin();
param_iter != _fragment_4d_handles.end(); param_iter++) {
p = cgGetNamedParameter(cgFragmentProgram, param_iter->second.c_str());
CGPARAMETER::value_type frag_param(param_iter->first, p);
_fragment_4d_params.insert(frag_param);
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: CgShader::Constructor
// Access: Published
// Description: Use to construct a new CgShader object.
// Pass filenames for the vertex and fragment programs
////////////////////////////////////////////////////////////////////
CgShader::
CgShader(const string &name, const string &vertex_shader,
const string &fragment_shader) {
_name = name;
_vertex_shader = vertex_shader;
_fragment_shader = fragment_shader;
bool res = init_cg();
}
////////////////////////////////////////////////////////////////////
// Function: CgShader::Destructor
// Access: Public
// Description: We need to clean up the CGcontext
////////////////////////////////////////////////////////////////////
CgShader::
~CgShader() {
cgDestroyContext(cgContext);
}
////////////////////////////////////////////////////////////////////
// Function: CgShader::add_param
// Access: Published
// Description: Add a new parameter
// Specify its name, name in the shader program (handle name)
// bind type, parameter type and whether its a vertex
// or fragment parameter
////////////////////////////////////////////////////////////////////
void CgShader::
add_param(const string &pname, const string &handle_name,
Param_Type t, Bind_Type b, bool vert_or_frag) {
/* We have only per-frame binding
if (b == BONCE) {
_bind_once.push_back(pname);
} else if (b == BFRAME) {
_bind_frame.push_back(pname);
} else if (b == BVERTEX) {
_bind_vertex.push_back(pname);
}
*/
// Add to the <parameter name, handle name> map
// Later, once we have loaded the cg programs
// this handles map is traversed and associations
// are made with the CGparameter objects
// using the cgGetNamedParameter function
if (t == P1F) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_1f_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_1f_handles.insert(param_handle);
}
}else if (t == P2F) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_2f_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_2f_handles.insert(param_handle);
}
}else if (t == P3F) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_3f_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_3f_handles.insert(param_handle);
}
}else if (t == P4F) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_4f_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_4f_handles.insert(param_handle);
}
}else if (t == P1D) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_1d_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_1d_handles.insert(param_handle);
}
}else if (t == P2D) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_2d_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_2d_handles.insert(param_handle);
}
}else if (t == P3D) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_3d_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_3d_handles.insert(param_handle);
}
}else if (t == P4D) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_4d_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_4d_handles.insert(param_handle);
}
} else if (t == PTEXTURE) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_texture_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_texture_handles.insert(param_handle);
}
} else if (t == PMATRIX) {
if (vert_or_frag) {
HANDLES::value_type param_handle(pname, handle_name);
_vertex_matrix_handles.insert(param_handle);
} else {
HANDLES::value_type param_handle(pname, handle_name);
_fragment_matrix_handles.insert(param_handle);
}
}
}
#endif // HAVE_CG