mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-17 20:23:47 -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']
|
IPATH=['panda/src/gobj']
|
||||||
OPTS=['BUILDING_PANDA', 'NSPR']
|
OPTS=['BUILDING_PANDA', 'NSPR', 'NVIDIACG']
|
||||||
CopyAllHeaders('panda/src/gobj')
|
CopyAllHeaders('panda/src/gobj')
|
||||||
EnqueueCxx(ipath=IPATH, opts=OPTS, src='gobj_composite1.cxx', obj='gobj_composite1.obj')
|
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')
|
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')
|
CopyAllHeaders('panda/src/particlesystem')
|
||||||
IPATH=['panda/metalibs/panda']
|
IPATH=['panda/metalibs/panda']
|
||||||
OPTS=['BUILDING_PANDA', 'ZLIB', 'VRPN', 'JPEG', 'PNG', 'TIFF', 'NSPR', 'FREETYPE', 'HELIX', 'FFTW', 'OPENCV',
|
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',
|
INFILES=['librecorder.in', 'libpgraph.in', 'libgrutil.in', 'libchan.in', 'libpstatclient.in',
|
||||||
'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libevent.in',
|
'libchar.in', 'libcollide.in', 'libdevice.in', 'libdgraph.in', 'libdisplay.in', 'libevent.in',
|
||||||
'libgobj.in', 'libgsgbase.in', 'liblinmath.in', 'libmathutil.in', 'libparametrics.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_display_region = (DisplayRegion*)0L;
|
||||||
_current_stereo_channel = Lens::SC_mono;
|
_current_stereo_channel = Lens::SC_mono;
|
||||||
_current_lens = (Lens *)NULL;
|
_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;
|
_needs_reset = true;
|
||||||
_is_valid = false;
|
_is_valid = false;
|
||||||
_closing_gsg = false;
|
_closing_gsg = false;
|
||||||
@ -363,6 +368,15 @@ set_scene(SceneSetup *scene_setup) {
|
|||||||
return false;
|
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();
|
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
|
// Function: GraphicsStateGuardian::prepare_display_region
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -1832,3 +2046,24 @@ traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),vo
|
|||||||
return;
|
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 "notify.h"
|
||||||
#include "pvector.h"
|
#include "pvector.h"
|
||||||
#include "attribSlots.h"
|
#include "attribSlots.h"
|
||||||
|
#include "shaderContext.h"
|
||||||
|
|
||||||
class DrawableRegion;
|
class DrawableRegion;
|
||||||
class GraphicsEngine;
|
class GraphicsEngine;
|
||||||
@ -158,8 +159,12 @@ public:
|
|||||||
|
|
||||||
void clear(DrawableRegion *clearable);
|
void clear(DrawableRegion *clearable);
|
||||||
|
|
||||||
|
bool fetch_specified_value(const ShaderContext::ShaderMatSpec &spec, LMatrix4f &result);
|
||||||
|
|
||||||
virtual void prepare_display_region(DisplayRegion *dr,
|
virtual void prepare_display_region(DisplayRegion *dr,
|
||||||
Lens::StereoChannel stereo_channel);
|
Lens::StereoChannel stereo_channel);
|
||||||
|
|
||||||
|
virtual CPT(TransformState) calc_projection_mat(const Lens *lens);
|
||||||
virtual bool prepare_lens();
|
virtual bool prepare_lens();
|
||||||
|
|
||||||
virtual bool begin_frame();
|
virtual bool begin_frame();
|
||||||
@ -198,7 +203,7 @@ public:
|
|||||||
|
|
||||||
INLINE const TransformState *get_cs_transform() const;
|
INLINE const TransformState *get_cs_transform() const;
|
||||||
INLINE const TransformState *get_inv_cs_transform() const;
|
INLINE const TransformState *get_inv_cs_transform() const;
|
||||||
|
|
||||||
void do_issue_clip_plane();
|
void do_issue_clip_plane();
|
||||||
void do_issue_color();
|
void do_issue_color();
|
||||||
void do_issue_color_scale();
|
void do_issue_color_scale();
|
||||||
@ -288,7 +293,11 @@ protected:
|
|||||||
CPT(DisplayRegion) _current_display_region;
|
CPT(DisplayRegion) _current_display_region;
|
||||||
Lens::StereoChannel _current_stereo_channel;
|
Lens::StereoChannel _current_stereo_channel;
|
||||||
CPT(Lens) _current_lens;
|
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 _coordinate_system;
|
||||||
CoordinateSystem _internal_coordinate_system;
|
CoordinateSystem _internal_coordinate_system;
|
||||||
CPT(TransformState) _cs_transform;
|
CPT(TransformState) _cs_transform;
|
||||||
|
@ -2058,22 +2058,22 @@ bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
|
|||||||
data = total->get_mat().get_data();
|
data = total->get_mat().get_data();
|
||||||
switch (stb.trans_piece) {
|
switch (stb.trans_piece) {
|
||||||
/*
|
/*
|
||||||
case SHADER_data_matrix: cgD3D9SetMatrixParameterfc(stb.parameter, data); break;
|
case SMP_whole: cgD3D9SetMatrixParameterfc(stb.parameter, data); break;
|
||||||
case SHADER_data_transpose: cgD3D9SetMatrixParameterfr(stb.parameter, data); break;
|
case SMP_transpose: cgD3D9SetMatrixParameterfr(stb.parameter, data); break;
|
||||||
case SHADER_data_row0: cgD3D9SetParameter4fv(stb.parameter, data+ 0); break;
|
case SMP_row0: cgD3D9SetParameter4fv(stb.parameter, data+ 0); break;
|
||||||
case SHADER_data_row1: cgD3D9SetParameter4fv(stb.parameter, data+ 4); break;
|
case SMP_row1: cgD3D9SetParameter4fv(stb.parameter, data+ 4); break;
|
||||||
case SHADER_data_row2: cgD3D9SetParameter4fv(stb.parameter, data+ 8); break;
|
case SMP_row2: cgD3D9SetParameter4fv(stb.parameter, data+ 8); break;
|
||||||
case SHADER_data_row3: cgD3D9SetParameter4fv(stb.parameter, data+12); break;
|
case SMP_row3: cgD3D9SetParameter4fv(stb.parameter, data+12); break;
|
||||||
case SHADER_data_col0: cgD3D9SetParameter4f(stb.parameter, data[0], data[4], data[ 8], data[12]); break;
|
case SMP_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 SMP_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 SMP_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_col3: cgD3D9SetParameter4f(stb.parameter, data[3], data[7], data[11], data[15]); break;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float vector [4];
|
float vector [4];
|
||||||
float matrix [16];
|
float matrix [16];
|
||||||
|
|
||||||
case SHADER_data_matrix:
|
case SMP_whole:
|
||||||
if (_cg_shader) {
|
if (_cg_shader) {
|
||||||
cgD3D9SetUniform (stb.parameter, data);
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, data, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_transpose:
|
case SMP_transpose:
|
||||||
matrix [0] = data[0];
|
matrix [0] = data[0];
|
||||||
matrix [1] = data[4];
|
matrix [1] = data[4];
|
||||||
matrix [2] = data[8];
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, matrix, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_row0:
|
case SMP_row0:
|
||||||
if (_cg_shader) {
|
if (_cg_shader) {
|
||||||
cgD3D9SetUniform (stb.parameter, data);
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, data, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_row1:
|
case SMP_row1:
|
||||||
if (_cg_shader) {
|
if (_cg_shader) {
|
||||||
cgD3D9SetUniform (stb.parameter, data + 4);
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, data + 4, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_row2:
|
case SMP_row2:
|
||||||
if (_cg_shader) {
|
if (_cg_shader) {
|
||||||
cgD3D9SetUniform (stb.parameter, data + 8);
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, data + 8, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_row3:
|
case SMP_row3:
|
||||||
if (_cg_shader) {
|
if (_cg_shader) {
|
||||||
cgD3D9SetUniform (stb.parameter, data + 12);
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, data + 12, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_col0:
|
case SMP_col0:
|
||||||
vector [0] = data[0];
|
vector [0] = data[0];
|
||||||
vector [1] = data[4];
|
vector [1] = data[4];
|
||||||
vector [2] = data[8];
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_col1:
|
case SMP_col1:
|
||||||
vector [0] = data[1];
|
vector [0] = data[1];
|
||||||
vector [1] = data[5];
|
vector [1] = data[5];
|
||||||
vector [2] = data[9];
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_col2:
|
case SMP_col2:
|
||||||
vector [0] = data[2];
|
vector [0] = data[2];
|
||||||
vector [1] = data[6];
|
vector [1] = data[6];
|
||||||
vector [2] = data[10];
|
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);
|
set_dx_shader_parameter_float (stb.dx_parameter, vector, gsg -> _d3d_device);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHADER_data_col3:
|
case SMP_col3:
|
||||||
vector [0] = data[3];
|
vector [0] = data[3];
|
||||||
vector [1] = data[7];
|
vector [1] = data[7];
|
||||||
vector [2] = data[11];
|
vector [2] = data[11];
|
||||||
@ -2499,21 +2499,21 @@ compile_cg_parameter(CGparameter p, DX_PARAMETER *dx_parameter)
|
|||||||
bind.parameter = p;
|
bind.parameter = p;
|
||||||
bind.dx_parameter = dx_parameter;
|
bind.dx_parameter = dx_parameter;
|
||||||
|
|
||||||
if (pieces[0]=="trans") bind.trans_piece = SHADER_data_matrix;
|
if (pieces[0]=="trans") bind.trans_piece = SMP_whole;
|
||||||
else if (pieces[0]=="tpose") bind.trans_piece = SHADER_data_transpose;
|
else if (pieces[0]=="tpose") bind.trans_piece = SMP_transpose;
|
||||||
else if (pieces[0]=="row0") bind.trans_piece = SHADER_data_row0;
|
else if (pieces[0]=="row0") bind.trans_piece = SMP_row0;
|
||||||
else if (pieces[0]=="row1") bind.trans_piece = SHADER_data_row1;
|
else if (pieces[0]=="row1") bind.trans_piece = SMP_row1;
|
||||||
else if (pieces[0]=="row2") bind.trans_piece = SHADER_data_row2;
|
else if (pieces[0]=="row2") bind.trans_piece = SMP_row2;
|
||||||
else if (pieces[0]=="row3") bind.trans_piece = SHADER_data_row3;
|
else if (pieces[0]=="row3") bind.trans_piece = SMP_row3;
|
||||||
else if (pieces[0]=="col0") bind.trans_piece = SHADER_data_col0;
|
else if (pieces[0]=="col0") bind.trans_piece = SMP_col0;
|
||||||
else if (pieces[0]=="col1") bind.trans_piece = SHADER_data_col1;
|
else if (pieces[0]=="col1") bind.trans_piece = SMP_col1;
|
||||||
else if (pieces[0]=="col2") bind.trans_piece = SHADER_data_col2;
|
else if (pieces[0]=="col2") bind.trans_piece = SMP_col2;
|
||||||
else if (pieces[0]=="col3") bind.trans_piece = SHADER_data_col3;
|
else if (pieces[0]=="col3") bind.trans_piece = SMP_col3;
|
||||||
|
|
||||||
bind.src_name = InternalName::make(pieces[1]);
|
bind.src_name = InternalName::make(pieces[1]);
|
||||||
bind.rel_name = InternalName::make(pieces[3]);
|
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;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||||
} else {
|
} else {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
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.parameter = p;
|
||||||
bind.dx_parameter = dx_parameter;
|
bind.dx_parameter = dx_parameter;
|
||||||
|
|
||||||
if (pieces[0]=="wstrans") { bind.rel_name = InternalName::get_world(); bind.trans_piece = SHADER_data_matrix; }
|
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 = SHADER_data_matrix; }
|
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 = SHADER_data_matrix; }
|
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 = SHADER_data_matrix; }
|
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 = SHADER_data_row3; }
|
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 = SHADER_data_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 = SHADER_data_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 = SHADER_data_row3; }
|
else if (pieces[0]=="mspos") { bind.rel_name = InternalName::get_model(); bind.trans_piece = SMP_row3; }
|
||||||
|
|
||||||
bind.src_name = InternalName::make(pieces[1]);
|
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;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||||
} else {
|
} else {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||||
|
@ -845,8 +845,6 @@ reset() {
|
|||||||
<< "max clip planes = " << _max_clip_planes << "\n";
|
<< "max clip planes = " << _max_clip_planes << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
_projection_mat = LMatrix4f::ident_mat();
|
|
||||||
|
|
||||||
if (_supports_multitexture) {
|
if (_supports_multitexture) {
|
||||||
GLint max_texture_stages;
|
GLint max_texture_stages;
|
||||||
GLP(GetIntegerv)(GL_MAX_TEXTURE_UNITS, &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();
|
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
|
// Function: GLGraphicsStateGuardian::prepare_lens
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -1000,40 +1040,12 @@ prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool CLP(GraphicsStateGuardian)::
|
bool CLP(GraphicsStateGuardian)::
|
||||||
prepare_lens() {
|
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()) {
|
if (GLCAT.is_spam()) {
|
||||||
GLCAT.spam()
|
GLCAT.spam()
|
||||||
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat << endl;
|
<< "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
|
||||||
}
|
}
|
||||||
GLP(MatrixMode)(GL_PROJECTION);
|
GLP(MatrixMode)(GL_PROJECTION);
|
||||||
GLP(LoadMatrixf)(_projection_mat.get_data());
|
GLP(LoadMatrixf)(_projection_mat->get_mat().get_data());
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
|
||||||
do_point_size();
|
do_point_size();
|
||||||
@ -2745,7 +2757,7 @@ do_issue_transform() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_current_shader_context)
|
if (_current_shader_context)
|
||||||
_current_shader_context->issue_transform(this);
|
_current_shader_context->issue_parameters(this, false);
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
@ -2818,7 +2830,7 @@ do_issue_shader() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Use the same shader as before, but with new input arguments.
|
// Use the same shader as before, but with new input arguments.
|
||||||
context->issue_parameters(this);
|
context->issue_parameters(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
@ -5965,7 +5977,7 @@ do_point_size() {
|
|||||||
// scaling factor based on the current viewport and projection
|
// scaling factor based on the current viewport and projection
|
||||||
// matrix.
|
// matrix.
|
||||||
LVector3f height(0.0f, _point_size, 1.0f);
|
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;
|
float s = height[1] * _viewport_height / _point_size;
|
||||||
|
|
||||||
if (_current_lens->is_orthographic()) {
|
if (_current_lens->is_orthographic()) {
|
||||||
|
@ -85,6 +85,7 @@ public:
|
|||||||
virtual void do_clear(const RenderBuffer &buffer);
|
virtual void do_clear(const RenderBuffer &buffer);
|
||||||
|
|
||||||
virtual void prepare_display_region(DisplayRegion *dr, Lens::StereoChannel stereo_channel);
|
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 prepare_lens();
|
||||||
|
|
||||||
virtual bool begin_frame();
|
virtual bool begin_frame();
|
||||||
@ -305,7 +306,6 @@ protected:
|
|||||||
|
|
||||||
bool _dithering_enabled;
|
bool _dithering_enabled;
|
||||||
|
|
||||||
LMatrix4f _projection_mat;
|
|
||||||
int _viewport_width;
|
int _viewport_width;
|
||||||
int _viewport_height;
|
int _viewport_height;
|
||||||
bool _auto_antialias_mode;
|
bool _auto_antialias_mode;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -42,102 +42,26 @@ public:
|
|||||||
INLINE bool valid(void);
|
INLINE bool valid(void);
|
||||||
void bind(GSG *gsg);
|
void bind(GSG *gsg);
|
||||||
void unbind();
|
void unbind();
|
||||||
void issue_parameters(GSG *gsg);
|
void issue_parameters(GSG *gsg, bool all);
|
||||||
void issue_transform(GSG *gsg);
|
|
||||||
void disable_shader_vertex_arrays(GSG *gsg);
|
void disable_shader_vertex_arrays(GSG *gsg);
|
||||||
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
|
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
|
||||||
void disable_shader_texture_bindings(GSG *gsg);
|
void disable_shader_texture_bindings(GSG *gsg);
|
||||||
void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
|
void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
|
||||||
|
|
||||||
bool _state;
|
bool _state;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef HAVE_CGGL
|
#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;
|
CGcontext _cg_context;
|
||||||
CGprofile _cg_profile[2];
|
CGprofile _cg_profile[2];
|
||||||
CGprogram _cg_program[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);
|
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);
|
void suggest_cg_profile(const string &vpro, const string &fpro);
|
||||||
CGprofile parse_cg_profile(const string &id, bool vertex);
|
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);
|
void print_cg_compile_errors(const string &file, CGcontext ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void release_resources(void);
|
void release_resources(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -442,3 +442,35 @@ operator << (ostream &out, const Lens &lens) {
|
|||||||
lens.output(out);
|
lens.output(out);
|
||||||
return 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(StereoChannel channel = SC_mono) const;
|
||||||
const LMatrix4f &get_projection_mat_inv(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() const;
|
||||||
const LMatrix4f &get_film_mat_inv() const;
|
const LMatrix4f &get_film_mat_inv() const;
|
||||||
|
|
||||||
|
@ -18,3 +18,634 @@
|
|||||||
|
|
||||||
TypeHandle ShaderContext::_type_handle;
|
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 "internalName.h"
|
||||||
#include "savedContext.h"
|
#include "savedContext.h"
|
||||||
#include "shaderExpansion.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
|
// Class : ShaderContext
|
||||||
@ -41,28 +48,117 @@ public:
|
|||||||
INLINE ShaderContext(ShaderExpansion *se);
|
INLINE ShaderContext(ShaderExpansion *se);
|
||||||
|
|
||||||
ShaderExpansion *_shader_expansion;
|
ShaderExpansion *_shader_expansion;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// The following declarations represent useful routines
|
|
||||||
// and constants that can be used by shader implementations.
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SHADER_type_vert=0,
|
SHADER_type_vert=0,
|
||||||
SHADER_type_frag=1,
|
SHADER_type_frag=1,
|
||||||
SHADER_type_both=2,
|
SHADER_type_both=2,
|
||||||
};
|
};
|
||||||
enum {
|
enum ShaderMatOp {
|
||||||
SHADER_data_matrix,
|
SMO_identity,
|
||||||
SHADER_data_transpose,
|
|
||||||
SHADER_data_row0,
|
SMO_modelview,
|
||||||
SHADER_data_row1,
|
SMO_projection,
|
||||||
SHADER_data_row2,
|
SMO_modelproj,
|
||||||
SHADER_data_row3,
|
|
||||||
SHADER_data_col0,
|
SMO_window_size,
|
||||||
SHADER_data_col1,
|
SMO_pixel_size,
|
||||||
SHADER_data_col2,
|
SMO_card_center,
|
||||||
SHADER_data_col3,
|
|
||||||
|
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:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user