mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 12:12:10 -04:00
Major overhaul to shader subsystem
This commit is contained in:
parent
43bbca86fb
commit
129cef9f62
@ -2296,7 +2296,7 @@ EnqueueIgate(ipath=IPATH, opts=OPTS, outd='libpstatclient.in', obj='libpstatclie
|
||||
#
|
||||
|
||||
IPATH=['panda/src/gobj']
|
||||
OPTS=['BUILDING_PANDA', 'NSPR']
|
||||
OPTS=['BUILDING_PANDA', 'NSPR', 'NVIDIACG']
|
||||
CopyAllHeaders('panda/src/gobj')
|
||||
EnqueueCxx(ipath=IPATH, opts=OPTS, src='gobj_composite1.cxx', obj='gobj_composite1.obj')
|
||||
EnqueueCxx(ipath=IPATH, opts=OPTS, src='gobj_composite2.cxx', obj='gobj_composite2.obj')
|
||||
@ -2572,7 +2572,7 @@ CopyAllHeaders('panda/src/physics')
|
||||
CopyAllHeaders('panda/src/particlesystem')
|
||||
IPATH=['panda/metalibs/panda']
|
||||
OPTS=['BUILDING_PANDA', 'ZLIB', 'VRPN', 'JPEG', 'PNG', 'TIFF', 'NSPR', 'FREETYPE', 'HELIX', 'FFTW', 'OPENCV',
|
||||
'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM']
|
||||
'ADVAPI', 'WINSOCK2', 'WINUSER', 'WINMM', 'NVIDIACG']
|
||||
INFILES=['librecorder.in', 'libpgraph.in', 'libgrutil.in', 'libchan.in', 'libpstatclient.in',
|
||||
'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libevent.in',
|
||||
'libgobj.in', 'libgsgbase.in', 'liblinmath.in', 'libmathutil.in', 'libparametrics.in',
|
||||
|
@ -103,6 +103,11 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
_current_display_region = (DisplayRegion*)0L;
|
||||
_current_stereo_channel = Lens::SC_mono;
|
||||
_current_lens = (Lens *)NULL;
|
||||
_projection_mat = TransformState::make_identity();
|
||||
_projection_mat_inv = TransformState::make_identity();
|
||||
_clip_to_view = TransformState::make_identity();
|
||||
_view_to_clip = TransformState::make_identity();
|
||||
|
||||
_needs_reset = true;
|
||||
_is_valid = false;
|
||||
_closing_gsg = false;
|
||||
@ -363,6 +368,15 @@ set_scene(SceneSetup *scene_setup) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_projection_mat = calc_projection_mat(_current_lens);
|
||||
if (_projection_mat == 0) {
|
||||
return false;
|
||||
}
|
||||
_projection_mat_inv = _projection_mat->get_inverse();
|
||||
_view_to_clip = TransformState::make_mat(_current_lens->
|
||||
get_projection_mat(_coordinate_system, _current_stereo_channel));
|
||||
_clip_to_view = TransformState::make_mat(_current_lens->
|
||||
get_projection_mat_inv(_coordinate_system, _current_stereo_channel));
|
||||
return prepare_lens();
|
||||
}
|
||||
|
||||
@ -636,6 +650,206 @@ clear(DrawableRegion *clearable) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::fetch_specified_value
|
||||
// Access: Public
|
||||
// Description: The gsg contains a large number of useful matrices:
|
||||
//
|
||||
// * the world transform,
|
||||
// * the modelview matrix,
|
||||
// * the cs_transform,
|
||||
// * etc, etc.
|
||||
//
|
||||
// A shader can request any of these values, and
|
||||
// furthermore, it can request that various compositions,
|
||||
// inverses, and transposes be performed. The
|
||||
// ShaderMatSpec is a data structure indicating what
|
||||
// datum is desired and what conversions to perform.
|
||||
// This routine, fetch_specified_value, is responsible for
|
||||
// doing the actual retrieval and conversions.
|
||||
//
|
||||
// Some values, like the following, aren't matrices:
|
||||
//
|
||||
// * window size
|
||||
// * texture coordinates of card center
|
||||
//
|
||||
// This routine can fetch these values as well, by
|
||||
// shoehorning them into a matrix. In this way, we avoid
|
||||
// the need for a separate routine to fetch these values.
|
||||
//
|
||||
// This routine is actually a simple pcode-interpreter,
|
||||
// and the ShaderMatSpec is actually a small pcode-array.
|
||||
// This makes it possible to express requests for a
|
||||
// large variety of values, and a large variety of
|
||||
// possible conversions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
fetch_specified_value(const ShaderContext::ShaderMatSpec &spec, LMatrix4f &result) {
|
||||
pvector<LMatrix4f> stack;
|
||||
int pc = 0;
|
||||
int ac = 0;
|
||||
while (pc < (int)spec._opcodes.size()) {
|
||||
int opcode = spec._opcodes[pc++];
|
||||
switch(opcode) {
|
||||
case ShaderContext::SMO_identity: {
|
||||
stack.push_back(LMatrix4f::ident_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_modelview: {
|
||||
stack.push_back(_internal_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_projection: {
|
||||
stack.push_back(_projection_mat->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_modelproj: {
|
||||
stack.push_back(_internal_transform->get_mat() * _projection_mat->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_window_size: {
|
||||
stack.push_back(LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_pixel_size: {
|
||||
stack.push_back(LMatrix4f::translate_mat(_current_display_region->get_pixel_width(),
|
||||
_current_display_region->get_pixel_height(),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_card_center: {
|
||||
int px = _current_display_region->get_pixel_width();
|
||||
int py = _current_display_region->get_pixel_height();
|
||||
stack.push_back(LMatrix4f::translate_mat((px*0.5) / Texture::up_to_power_2(px),
|
||||
(py*0.5) / Texture::up_to_power_2(py),
|
||||
0.0));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_mat_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
if (input->get_nodepath().is_empty()) {
|
||||
return false;
|
||||
}
|
||||
stack.push_back(input->get_nodepath().node()->get_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_vec_constant_x: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
const float *data = input->get_vector().get_data();
|
||||
stack.push_back(LMatrix4f(data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3],
|
||||
data[0],data[1],data[2],data[3]));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_world_to_view: {
|
||||
stack.push_back(get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_world_C: {
|
||||
stack.back() *= get_scene()->get_camera_transform()->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_model_to_view: {
|
||||
stack.push_back(_external_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_model_C: {
|
||||
stack.back() *= invert(_external_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_to_view: {
|
||||
stack.push_back(_inv_cs_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview_C: {
|
||||
stack.back() *= _cs_transform->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_clip_to_view: {
|
||||
stack.push_back(_clip_to_view->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_clip_C: {
|
||||
stack.back() *= _view_to_clip->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_to_view: {
|
||||
stack.push_back(_projection_mat_inv->get_mat() * _inv_cs_transform->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip_C: {
|
||||
stack.back() *= _cs_transform->get_mat() * _projection_mat->get_mat();
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.push_back(input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_view_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiview_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.push_back(LMatrix4f::convert_mat(_internal_coordinate_system, _coordinate_system) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiview_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
LMatrix4f::convert_mat(_coordinate_system, _internal_coordinate_system));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_clip_x_to_view: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
stack.push_back(lens->get_projection_mat_inv(_coordinate_system, _current_stereo_channel) *
|
||||
input->get_nodepath().get_net_transform()->get_mat() *
|
||||
get_scene()->get_world_transform()->get_mat());
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_clip_x_C: {
|
||||
const ShaderInput *input = _target._shader->get_shader_input(spec._args[ac++]);
|
||||
nassertr(!input->get_nodepath().is_empty(), false);
|
||||
Lens *lens = DCAST(LensNode, input->get_nodepath().node())->get_lens();
|
||||
stack.back()*= (get_scene()->get_camera_transform()->get_mat() *
|
||||
invert(input->get_nodepath().get_net_transform()->get_mat()) *
|
||||
lens->get_projection_mat(_coordinate_system, _current_stereo_channel));
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_apiclip_x_to_view: {
|
||||
// NOT IMPLEMENTED
|
||||
break;
|
||||
}
|
||||
case ShaderContext::SMO_view_to_apiclip_x_C: {
|
||||
// NOT IMPLEMENTED
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderContext::SMO_transpose:
|
||||
stack.back().transpose_in_place();
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = stack.back();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::prepare_display_region
|
||||
// Access: Public, Virtual
|
||||
@ -1832,3 +2046,24 @@ traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),vo
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::calc_projection_mat
|
||||
// Access: Public, Virtual
|
||||
// Description: Given a lens, this function calculates the appropriate
|
||||
// projection matrix for this gsg. The result depends
|
||||
// on the peculiarities of the rendering API.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) GraphicsStateGuardian::
|
||||
calc_projection_mat(const Lens *lens) {
|
||||
if (lens == (Lens *)NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!lens->is_linear()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TransformState::make_identity();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "notify.h"
|
||||
#include "pvector.h"
|
||||
#include "attribSlots.h"
|
||||
#include "shaderContext.h"
|
||||
|
||||
class DrawableRegion;
|
||||
class GraphicsEngine;
|
||||
@ -158,8 +159,12 @@ public:
|
||||
|
||||
void clear(DrawableRegion *clearable);
|
||||
|
||||
bool fetch_specified_value(const ShaderContext::ShaderMatSpec &spec, LMatrix4f &result);
|
||||
|
||||
virtual void prepare_display_region(DisplayRegion *dr,
|
||||
Lens::StereoChannel stereo_channel);
|
||||
|
||||
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
|
||||
virtual bool prepare_lens();
|
||||
|
||||
virtual bool begin_frame();
|
||||
@ -198,7 +203,7 @@ public:
|
||||
|
||||
INLINE const TransformState *get_cs_transform() const;
|
||||
INLINE const TransformState *get_inv_cs_transform() const;
|
||||
|
||||
|
||||
void do_issue_clip_plane();
|
||||
void do_issue_color();
|
||||
void do_issue_color_scale();
|
||||
@ -288,7 +293,11 @@ protected:
|
||||
CPT(DisplayRegion) _current_display_region;
|
||||
Lens::StereoChannel _current_stereo_channel;
|
||||
CPT(Lens) _current_lens;
|
||||
|
||||
CPT(TransformState) _projection_mat;
|
||||
CPT(TransformState) _projection_mat_inv;
|
||||
CPT(TransformState) _view_to_clip;
|
||||
CPT(TransformState) _clip_to_view;
|
||||
|
||||
CoordinateSystem _coordinate_system;
|
||||
CoordinateSystem _internal_coordinate_system;
|
||||
CPT(TransformState) _cs_transform;
|
||||
|
@ -2058,22 +2058,22 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
data = total->get_mat().get_data();
|
||||
switch (stb.trans_piece) {
|
||||
/*
|
||||
case SHADER_data_matrix: cgD3D9SetMatrixParameterfc(stb.parameter, data); break;
|
||||
case SHADER_data_transpose: cgD3D9SetMatrixParameterfr(stb.parameter, data); break;
|
||||
case SHADER_data_row0: cgD3D9SetParameter4fv(stb.parameter, data+ 0); break;
|
||||
case SHADER_data_row1: cgD3D9SetParameter4fv(stb.parameter, data+ 4); break;
|
||||
case SHADER_data_row2: cgD3D9SetParameter4fv(stb.parameter, data+ 8); break;
|
||||
case SHADER_data_row3: cgD3D9SetParameter4fv(stb.parameter, data+12); break;
|
||||
case SHADER_data_col0: cgD3D9SetParameter4f(stb.parameter, data[0], data[4], data[ 8], data[12]); break;
|
||||
case SHADER_data_col1: cgD3D9SetParameter4f(stb.parameter, data[1], data[5], data[ 9], data[13]); break;
|
||||
case SHADER_data_col2: cgD3D9SetParameter4f(stb.parameter, data[2], data[6], data[10], data[14]); break;
|
||||
case SHADER_data_col3: cgD3D9SetParameter4f(stb.parameter, data[3], data[7], data[11], data[15]); break;
|
||||
case SMP_whole: cgD3D9SetMatrixParameterfc(stb.parameter, data); break;
|
||||
case SMP_transpose: cgD3D9SetMatrixParameterfr(stb.parameter, data); break;
|
||||
case SMP_row0: cgD3D9SetParameter4fv(stb.parameter, data+ 0); break;
|
||||
case SMP_row1: cgD3D9SetParameter4fv(stb.parameter, data+ 4); break;
|
||||
case SMP_row2: cgD3D9SetParameter4fv(stb.parameter, data+ 8); break;
|
||||
case SMP_row3: cgD3D9SetParameter4fv(stb.parameter, data+12); break;
|
||||
case SMP_col0: cgD3D9SetParameter4f(stb.parameter, data[0], data[4], data[ 8], data[12]); break;
|
||||
case SMP_col1: cgD3D9SetParameter4f(stb.parameter, data[1], data[5], data[ 9], data[13]); break;
|
||||
case SMP_col2: cgD3D9SetParameter4f(stb.parameter, data[2], data[6], data[10], data[14]); break;
|
||||
case SMP_col3: cgD3D9SetParameter4f(stb.parameter, data[3], data[7], data[11], data[15]); break;
|
||||
*/
|
||||
|
||||
float vector [4];
|
||||
float matrix [16];
|
||||
|
||||
case SHADER_data_matrix:
|
||||
case SMP_whole:
|
||||
if (_cg_shader) {
|
||||
cgD3D9SetUniform (stb.parameter, data);
|
||||
}
|
||||
@ -2081,7 +2081,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, data, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_transpose:
|
||||
case SMP_transpose:
|
||||
matrix [0] = data[0];
|
||||
matrix [1] = data[4];
|
||||
matrix [2] = data[8];
|
||||
@ -2105,7 +2105,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, matrix, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_row0:
|
||||
case SMP_row0:
|
||||
if (_cg_shader) {
|
||||
cgD3D9SetUniform (stb.parameter, data);
|
||||
}
|
||||
@ -2113,7 +2113,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, data, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_row1:
|
||||
case SMP_row1:
|
||||
if (_cg_shader) {
|
||||
cgD3D9SetUniform (stb.parameter, data + 4);
|
||||
}
|
||||
@ -2121,7 +2121,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, data + 4, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_row2:
|
||||
case SMP_row2:
|
||||
if (_cg_shader) {
|
||||
cgD3D9SetUniform (stb.parameter, data + 8);
|
||||
}
|
||||
@ -2129,7 +2129,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, data + 8, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_row3:
|
||||
case SMP_row3:
|
||||
if (_cg_shader) {
|
||||
cgD3D9SetUniform (stb.parameter, data + 12);
|
||||
}
|
||||
@ -2137,7 +2137,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, data + 12, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_col0:
|
||||
case SMP_col0:
|
||||
vector [0] = data[0];
|
||||
vector [1] = data[4];
|
||||
vector [2] = data[8];
|
||||
@ -2149,7 +2149,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_col1:
|
||||
case SMP_col1:
|
||||
vector [0] = data[1];
|
||||
vector [1] = data[5];
|
||||
vector [2] = data[9];
|
||||
@ -2161,7 +2161,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_col2:
|
||||
case SMP_col2:
|
||||
vector [0] = data[2];
|
||||
vector [1] = data[6];
|
||||
vector [2] = data[10];
|
||||
@ -2173,7 +2173,7 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
||||
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||
}
|
||||
break;
|
||||
case SHADER_data_col3:
|
||||
case SMP_col3:
|
||||
vector [0] = data[3];
|
||||
vector [1] = data[7];
|
||||
vector [2] = data[11];
|
||||
@ -2499,21 +2499,21 @@ compile_cg_parameter(CGparameter p, DX_PARAMETER *dx_parameter)
|
||||
bind.parameter = p;
|
||||
bind.dx_parameter = dx_parameter;
|
||||
|
||||
if (pieces[0]=="trans") bind.trans_piece = SHADER_data_matrix;
|
||||
else if (pieces[0]=="tpose") bind.trans_piece = SHADER_data_transpose;
|
||||
else if (pieces[0]=="row0") bind.trans_piece = SHADER_data_row0;
|
||||
else if (pieces[0]=="row1") bind.trans_piece = SHADER_data_row1;
|
||||
else if (pieces[0]=="row2") bind.trans_piece = SHADER_data_row2;
|
||||
else if (pieces[0]=="row3") bind.trans_piece = SHADER_data_row3;
|
||||
else if (pieces[0]=="col0") bind.trans_piece = SHADER_data_col0;
|
||||
else if (pieces[0]=="col1") bind.trans_piece = SHADER_data_col1;
|
||||
else if (pieces[0]=="col2") bind.trans_piece = SHADER_data_col2;
|
||||
else if (pieces[0]=="col3") bind.trans_piece = SHADER_data_col3;
|
||||
if (pieces[0]=="trans") bind.trans_piece = SMP_whole;
|
||||
else if (pieces[0]=="tpose") bind.trans_piece = SMP_transpose;
|
||||
else if (pieces[0]=="row0") bind.trans_piece = SMP_row0;
|
||||
else if (pieces[0]=="row1") bind.trans_piece = SMP_row1;
|
||||
else if (pieces[0]=="row2") bind.trans_piece = SMP_row2;
|
||||
else if (pieces[0]=="row3") bind.trans_piece = SMP_row3;
|
||||
else if (pieces[0]=="col0") bind.trans_piece = SMP_col0;
|
||||
else if (pieces[0]=="col1") bind.trans_piece = SMP_col1;
|
||||
else if (pieces[0]=="col2") bind.trans_piece = SMP_col2;
|
||||
else if (pieces[0]=="col3") bind.trans_piece = SMP_col3;
|
||||
|
||||
bind.src_name = InternalName::make(pieces[1]);
|
||||
bind.rel_name = InternalName::make(pieces[3]);
|
||||
|
||||
if ((bind.trans_piece == SHADER_data_matrix)||(bind.trans_piece == SHADER_data_transpose)) {
|
||||
if ((bind.trans_piece == SMP_whole)||(bind.trans_piece == SMP_transpose)) {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||
} else {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||
@ -2541,18 +2541,18 @@ compile_cg_parameter(CGparameter p, DX_PARAMETER *dx_parameter)
|
||||
bind.parameter = p;
|
||||
bind.dx_parameter = dx_parameter;
|
||||
|
||||
if (pieces[0]=="wstrans") { bind.rel_name = InternalName::get_world(); bind.trans_piece = SHADER_data_matrix; }
|
||||
else if (pieces[0]=="vstrans") { bind.rel_name = InternalName::get_view(); bind.trans_piece = SHADER_data_matrix; }
|
||||
else if (pieces[0]=="cstrans") { bind.rel_name = InternalName::get_camera(); bind.trans_piece = SHADER_data_matrix; }
|
||||
else if (pieces[0]=="mstrans") { bind.rel_name = InternalName::get_model(); bind.trans_piece = SHADER_data_matrix; }
|
||||
else if (pieces[0]=="wspos") { bind.rel_name = InternalName::get_world(); bind.trans_piece = SHADER_data_row3; }
|
||||
else if (pieces[0]=="vspos") { bind.rel_name = InternalName::get_view(); bind.trans_piece = SHADER_data_row3; }
|
||||
else if (pieces[0]=="cspos") { bind.rel_name = InternalName::get_camera(); bind.trans_piece = SHADER_data_row3; }
|
||||
else if (pieces[0]=="mspos") { bind.rel_name = InternalName::get_model(); bind.trans_piece = SHADER_data_row3; }
|
||||
if (pieces[0]=="wstrans") { bind.rel_name = InternalName::get_world(); bind.trans_piece = SMP_whole; }
|
||||
else if (pieces[0]=="vstrans") { bind.rel_name = InternalName::get_view(); bind.trans_piece = SMP_whole; }
|
||||
else if (pieces[0]=="cstrans") { bind.rel_name = InternalName::get_camera(); bind.trans_piece = SMP_whole; }
|
||||
else if (pieces[0]=="mstrans") { bind.rel_name = InternalName::get_model(); bind.trans_piece = SMP_whole; }
|
||||
else if (pieces[0]=="wspos") { bind.rel_name = InternalName::get_world(); bind.trans_piece = SMP_row3; }
|
||||
else if (pieces[0]=="vspos") { bind.rel_name = InternalName::get_view(); bind.trans_piece = SMP_row3; }
|
||||
else if (pieces[0]=="cspos") { bind.rel_name = InternalName::get_camera(); bind.trans_piece = SMP_row3; }
|
||||
else if (pieces[0]=="mspos") { bind.rel_name = InternalName::get_model(); bind.trans_piece = SMP_row3; }
|
||||
|
||||
bind.src_name = InternalName::make(pieces[1]);
|
||||
|
||||
if ((bind.trans_piece == SHADER_data_matrix)||(bind.trans_piece == SHADER_data_transpose)) {
|
||||
if ((bind.trans_piece == SMP_whole)||(bind.trans_piece == SMP_transpose)) {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||
} else {
|
||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||
|
@ -845,8 +845,6 @@ reset() {
|
||||
<< "max clip planes = " << _max_clip_planes << "\n";
|
||||
}
|
||||
|
||||
_projection_mat = LMatrix4f::ident_mat();
|
||||
|
||||
if (_supports_multitexture) {
|
||||
GLint max_texture_stages;
|
||||
GLP(GetIntegerv)(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
|
||||
@ -986,6 +984,48 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) {
|
||||
do_point_size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::calc_projection_mat
|
||||
// Access: Public, Virtual
|
||||
// Description: Given a lens, calculates the appropriate projection
|
||||
// matrix for use with this gsg. Note that the
|
||||
// projection matrix depends a lot upon the coordinate
|
||||
// system of the rendering API.
|
||||
//
|
||||
// The return value is a TransformState if the lens is
|
||||
// acceptable, NULL if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(TransformState) CLP(GraphicsStateGuardian)::
|
||||
calc_projection_mat(const Lens *lens) {
|
||||
if (lens == (Lens *)NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!lens->is_linear()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The projection matrix must always be right-handed Y-up, even if
|
||||
// our coordinate system of choice is otherwise, because certain GL
|
||||
// calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
|
||||
// a coordinate system. Sigh. In order to implement a Z-up (or
|
||||
// other arbitrary) coordinate system, we'll use a Y-up projection
|
||||
// matrix, and store the conversion to our coordinate system of
|
||||
// choice in the modelview matrix.
|
||||
|
||||
LMatrix4f &result =
|
||||
LMatrix4f::convert_mat(CS_yup_right, _current_lens->get_coordinate_system()) *
|
||||
lens->get_projection_mat(_current_stereo_channel);
|
||||
|
||||
if (_scene_setup->get_inverted()) {
|
||||
// If the scene is supposed to be inverted, then invert the
|
||||
// projection matrix.
|
||||
result *= LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
return TransformState::make_mat(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::prepare_lens
|
||||
// Access: Public, Virtual
|
||||
@ -1000,40 +1040,12 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
prepare_lens() {
|
||||
if (_current_lens == (Lens *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_current_lens->is_linear()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(_current_stereo_channel);
|
||||
|
||||
// The projection matrix must always be right-handed Y-up, even if
|
||||
// our coordinate system of choice is otherwise, because certain GL
|
||||
// calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
|
||||
// a coordinate system. Sigh. In order to implement a Z-up (or
|
||||
// other arbitrary) coordinate system, we'll use a Y-up projection
|
||||
// matrix, and store the conversion to our coordinate system of
|
||||
// choice in the modelview matrix.
|
||||
_projection_mat =
|
||||
LMatrix4f::convert_mat(CS_yup_right, _current_lens->get_coordinate_system()) *
|
||||
lens_mat;
|
||||
|
||||
if (_scene_setup->get_inverted()) {
|
||||
// If the scene is supposed to be inverted, then invert the
|
||||
// projection matrix.
|
||||
static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
|
||||
_projection_mat *= invert_mat;
|
||||
}
|
||||
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl;
|
||||
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
|
||||
}
|
||||
GLP(MatrixMode)(GL_PROJECTION);
|
||||
GLP(LoadMatrixf)(_projection_mat.get_data());
|
||||
GLP(LoadMatrixf)(_projection_mat->get_mat().get_data());
|
||||
report_my_gl_errors();
|
||||
|
||||
do_point_size();
|
||||
@ -2745,7 +2757,7 @@ do_issue_transform() {
|
||||
}
|
||||
|
||||
if (_current_shader_context)
|
||||
_current_shader_context->issue_transform(this);
|
||||
_current_shader_context->issue_parameters(this, false);
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
@ -2818,7 +2830,7 @@ do_issue_shader() {
|
||||
}
|
||||
} else {
|
||||
// Use the same shader as before, but with new input arguments.
|
||||
context->issue_parameters(this);
|
||||
context->issue_parameters(this, true);
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
@ -5965,7 +5977,7 @@ do_point_size() {
|
||||
// scaling factor based on the current viewport and projection
|
||||
// matrix.
|
||||
LVector3f height(0.0f, _point_size, 1.0f);
|
||||
height = height * _projection_mat;
|
||||
height = height * _projection_mat->get_mat();
|
||||
float s = height[1] * _viewport_height / _point_size;
|
||||
|
||||
if (_current_lens->is_orthographic()) {
|
||||
|
@ -85,6 +85,7 @@ public:
|
||||
virtual void do_clear(const RenderBuffer &buffer);
|
||||
|
||||
virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel);
|
||||
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
|
||||
virtual bool prepare_lens();
|
||||
|
||||
virtual bool begin_frame();
|
||||
@ -305,7 +306,6 @@ protected:
|
||||
|
||||
bool _dithering_enabled;
|
||||
|
||||
LMatrix4f _projection_mat;
|
||||
int _viewport_width;
|
||||
int _viewport_height;
|
||||
bool _auto_antialias_mode;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,102 +42,26 @@ public:
|
||||
INLINE bool valid(void);
|
||||
void bind(GSG *gsg);
|
||||
void unbind();
|
||||
void issue_parameters(GSG *gsg);
|
||||
void issue_transform(GSG *gsg);
|
||||
void issue_parameters(GSG *gsg, bool all);
|
||||
void disable_shader_vertex_arrays(GSG *gsg);
|
||||
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
|
||||
void disable_shader_texture_bindings(GSG *gsg);
|
||||
void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
|
||||
|
||||
bool _state;
|
||||
|
||||
private:
|
||||
|
||||
#ifdef HAVE_CGGL
|
||||
enum ShaderAutoValue {
|
||||
// This first batch of constants cleverly lines up
|
||||
// with the Cg constant values. Don't insert anything.
|
||||
SIC_mat_modelview,
|
||||
SIC_inv_modelview,
|
||||
SIC_tps_modelview,
|
||||
SIC_itp_modelview,
|
||||
SIC_mat_projection,
|
||||
SIC_inv_projection,
|
||||
SIC_tps_projection,
|
||||
SIC_itp_projection,
|
||||
SIC_mat_texture,
|
||||
SIC_inv_texture,
|
||||
SIC_tps_texture,
|
||||
SIC_itp_texture,
|
||||
SIC_mat_modelproj,
|
||||
SIC_inv_modelproj,
|
||||
SIC_tps_modelproj,
|
||||
SIC_itp_modelproj,
|
||||
// From this point forward, it's okay to insert stuff.
|
||||
SIC_sys_windowsize,
|
||||
SIC_sys_pixelsize,
|
||||
SIC_sys_cardcenter,
|
||||
};
|
||||
struct ShaderAutoBind {
|
||||
CGparameter parameter;
|
||||
int value;
|
||||
};
|
||||
struct ShaderArgBind {
|
||||
CGparameter parameter;
|
||||
PT(InternalName) name;
|
||||
};
|
||||
struct ShaderTexBind {
|
||||
CGparameter parameter;
|
||||
PT(InternalName) name;
|
||||
int stage;
|
||||
int desiredtype;
|
||||
PT(InternalName) suffix;
|
||||
};
|
||||
struct ShaderTransBind {
|
||||
CGparameter parameter;
|
||||
PT(InternalName) src_name;
|
||||
PT(InternalName) rel_name;
|
||||
int trans_piece;
|
||||
};
|
||||
struct ShaderVarying {
|
||||
CGparameter parameter;
|
||||
PT(InternalName) name;
|
||||
int append_uv;
|
||||
};
|
||||
CGcontext _cg_context;
|
||||
CGprofile _cg_profile[2];
|
||||
CGprogram _cg_program[2];
|
||||
string _cg_errors;
|
||||
|
||||
// These arrays contain lists of "bindings." They
|
||||
// tell us how to fill the shader's input parameters.
|
||||
vector <ShaderAutoBind> _cg_auto_trans;
|
||||
vector <ShaderAutoBind> _cg_auto_param;
|
||||
vector <ShaderArgBind> _cg_fbind;
|
||||
vector <ShaderArgBind> _cg_npbind;
|
||||
vector <ShaderTexBind> _cg_texbind;
|
||||
vector <ShaderTransBind> _cg_transform_bind;
|
||||
vector <ShaderTransBind> _cg_parameter_bind;
|
||||
vector <ShaderVarying> _cg_varying;
|
||||
|
||||
bool try_cg_compile(ShaderExpansion *s, GSG *gsg);
|
||||
void bind_cg_transform(const ShaderTransBind &stb,
|
||||
CLP(GraphicsStateGuardian) *gsg);
|
||||
void suggest_cg_profile(const string &vpro, const string &fpro);
|
||||
CGprofile parse_cg_profile(const string &id, bool vertex);
|
||||
void issue_cg_auto_bind(const ShaderAutoBind &bind, GSG *gsg);
|
||||
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_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);
|
||||
void print_cg_compile_errors(const string &file, CGcontext ctx);
|
||||
#endif
|
||||
|
||||
|
||||
void release_resources(void);
|
||||
|
||||
public:
|
||||
|
@ -442,3 +442,35 @@ operator << (ostream &out, const Lens &lens) {
|
||||
lens.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_projection_mat
|
||||
// Access: Published
|
||||
// Description: Returns the complete transformation matrix from a 3-d
|
||||
// point in space to a point on the film, if such a
|
||||
// matrix exists, or the identity matrix if the lens is
|
||||
// nonlinear, in the specified coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f Lens::
|
||||
get_projection_mat(CoordinateSystem cs, StereoChannel channel) const {
|
||||
return
|
||||
LMatrix4f::convert_mat(cs, _cs) *
|
||||
get_projection_mat(channel) *
|
||||
LMatrix4f::convert_mat(CS_yup_right, cs);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_projection_mat_inv
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a 2-d point
|
||||
// on the film to a 3-d vector in space, if such a
|
||||
// matrix exists, in the specified coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f Lens::
|
||||
get_projection_mat_inv(CoordinateSystem cs, StereoChannel channel) const {
|
||||
return
|
||||
LMatrix4f::convert_mat(cs, CS_yup_right) *
|
||||
get_projection_mat_inv(channel) *
|
||||
LMatrix4f::convert_mat(_cs, cs);
|
||||
}
|
||||
|
||||
|
@ -155,6 +155,9 @@ PUBLISHED:
|
||||
const LMatrix4f &get_projection_mat(StereoChannel channel = SC_mono) const;
|
||||
const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_mono) const;
|
||||
|
||||
INLINE const LMatrix4f get_projection_mat(CoordinateSystem cs, StereoChannel channel) const;
|
||||
INLINE const LMatrix4f get_projection_mat_inv(CoordinateSystem cs, StereoChannel channel) const;
|
||||
|
||||
const LMatrix4f &get_film_mat() const;
|
||||
const LMatrix4f &get_film_mat_inv() const;
|
||||
|
||||
|
@ -18,3 +18,634 @@
|
||||
|
||||
TypeHandle ShaderContext::_type_handle;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
#include "Cg/cg.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::report_cg_compile_errors
|
||||
// Access: Public, Static
|
||||
// Description: Used only after a Cg compile command, to print
|
||||
// out any error messages that may have occurred
|
||||
// during the Cg shader compilation. The 'file'
|
||||
// is the name of the file containing the Cg code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShaderContext::
|
||||
report_cg_compile_errors(const string &file, CGcontext ctx,
|
||||
NotifyCategory *cat)
|
||||
{
|
||||
CGerror err = cgGetError();
|
||||
if (err != CG_NO_ERROR) {
|
||||
if (err == CG_COMPILER_ERROR) {
|
||||
string listing = cgGetLastListing(ctx);
|
||||
vector_string errlines;
|
||||
tokenize(listing, errlines, "\n");
|
||||
for (int i=0; i<(int)errlines.size(); i++) {
|
||||
string line = trim(errlines[i]);
|
||||
if (line != "") {
|
||||
cat->error() << file << " " << errlines[i] << "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cat->error() << file << ": " << cgGetErrorString(err) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::report_cg_parameter_error
|
||||
// Access: Public
|
||||
// Description: Generate an error message including a description
|
||||
// of the specified Cg parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShaderContext::
|
||||
report_cg_parameter_error(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));
|
||||
|
||||
string err;
|
||||
string fn = _shader_expansion->get_name();
|
||||
_cg_report_cat->error() << fn << ": " << msg << " (" <<
|
||||
vstr << dstr << ts << " " << cgGetParameterName(p) << ")\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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 ShaderContext::
|
||||
errchk_cg_parameter_words(CGparameter p, int len)
|
||||
{
|
||||
vector_string words;
|
||||
tokenize(cgGetParameterName(p), words, "_");
|
||||
if (words.size() != len) {
|
||||
report_cg_parameter_error(p, "parameter name has wrong number of words");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_in
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// CG_IN direction. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
errchk_cg_parameter_in(CGparameter p)
|
||||
{
|
||||
if (cgGetParameterDirection(p) != CG_IN) {
|
||||
report_cg_parameter_error(p, "parameter should be declared 'in'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_varying
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct variance. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
errchk_cg_parameter_varying(CGparameter p)
|
||||
{
|
||||
if (cgGetParameterVariability(p) != CG_VARYING) {
|
||||
report_cg_parameter_error(p, "parameter should be declared 'varying'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Shader::errchk_cg_parameter_uniform
|
||||
// Access: Public, Static
|
||||
// Description: Make sure the provided Cg parameter has the
|
||||
// correct variance. If not, print
|
||||
// error message and return false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
errchk_cg_parameter_uniform(CGparameter p)
|
||||
{
|
||||
if (cgGetParameterVariability(p) != CG_UNIFORM) {
|
||||
report_cg_parameter_error(p, "parameter should be declared 'uniform'");
|
||||
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 ShaderContext::
|
||||
errchk_cg_parameter_float(CGparameter p, int lo, int hi)
|
||||
{
|
||||
CGtype t = cgGetParameterType(p);
|
||||
int nfloat = 0;
|
||||
switch (t) {
|
||||
case CG_FLOAT1: nfloat = 1; break;
|
||||
case CG_FLOAT2: nfloat = 2; break;
|
||||
case CG_FLOAT3: nfloat = 3; break;
|
||||
case CG_FLOAT4: nfloat = 4; break;
|
||||
case CG_FLOAT4x4: nfloat = 16; break;
|
||||
}
|
||||
if ((nfloat < lo)||(nfloat > hi)) {
|
||||
report_cg_parameter_error(p, "wrong float-type for parameter");
|
||||
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 ShaderContext::
|
||||
errchk_cg_parameter_sampler(CGparameter p)
|
||||
{
|
||||
CGtype t = cgGetParameterType(p);
|
||||
if ((t!=CG_SAMPLER1D)&&
|
||||
(t!=CG_SAMPLER2D)&&
|
||||
(t!=CG_SAMPLER3D)&&
|
||||
(t!=CG_SAMPLERCUBE)) {
|
||||
report_cg_parameter_error(p, "parameter should have a 'sampler' type");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLShaderContext::parse_cg_trans_clause
|
||||
// Access: Public
|
||||
// Description: Parses a single clause of a "trans" parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
parse_cg_trans_clause(CGparameter p, ShaderMatSpec &spec, const vector_string &pieces,
|
||||
int &next, ShaderMatOp ofop, ShaderMatOp op) {
|
||||
if (pieces[next+1]=="of") {
|
||||
if (pieces[next+2]=="") {
|
||||
report_cg_parameter_error(p, "'of' should be followed by a name");
|
||||
return false;
|
||||
}
|
||||
if (ofop != SMO_noop) {
|
||||
spec._opcodes.push_back(ofop);
|
||||
spec._args.push_back(InternalName::make(pieces[next+2]));
|
||||
}
|
||||
next += 3;
|
||||
return true;
|
||||
} else {
|
||||
if (op != SMO_noop) {
|
||||
spec._opcodes.push_back(op);
|
||||
}
|
||||
next += 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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.
|
||||
//
|
||||
// If there is an error, this routine will append
|
||||
// an error message onto the error messages.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ShaderContext::
|
||||
compile_cg_parameter(CGparameter p, NotifyCategory *cat)
|
||||
{
|
||||
_cg_report_cat = cat;
|
||||
string pname = cgGetParameterName(p);
|
||||
if (pname.size() == 0) return true;
|
||||
if (pname[0] == '$') return true;
|
||||
vector_string pieces;
|
||||
tokenize(pname, pieces, "_");
|
||||
|
||||
if (pieces.size() < 2) {
|
||||
report_cg_parameter_error(p, "invalid parameter name");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implement vtx parameters - the varying kind.
|
||||
|
||||
if (pieces[0] == "vtx") {
|
||||
if ((!errchk_cg_parameter_in(p)) ||
|
||||
(!errchk_cg_parameter_varying(p)) ||
|
||||
(!errchk_cg_parameter_float(p, 1, 4))) {
|
||||
return false;
|
||||
}
|
||||
ShaderVarSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
if (pieces.size() == 2) {
|
||||
if (pieces[1]=="position") {
|
||||
bind._name = InternalName::get_vertex();
|
||||
bind._append_uv = -1;
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,8)=="texcoord") {
|
||||
bind._name = InternalName::get_texcoord();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+8);
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,7)=="tangent") {
|
||||
bind._name = InternalName::get_tangent();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+7);
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
if (pieces[1].substr(0,8)=="binormal") {
|
||||
bind._name = InternalName::get_binormal();
|
||||
bind._append_uv = atoi(pieces[1].c_str()+8);
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bind._name = InternalName::get_root();
|
||||
bind._append_uv = -1;
|
||||
for (int i=1; i<(int)(pieces.size()-0); i++)
|
||||
bind._name = bind._name->append(pieces[i]);
|
||||
_var_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Implement some macros. Macros work by altering the
|
||||
// contents of the 'pieces' array, and then falling through.
|
||||
|
||||
if (pieces[0] == "mstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("model");
|
||||
}
|
||||
if (pieces[0] == "wstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("world");
|
||||
}
|
||||
if (pieces[0] == "vstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("view");
|
||||
}
|
||||
if (pieces[0] == "cstrans") {
|
||||
pieces[0] = "trans";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("clip");
|
||||
}
|
||||
if (pieces[0] == "mspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("model");
|
||||
}
|
||||
if (pieces[0] == "wspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("world");
|
||||
}
|
||||
if (pieces[0] == "vspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("view");
|
||||
}
|
||||
if (pieces[0] == "cspos") {
|
||||
pieces[0] = "row3";
|
||||
pieces.push_back("to");
|
||||
pieces.push_back("clip");
|
||||
}
|
||||
|
||||
// Implement the modelview macros.
|
||||
|
||||
if ((pieces[0] == "mat")||(pieces[0] == "inv")||
|
||||
(pieces[0] == "tps")||(pieces[0] == "itp")) {
|
||||
if (!errchk_cg_parameter_words(p, 2)) {
|
||||
return false;
|
||||
}
|
||||
string trans = pieces[0];
|
||||
string matrix = pieces[1];
|
||||
pieces.clear();
|
||||
if (matrix == "modelview") {
|
||||
tokenize("trans_model_to_apiview", pieces, "_");
|
||||
} else if (matrix == "projection") {
|
||||
tokenize("trans_apiview_to_apiclip", pieces, "_");
|
||||
} else if (matrix == "modelproj") {
|
||||
tokenize("trans_model_to_apiclip", pieces, "_");
|
||||
} else {
|
||||
report_cg_parameter_error(p,"unrecognized matrix name");
|
||||
return false;
|
||||
}
|
||||
if (trans=="mat") {
|
||||
pieces[0] = "trans";
|
||||
} else if (trans=="inv") {
|
||||
string t = pieces[1];
|
||||
pieces[1] = pieces[3];
|
||||
pieces[3] = t;
|
||||
} else if (trans=="tps") {
|
||||
pieces[0] = "tpose";
|
||||
} else if (trans=="itp") {
|
||||
string t = pieces[1];
|
||||
pieces[1] = pieces[3];
|
||||
pieces[3] = t;
|
||||
pieces[0] = "tpose";
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the transform-matrix generator.
|
||||
|
||||
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")) {
|
||||
|
||||
if ((!errchk_cg_parameter_in(p)) ||
|
||||
(!errchk_cg_parameter_uniform(p)))
|
||||
return false;
|
||||
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._trans_dependent = false;
|
||||
|
||||
int next = 1;
|
||||
pieces.push_back("");
|
||||
|
||||
// Decide whether this is a matrix or vector.
|
||||
if (pieces[0]=="trans") bind._piece = SMP_whole;
|
||||
else if (pieces[0]=="tpose") bind._piece = SMP_whole;
|
||||
else if (pieces[0]=="row0") bind._piece = SMP_row0;
|
||||
else if (pieces[0]=="row1") bind._piece = SMP_row1;
|
||||
else if (pieces[0]=="row2") bind._piece = SMP_row2;
|
||||
else if (pieces[0]=="row3") bind._piece = SMP_row3;
|
||||
else if (pieces[0]=="col0") bind._piece = SMP_col0;
|
||||
else if (pieces[0]=="col1") bind._piece = SMP_col1;
|
||||
else if (pieces[0]=="col2") bind._piece = SMP_col2;
|
||||
else if (pieces[0]=="col3") bind._piece = SMP_col3;
|
||||
if (bind._piece == SMP_whole) {
|
||||
if (!errchk_cg_parameter_float(p, 16, 16)) return false;
|
||||
} else {
|
||||
if (!errchk_cg_parameter_float(p, 4, 4)) return false;
|
||||
}
|
||||
|
||||
// Parse the first half of the clause.
|
||||
bool ok = true;
|
||||
if ((pieces[next]=="")||(pieces[next]=="of")||(pieces[next]=="to")){
|
||||
report_cg_parameter_error(p, "argument missing");
|
||||
return false;
|
||||
} else if (pieces[next] == "world") {
|
||||
bind._opcodes.push_back(SMO_world_to_view);
|
||||
next += 1;
|
||||
} else if (pieces[next] == "model") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_model_to_view);
|
||||
} else if (pieces[next] == "clip") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_clip_x_to_view, SMO_clip_to_view);
|
||||
} else if (pieces[next] == "view") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_x_to_view, SMO_identity);
|
||||
} else if (pieces[next] == "apiview") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_apiview_x_to_view, SMO_apiview_to_view);
|
||||
} else if (pieces[next] == "apiclip") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_apiclip_x_to_view, SMO_apiclip_to_view);
|
||||
} else {
|
||||
bind._opcodes.push_back(SMO_view_x_to_view);
|
||||
bind._args.push_back(InternalName::make(pieces[next]));
|
||||
next += 1;
|
||||
}
|
||||
|
||||
// Check for errors in the first clause.
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for transform-dependence.
|
||||
if (bind._opcodes.back() == SMO_model_to_view) {
|
||||
bind._trans_dependent = true;
|
||||
}
|
||||
|
||||
// Check for syntactic well-formed-ness.
|
||||
if (pieces[next] != "to") {
|
||||
report_cg_parameter_error(p, "keyword 'to' expected");
|
||||
return false;
|
||||
} else {
|
||||
next += 1;
|
||||
}
|
||||
|
||||
// Parse the second half of the clause.
|
||||
if ((pieces[next]=="")||(pieces[next]=="of")||(pieces[next]=="to")){
|
||||
report_cg_parameter_error(p, "argument missing");
|
||||
return false;
|
||||
} else if (pieces[next] == "world") {
|
||||
bind._opcodes.push_back(SMO_view_to_world_C);
|
||||
next += 1;
|
||||
} else if (pieces[next] == "model") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_view_to_model_C);
|
||||
} else if (pieces[next] == "clip") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_clip_x_C, SMO_view_to_clip_C);
|
||||
} else if (pieces[next] == "view") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_view_x_C, SMO_noop);
|
||||
} else if (pieces[next] == "apiview") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_apiview_x_C, SMO_view_to_apiview_C);
|
||||
} else if (pieces[next] == "apiclip") {
|
||||
ok &= parse_cg_trans_clause(p, bind, pieces, next, SMO_view_to_apiclip_x_C, SMO_view_to_apiclip_C);
|
||||
} else {
|
||||
bind._opcodes.push_back(SMO_view_to_view_x_C);
|
||||
bind._args.push_back(InternalName::make(pieces[next]));
|
||||
next += 1;
|
||||
}
|
||||
|
||||
// Check for errors in the second clause.
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for transform-dependence.
|
||||
if (bind._opcodes.back() == SMO_view_to_model_C) {
|
||||
bind._trans_dependent = true;
|
||||
}
|
||||
|
||||
// Check for syntactic well-formed-ness.
|
||||
if (pieces[next] != "") {
|
||||
report_cg_parameter_error(p, "end of line expected");
|
||||
return false;
|
||||
}
|
||||
|
||||
_mat_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keywords to access unusual parameters.
|
||||
|
||||
if (pieces[0] == "sys") {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_in(p)) ||
|
||||
(!errchk_cg_parameter_uniform(p))) {
|
||||
return false;
|
||||
}
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_row3;
|
||||
if (pieces[1] == "pixelsize") {
|
||||
if (!errchk_cg_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_pixel_size);
|
||||
} else if (pieces[1] == "windowsize") {
|
||||
if (!errchk_cg_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_window_size);
|
||||
} else if (pieces[1] == "cardcenter") {
|
||||
if (!errchk_cg_parameter_float(p, 2, 2)) {
|
||||
return false;
|
||||
}
|
||||
bind._opcodes.push_back(SMO_card_center);
|
||||
} else {
|
||||
report_cg_parameter_error(p,"unknown system parameter");
|
||||
return false;
|
||||
}
|
||||
_mat_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keywords to access textures.
|
||||
|
||||
if (pieces[0] == "tex") {
|
||||
if ((!errchk_cg_parameter_in(p)) ||
|
||||
(!errchk_cg_parameter_uniform(p)) ||
|
||||
(!errchk_cg_parameter_sampler(p)))
|
||||
return false;
|
||||
if ((pieces.size() != 2)&&(pieces.size() != 3)) {
|
||||
report_cg_parameter_error(p, "Invalid parameter name");
|
||||
return false;
|
||||
}
|
||||
ShaderTexSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._name = 0;
|
||||
bind._stage = atoi(pieces[1].c_str());
|
||||
switch (cgGetParameterType(p)) {
|
||||
case CG_SAMPLER1D: bind._desired_type = Texture::TT_1d_texture; break;
|
||||
case CG_SAMPLER2D: bind._desired_type = Texture::TT_2d_texture; break;
|
||||
case CG_SAMPLER3D: bind._desired_type = Texture::TT_3d_texture; break;
|
||||
case CG_SAMPLERCUBE: bind._desired_type = Texture::TT_cube_map; break;
|
||||
default:
|
||||
report_cg_parameter_error(p, "Invalid type for a tex-parameter");
|
||||
return false;
|
||||
}
|
||||
if (pieces.size()==3) {
|
||||
bind._suffix = InternalName::make(((string)"-") + pieces[2]);
|
||||
}
|
||||
_tex_spec.push_back(bind);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Keywords to access constants.
|
||||
|
||||
if (pieces[0] == "k") {
|
||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||
(!errchk_cg_parameter_in(p)) ||
|
||||
(!errchk_cg_parameter_uniform(p)))
|
||||
return false;
|
||||
switch (cgGetParameterType(p)) {
|
||||
case CG_FLOAT4: {
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_row3;
|
||||
bind._opcodes.push_back(SMO_vec_constant_x);
|
||||
bind._args.push_back(InternalName::make(pieces[1]));
|
||||
_mat_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case CG_FLOAT4x4: {
|
||||
ShaderMatSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._trans_dependent = false;
|
||||
bind._piece = SMP_whole;
|
||||
bind._opcodes.push_back(SMO_mat_constant_x);
|
||||
bind._args.push_back(InternalName::make(pieces[1]));
|
||||
_mat_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case CG_SAMPLER1D: {
|
||||
ShaderTexSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._name = InternalName::make(pieces[1]);
|
||||
bind._desired_type=Texture::TT_1d_texture;
|
||||
_tex_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case CG_SAMPLER2D: {
|
||||
ShaderTexSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._name = InternalName::make(pieces[1]);
|
||||
bind._desired_type=Texture::TT_2d_texture;
|
||||
_tex_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case CG_SAMPLER3D: {
|
||||
ShaderTexSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._name = InternalName::make(pieces[1]);
|
||||
bind._desired_type=Texture::TT_3d_texture;
|
||||
_tex_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
case CG_SAMPLERCUBE: {
|
||||
ShaderTexSpec bind;
|
||||
bind._parameter = (void*)p;
|
||||
bind._name = InternalName::make(pieces[1]);
|
||||
bind._desired_type = Texture::TT_cube_map;
|
||||
_tex_spec.push_back(bind);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
report_cg_parameter_error(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.
|
||||
}
|
||||
|
||||
report_cg_parameter_error(p, "unrecognized parameter name");
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // HAVE_CG
|
||||
|
@ -23,6 +23,13 @@
|
||||
#include "internalName.h"
|
||||
#include "savedContext.h"
|
||||
#include "shaderExpansion.h"
|
||||
#ifdef HAVE_CG
|
||||
// Instead of including the whole header file, just include these stubs.
|
||||
typedef struct _CGcontext *CGcontext;
|
||||
typedef struct _CGprogram *CGprogram;
|
||||
typedef struct _CGparameter *CGparameter;
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ShaderContext
|
||||
@ -41,28 +48,117 @@ public:
|
||||
INLINE ShaderContext(ShaderExpansion *se);
|
||||
|
||||
ShaderExpansion *_shader_expansion;
|
||||
|
||||
|
||||
public:
|
||||
// The following declarations represent useful routines
|
||||
// and constants that can be used by shader implementations.
|
||||
|
||||
enum {
|
||||
SHADER_type_vert=0,
|
||||
SHADER_type_frag=1,
|
||||
SHADER_type_both=2,
|
||||
};
|
||||
enum {
|
||||
SHADER_data_matrix,
|
||||
SHADER_data_transpose,
|
||||
SHADER_data_row0,
|
||||
SHADER_data_row1,
|
||||
SHADER_data_row2,
|
||||
SHADER_data_row3,
|
||||
SHADER_data_col0,
|
||||
SHADER_data_col1,
|
||||
SHADER_data_col2,
|
||||
SHADER_data_col3,
|
||||
enum ShaderMatOp {
|
||||
SMO_identity,
|
||||
|
||||
SMO_modelview,
|
||||
SMO_projection,
|
||||
SMO_modelproj,
|
||||
|
||||
SMO_window_size,
|
||||
SMO_pixel_size,
|
||||
SMO_card_center,
|
||||
|
||||
SMO_mat_constant_x,
|
||||
SMO_vec_constant_x,
|
||||
|
||||
SMO_world_to_view,
|
||||
SMO_view_to_world_C,
|
||||
|
||||
SMO_model_to_view,
|
||||
SMO_view_to_model_C,
|
||||
|
||||
SMO_apiview_to_view,
|
||||
SMO_view_to_apiview_C,
|
||||
|
||||
SMO_clip_to_view,
|
||||
SMO_view_to_clip_C,
|
||||
|
||||
SMO_apiclip_to_view,
|
||||
SMO_view_to_apiclip_C,
|
||||
|
||||
SMO_view_x_to_view,
|
||||
SMO_view_to_view_x_C,
|
||||
|
||||
SMO_apiview_x_to_view,
|
||||
SMO_view_to_apiview_x_C,
|
||||
|
||||
SMO_clip_x_to_view,
|
||||
SMO_view_to_clip_x_C,
|
||||
|
||||
SMO_apiclip_x_to_view,
|
||||
SMO_view_to_apiclip_x_C,
|
||||
|
||||
SMO_transpose,
|
||||
SMO_noop,
|
||||
};
|
||||
enum ShaderMatPiece {
|
||||
SMP_whole,
|
||||
SMP_transpose,
|
||||
SMP_row0,
|
||||
SMP_row1,
|
||||
SMP_row2,
|
||||
SMP_row3,
|
||||
SMP_col0,
|
||||
SMP_col1,
|
||||
SMP_col2,
|
||||
SMP_col3,
|
||||
};
|
||||
struct ShaderMatSpec {
|
||||
pvector<ShaderMatOp> _opcodes;
|
||||
pvector<PT(InternalName)> _args;
|
||||
ShaderMatPiece _piece;
|
||||
bool _trans_dependent;
|
||||
void *_parameter;
|
||||
};
|
||||
struct ShaderTexSpec {
|
||||
PT(InternalName) _name;
|
||||
int _stage;
|
||||
int _desired_type;
|
||||
PT(InternalName) _suffix;
|
||||
void *_parameter;
|
||||
};
|
||||
struct ShaderVarSpec {
|
||||
PT(InternalName) _name;
|
||||
int _append_uv;
|
||||
void *_parameter;
|
||||
};
|
||||
|
||||
protected:
|
||||
pvector <ShaderMatSpec> _mat_spec;
|
||||
pvector <ShaderTexSpec> _tex_spec;
|
||||
pvector <ShaderVarSpec> _var_spec;
|
||||
|
||||
#ifdef HAVE_CG
|
||||
private:
|
||||
// These functions are only called by 'compile_cg_parameter'
|
||||
NotifyCategory *_cg_report_cat;
|
||||
void report_cg_parameter_error(CGparameter p, const string &msg);
|
||||
bool errchk_cg_parameter_words(CGparameter p, int len);
|
||||
bool errchk_cg_parameter_in(CGparameter p);
|
||||
bool errchk_cg_parameter_varying(CGparameter p);
|
||||
bool errchk_cg_parameter_uniform(CGparameter p);
|
||||
bool errchk_cg_parameter_float(CGparameter p, int lo, int hi);
|
||||
bool errchk_cg_parameter_sampler(CGparameter p);
|
||||
bool parse_cg_trans_clause(CGparameter p,
|
||||
ShaderMatSpec &spec,
|
||||
const vector_string &pieces,
|
||||
int &next,
|
||||
ShaderMatOp ofop,
|
||||
ShaderMatOp op);
|
||||
|
||||
protected:
|
||||
void report_cg_compile_errors(const string &file, CGcontext ctx,
|
||||
NotifyCategory *cat);
|
||||
bool compile_cg_parameter(CGparameter p, NotifyCategory *cat);
|
||||
#endif
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user