New shader system

This commit is contained in:
Josh Yelon 2005-09-25 04:06:31 +00:00
parent 1dee0208ee
commit 2095d8c44f
61 changed files with 2624 additions and 1888 deletions

File diff suppressed because it is too large Load Diff

View File

@ -23,17 +23,7 @@
#include "vertexBufferContext.h"
#include "indexBufferContext.h"
#include "renderBuffer.h"
#include "colorAttrib.h"
#include "colorScaleAttrib.h"
#include "lightAttrib.h"
#include "textureAttrib.h"
#include "texGenAttrib.h"
#include "renderState.h"
#include "depthWriteAttrib.h"
#include "colorWriteAttrib.h"
#include "textureAttrib.h"
#include "lightAttrib.h"
#include "clipPlaneAttrib.h"
#include "attribSlots.h"
#include "light.h"
#include "planeNode.h"
#include "ambientLight.h"
@ -279,7 +269,8 @@ reset() {
_frame_buffer_stack_level = 0;
_lens_stack_level = 0;
_last_state = NULL;
_state_rs = NULL;
_target_rs = NULL;
_state.clear_to_zero();
_target.clear_to_defaults();
_external_transform = TransformState::make_identity();
@ -430,7 +421,7 @@ release_geom(GeomContext *) {
// Description: Compile a vertex/fragment shader body.
////////////////////////////////////////////////////////////////////
ShaderContext *GraphicsStateGuardian::
prepare_shader(Shader *shader) {
prepare_shader(ShaderExpansion *shader) {
return (ShaderContext *)NULL;
}
@ -672,7 +663,7 @@ begin_frame() {
// have changed properties since last time without changing
// attribute pointers--like textures, lighting, or fog--will still
// be accurately updated.
_last_state = 0;
_state_rs = 0;
_state.clear_to_zero();
return true;
@ -751,7 +742,7 @@ end_scene() {
}
// Put the state into the 'unknown' state, forcing a reload.
_last_state = 0;
_state_rs = 0;
_state.clear_to_zero();
// We need to reset this to force a dynamic texture to be reloaded
@ -1033,15 +1024,15 @@ do_issue_color_scale() {
_current_color_scale = attrib->get_scale();
if (_color_blend_involves_color_scale) {
_last_state = 0;
_state_rs = 0;
_state._transparency = 0;
}
if (_texture_involves_color_scale) {
_last_state = 0;
_state_rs = 0;
_state._texture = 0;
}
if (_color_scale_via_lighting) {
_last_state = 0;
_state_rs = 0;
_state._light = 0;
_state._material = 0;
@ -1090,7 +1081,7 @@ do_issue_color() {
}
if (_color_scale_via_lighting) {
_last_state = 0;
_state_rs = 0;
_state._light = 0;
_state._material = 0;

View File

@ -132,7 +132,7 @@ public:
virtual GeomContext *prepare_geom(Geom *geom);
virtual void release_geom(GeomContext *gc);
virtual ShaderContext *prepare_shader(Shader *shader);
virtual ShaderContext *prepare_shader(ShaderExpansion *shader);
virtual void release_shader(ShaderContext *sc);
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
@ -281,9 +281,10 @@ protected:
PT(SceneSetup) _scene_null;
PT(SceneSetup) _scene_setup;
CPT(RenderState) _last_state;
AttribSlots _state;
AttribSlots _target;
CPT(RenderState) _state_rs;
CPT(RenderState) _target_rs;
CPT(TransformState) _external_transform;
CPT(TransformState) _internal_transform;
CPT(GeomMunger) _munger;

View File

@ -1965,12 +1965,12 @@ do_issue_shade_model() {
// state is already stored in _target.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
set_state_and_transform(const RenderState *state,
set_state_and_transform(const RenderState *target,
const TransformState *transform) {
#ifndef NDEBUG
if (gsg_cat.is_spam()) {
gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
state->write(gsg_cat.spam(false), 2);
gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
target->write(gsg_cat.spam(false), 2);
}
#endif
_state_pcollector.add_level(1);
@ -1982,15 +1982,13 @@ set_state_and_transform(const RenderState *state,
do_issue_transform();
}
if (state) {
if (state == _last_state) {
return;
}
_target.clear_to_defaults();
state->store_into_slots(&_target);
if (target == _state_rs) {
return;
}
_last_state = state;
_target_rs = target;
_target.clear_to_defaults();
target->store_into_slots(&_target);
_state_rs = 0;
if (_target._alpha_test != _state._alpha_test) {
do_issue_alpha_test();
@ -2097,6 +2095,8 @@ set_state_and_transform(const RenderState *state,
do_issue_light();
_state._light = _target._light;
}
_state_rs = _target_rs;
}
////////////////////////////////////////////////////////////////////
@ -2724,7 +2724,7 @@ free_nondx_resources() {
void DXGraphicsStateGuardian8::
free_d3d_device() {
// dont want a full reset of gsg, just a state clear
_last_state = 0;
_state_rs = 0;
_state.clear_to_zero();
// want gsg to pass all state settings through

View File

@ -35,23 +35,7 @@
#include "pointLight.h"
#include "spotlight.h"
#include "planeNode.h"
#include "textureAttrib.h"
#include "lightAttrib.h"
#include "cullFaceAttrib.h"
#include "transparencyAttrib.h"
#include "alphaTestAttrib.h"
#include "depthTestAttrib.h"
#include "depthWriteAttrib.h"
#include "colorWriteAttrib.h"
#include "texMatrixAttrib.h"
#include "texGenAttrib.h"
#include "materialAttrib.h"
#include "renderModeAttrib.h"
#include "rescaleNormalAttrib.h"
#include "fogAttrib.h"
#include "depthOffsetAttrib.h"
#include "shadeModelAttrib.h"
#include "shaderAttrib.h"
#include "attribSlots.h"
#include "fog.h"
#include "clockObject.h"
#include "string_utils.h"
@ -65,8 +49,6 @@
#include "mutexHolder.h"
#include "indirectLess.h"
#include "pStatTimer.h"
#include "shader.h"
#include "shaderMode.h"
#include <algorithm>
@ -771,9 +753,9 @@ reset() {
_texgen_forced_normal = false;
_current_shader_mode = (ShaderMode *)NULL;
_current_shader_expansion = (ShaderExpansion *)NULL;
_current_shader_context = (CLP(ShaderContext) *)NULL;
_vertex_array_shader_mode = (ShaderMode *)NULL;
_vertex_array_shader_expansion = (ShaderExpansion *)NULL;
_vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
// Count the max number of lights
@ -863,18 +845,14 @@ do_clear(const RenderBuffer &buffer) {
_color_clear_value[1],
_color_clear_value[2],
_color_clear_value[3]);
_target._color_write = AttribSlots::get_defaults()._color_write;
mask |= GL_COLOR_BUFFER_BIT;
_target._color_write = AttribSlots::get_defaults()._color_write;
set_draw_buffer(buffer);
}
if (buffer_type & RenderBuffer::T_depth) {
GLP(ClearDepth)(_depth_clear_value);
mask |= GL_DEPTH_BUFFER_BIT;
// In order to clear the depth buffer, the depth mask must enable
// writing to the depth buffer.
_target._depth_write = AttribSlots::get_defaults()._depth_write;
}
@ -908,7 +886,19 @@ do_clear(const RenderBuffer &buffer) {
GLCAT.spam(false) << ")" << endl;
}
set_state_and_transform(NULL, _external_transform);
if (_target._depth_write != _state._depth_write) {
do_issue_depth_write();
_state._depth_write = _target._depth_write;
}
if ((_target._transparency != _state._transparency)||
(_target._color_write != _state._color_write)||
(_target._color_blend != _state._color_blend)) {
do_issue_blending();
_state._transparency = _target._transparency;
_state._color_write = _target._color_write;
_state._color_blend = _target._color_blend;
}
_state_rs = 0;
GLP(Clear)(mask);
report_my_gl_errors();
@ -1312,7 +1302,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
update_shader_vertex_arrays(_vertex_array_shader_context,this);
}
}
_vertex_array_shader_mode = _current_shader_mode;
_vertex_array_shader_expansion = _current_shader_expansion;
_vertex_array_shader_context = _current_shader_context;
report_my_gl_errors();
@ -2008,8 +1998,8 @@ release_geom(GeomContext *gc) {
// Description: yadda.
////////////////////////////////////////////////////////////////////
ShaderContext *CLP(GraphicsStateGuardian)::
prepare_shader(Shader *shader) {
CLP(ShaderContext) *result = new CLP(ShaderContext)(shader);
prepare_shader(ShaderExpansion *se) {
CLP(ShaderContext) *result = new CLP(ShaderContext)(se);
if (result->valid()) return result;
delete result;
return NULL;
@ -2438,7 +2428,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
report_my_gl_errors();
// Force reload of texture state, since we've just monkeyed with it.
_last_state = 0;
_state_rs = 0;
_state._texture = 0;
}
@ -2464,7 +2454,11 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
// NOTE: reading the depth buffer is *much* slower than reading the
// color buffer
_target._texture = AttribSlots::get_defaults()._texture;
set_state_and_transform(NULL, _external_transform);
if (_target._texture != _state._texture) {
do_issue_texture();
_state._texture = _target._texture;
}
_state_rs = 0;
int xo, yo, w, h;
dr->get_region_pixels(xo, yo, w, h);
@ -2641,7 +2635,7 @@ do_issue_transform() {
}
if (_current_shader_context)
_current_shader_context->issue_transform(_current_shader_mode, this);
_current_shader_context->issue_transform(this);
report_my_gl_errors();
}
@ -2670,28 +2664,30 @@ do_issue_shade_model() {
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::do_issue_shader
// Access: Protected
// Description: Bind a shader.
// Description:
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
do_issue_shader() {
const ShaderAttrib *attrib = _target._shader;
ShaderMode *mode = attrib->get_shader_mode();
if (mode == 0) {
if (_current_shader_context != 0) {
_current_shader_context->unbind();
_current_shader_mode = 0;
_current_shader_context = 0;
CLP(ShaderContext) *context = 0;
ShaderExpansion *expansion = _target_rs->get_shader_expansion();
if (expansion == 0) {
if (_target._shader->get_shader() != 0) {
expansion = _target._shader->get_shader()->macroexpand(_target_rs);
// I am casting away the const-ness of this pointer, because
// the 'shader-expansion' field is just a cache.
((RenderState *)((const RenderState*)_target_rs))->
set_shader_expansion(expansion);
}
return;
}
Shader *shader = mode->get_shader();
CLP(ShaderContext) *context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
if (expansion) {
context = (CLP(ShaderContext) *)(expansion->prepare_now(get_prepared_objects(), this));
}
if (context == 0) {
if (_current_shader_context != 0) {
_current_shader_context->unbind();
_current_shader_mode = 0;
_current_shader_expansion = 0;
_current_shader_context = 0;
}
return;
@ -2703,19 +2699,18 @@ do_issue_shader() {
if (_current_shader_context != 0) {
_current_shader_context->unbind();
_current_shader_context = 0;
_current_shader_expansion = 0;
}
if (context != 0) {
context->bind(mode, this);
_current_shader_mode = mode;
context->bind(this);
_current_shader_expansion = expansion;
_current_shader_context = context;
}
} else {
// Use the same shader as before, but with new input arguments.
_current_shader_mode = mode;
_current_shader_context = context;
context->issue_parameters(mode, this);
context->issue_parameters(this);
}
report_my_gl_errors();
}
@ -3062,6 +3057,128 @@ do_issue_material() {
report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::do_issue_blending
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
do_issue_blending() {
// Handle the color_write attrib. If color_write is off, then
// all the other blending-related stuff doesn't matter. If the
// device doesn't support color-write, we use blending tricks
// to effectively disable color write.
if (_target._color_write->get_mode() == ColorWriteAttrib::M_off) {
if (_target._color_write != _state._color_write) {
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
if (CLP(color_mask)) {
enable_blend(false);
GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
} else {
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_ZERO, GL_ONE);
}
}
return;
} else {
if (_target._color_write != _state._color_write) {
if (CLP(color_mask)) {
GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
}
CPT(ColorBlendAttrib) color_blend = _target._color_blend;
ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode();
TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode();
_color_blend_involves_color_scale = color_blend->involves_color_scale();
// Is there a color blend set?
if (color_blend_mode != ColorBlendAttrib::M_none) {
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(get_blend_equation_type(color_blend_mode));
GLP(BlendFunc)(get_blend_func(color_blend->get_operand_a()),
get_blend_func(color_blend->get_operand_b()));
if (_color_blend_involves_color_scale) {
// Apply the current color scale to the blend mode.
_glBlendColor(_current_color_scale[0], _current_color_scale[1],
_current_color_scale[2], _current_color_scale[3]);
} else {
Colorf c = color_blend->get_color();
_glBlendColor(c[0], c[1], c[2], c[3]);
}
return;
}
// No color blend; is there a transparency set?
switch (transparency_mode) {
case TransparencyAttrib::M_none:
case TransparencyAttrib::M_binary:
break;
case TransparencyAttrib::M_alpha:
case TransparencyAttrib::M_dual:
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
case TransparencyAttrib::M_multisample:
// We need to enable *both* of these in M_multisample case.
enable_multisample_alpha_one(true);
enable_multisample_alpha_mask(true);
enable_blend(false);
return;
case TransparencyAttrib::M_multisample_mask:
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(true);
enable_blend(false);
return;
default:
GLCAT.error()
<< "invalid transparency mode " << (int)transparency_mode << endl;
break;
}
if (_line_smooth_enabled || _point_smooth_enabled) {
// If we have either of these turned on, we also need to have
// blend mode enabled in order to see it.
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
}
// For best polygon smoothing, we need:
// (1) a frame buffer that supports alpha
// (2) sort polygons front-to-back
// (3) glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
//
// Since these modes have other implications for the application, we
// don't attempt to do this by default. If you really want good
// polygon smoothing (and you don't have multisample support), do
// all this yourself.
// Nothing's set, so disable blending.
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(false);
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::bind_light
// Access: Public, Virtual
@ -4429,128 +4546,6 @@ end_bind_clip_planes() {
GLP(PopMatrix)();
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::do_issue_blending
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
do_issue_blending() {
// If necessary, we disable writing to the color buffer using
// blending. This case is only used if we can't use GLP(ColorMask)
// to disable the color writing for some reason (usually a driver
// problem).
if (_target._color_write->get_mode() == ColorWriteAttrib::M_off) {
if (_target._color_write != _state._color_write) {
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
if (CLP(color_mask)) {
enable_blend(false);
GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
} else {
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_ZERO, GL_ONE);
}
}
return;
} else {
if (_target._color_write != _state._color_write) {
if (CLP(color_mask)) {
GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
}
}
CPT(ColorBlendAttrib) color_blend = _target._color_blend;
ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode();
TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode();
_color_blend_involves_color_scale = color_blend->involves_color_scale();
// Is there a color blend set?
if (color_blend_mode != ColorBlendAttrib::M_none) {
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(get_blend_equation_type(color_blend_mode));
GLP(BlendFunc)(get_blend_func(color_blend->get_operand_a()),
get_blend_func(color_blend->get_operand_b()));
if (_color_blend_involves_color_scale) {
// Apply the current color scale to the blend mode.
_glBlendColor(_current_color_scale[0], _current_color_scale[1],
_current_color_scale[2], _current_color_scale[3]);
} else {
Colorf c = color_blend->get_color();
_glBlendColor(c[0], c[1], c[2], c[3]);
}
return;
}
// No color blend; is there a transparency set?
switch (transparency_mode) {
case TransparencyAttrib::M_none:
case TransparencyAttrib::M_binary:
break;
case TransparencyAttrib::M_alpha:
case TransparencyAttrib::M_dual:
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
case TransparencyAttrib::M_multisample:
// We need to enable *both* of these in M_multisample case.
enable_multisample_alpha_one(true);
enable_multisample_alpha_mask(true);
enable_blend(false);
return;
case TransparencyAttrib::M_multisample_mask:
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(true);
enable_blend(false);
return;
default:
GLCAT.error()
<< "invalid transparency mode " << (int)transparency_mode << endl;
break;
}
if (_line_smooth_enabled || _point_smooth_enabled) {
// If we have either of these turned on, we also need to have
// blend mode enabled in order to see it.
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(true);
_glBlendEquation(GL_FUNC_ADD);
GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
}
// For best polygon smoothing, we need:
// (1) a frame buffer that supports alpha
// (2) sort polygons front-to-back
// (3) glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
//
// Since these modes have other implications for the application, we
// don't attempt to do this by default. If you really want good
// polygon smoothing (and you don't have multisample support), do
// all this yourself.
// Nothing's set, so disable blending.
enable_multisample_alpha_one(false);
enable_multisample_alpha_mask(false);
enable_blend(false);
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::set_state_and_transform
// Access: Public, Virtual
@ -4562,17 +4557,14 @@ do_issue_blending() {
// space; internally, it will be pretransformed by
// get_cs_transform() to express it in the GSG's
// internal coordinate space.
//
// Special case: if (state==NULL), then the target
// state is already stored in _target.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
set_state_and_transform(const RenderState *state,
set_state_and_transform(const RenderState *target,
const TransformState *transform) {
#ifndef NDEBUG
if (gsg_cat.is_spam()) {
gsg_cat.spam() << "Setting GSG state to " << (void *)state << ":\n";
state->write(gsg_cat.spam(false), 2);
gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
target->write(gsg_cat.spam(false), 2);
}
#endif
_state_pcollector.add_level(1);
@ -4584,15 +4576,13 @@ set_state_and_transform(const RenderState *state,
do_issue_transform();
}
if (state) {
if (state == _last_state) {
return;
}
_target.clear_to_defaults();
state->store_into_slots(&_target);
if (target == _state_rs) {
return;
}
_last_state = state;
_target_rs = target;
_target.clear_to_defaults();
target->store_into_slots(&_target);
_state_rs = 0;
if (_target._alpha_test != _state._alpha_test) {
do_issue_alpha_test();
@ -4978,6 +4968,8 @@ set_state_and_transform(const RenderState *state,
report_my_gl_errors();
}
_state_rs = _target_rs;
}
////////////////////////////////////////////////////////////////////
@ -5234,7 +5226,7 @@ do_issue_texture() {
// texgen and texmat attribs.
_needs_tex_gen = true;
_needs_tex_mat = true;
report_my_gl_errors();
}

View File

@ -38,8 +38,6 @@
#include "pmap.h"
#include "geomVertexArrayData.h"
#include "pmutex.h"
#include "shader.h"
#include "shaderMode.h"
class PlaneNode;
class Light;
@ -104,9 +102,9 @@ public:
virtual GeomContext *prepare_geom(Geom *geom);
virtual void release_geom(GeomContext *gc);
virtual ShaderContext *prepare_shader(Shader *shader);
virtual ShaderContext *prepare_shader(ShaderExpansion *shader);
virtual void release_shader(ShaderContext *sc);
void record_deleted_display_list(GLuint index);
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
@ -308,10 +306,10 @@ protected:
bool _point_perspective;
bool _vertex_blending_enabled;
PT(ShaderMode) _current_shader_mode;
CLP(ShaderContext) *_current_shader_context;
PT(ShaderMode) _vertex_array_shader_mode;
CLP(ShaderContext) *_vertex_array_shader_context;
PT(ShaderExpansion) _current_shader_expansion;
CLP(ShaderContext) *_current_shader_context;
PT(ShaderExpansion) _vertex_array_shader_expansion;
CLP(ShaderContext) *_vertex_array_shader_context;
CPT(DisplayRegion) _actual_display_region;

View File

@ -24,7 +24,7 @@ TypeHandle CLP(ShaderContext)::_type_handle;
// Description: xyz
////////////////////////////////////////////////////////////////////
CLP(ShaderContext)::
CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
CLP(ShaderContext)(ShaderExpansion *s) : ShaderContext(s) {
string header;
s->parse_init();
s->parse_line(header, true, true);
@ -58,13 +58,13 @@ CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
_cg_program[0] =
cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
_cg_profile[0], "vshader", (const char**)NULL);
print_cg_compile_errors(s->_file, _cg_context);
print_cg_compile_errors(s->get_name(), _cg_context);
cgGetError();
_cg_program[1] =
cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
_cg_profile[1], "fshader", (const char**)NULL);
print_cg_compile_errors(s->_file, _cg_context);
print_cg_compile_errors(s->get_name(), _cg_context);
if ((_cg_program[SHADER_type_vert]==0)||(_cg_program[SHADER_type_frag]==0)) {
release_resources();
@ -88,12 +88,12 @@ CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
cgGLLoadProgram(_cg_program[SHADER_type_vert]);
cgGLLoadProgram(_cg_program[SHADER_type_frag]);
cerr << s->_file << ": compiled ok.\n";
cerr << s->get_name() << ": compiled ok.\n";
return;
}
#endif
cerr << s->_file << ": unrecognized shader language " << header << "\n";
cerr << s->get_name() << ": unrecognized shader language " << header << "\n";
}
////////////////////////////////////////////////////////////////////
@ -134,13 +134,13 @@ release_resources() {
// input parameters.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
bind(ShaderMode *m, GSG *gsg) {
bind(GSG *gsg) {
#ifdef HAVE_CGGL
if (_cg_context != 0) {
// Pass in k-parameters and transform-parameters
issue_parameters(m, gsg);
issue_transform(m, gsg);
issue_parameters(gsg);
issue_transform(gsg);
// Bind the shaders.
cgGLEnableProfile(_cg_profile[SHADER_type_vert]);
@ -171,39 +171,42 @@ unbind()
// Function: GLShaderContext::issue_parameters
// Access: Public
// Description: This function is to be called whenever
// the ShaderMode has changed, but the Shader
// itself has not changed. It loads the new
// input parameters into the already-bound shader.
// the RenderState has changed, but the ShaderExpansion
// has not changed. It loads the new input parameters
// into the already-bound shader.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
issue_parameters(ShaderMode *m, GSG *gsg)
issue_parameters(GSG *gsg)
{
#ifdef HAVE_CGGL
if (_cg_context != 0) {
// Pass in k-float parameters.
for (int i=0; i<(int)_cg_fbind.size(); i++) {
int index = _cg_fbind[i].argindex;
if (index >= (int)m->_args.size()) continue;
if (m->_args[index]._type != ShaderModeArg::SAT_FLOAT) continue;
cgGLSetParameter4dv(_cg_fbind[i].parameter, m->_args[index]._fvalue.get_data());
InternalName *id = _cg_fbind[i].name;
const ShaderInput *input = gsg->_target._shader->get_input(id);
cgGLSetParameter4fv(_cg_fbind[i].parameter, input->get_vector().get_data());
}
// Pass in k-float4x4 parameters.
for (int i=0; i<(int)_cg_npbind.size(); i++) {
int index = _cg_npbind[i].argindex;
if (index >= (int)m->_args.size()) continue;
if (m->_args[index]._type != ShaderModeArg::SAT_NODEPATH) continue;
const float *dat = m->_args[index]._nvalue.node()->get_transform()->get_mat().get_data();
InternalName *id = _cg_npbind[i].name;
const ShaderInput *input = gsg->_target._shader->get_input(id);
const float *dat;
if (input->get_nodepath().is_empty()) {
dat = LMatrix4f::ident_mat().get_data();
} else {
dat = input->get_nodepath().node()->get_transform()->get_mat().get_data();
}
cgGLSetMatrixParameterfc(_cg_npbind[i].parameter, dat);
}
// Pass in trans,tpose,row,col,xvec,yvec,zvec,pos parameters
for (int i=0; i<(int)_cg_parameter_bind.size(); i++)
bind_cg_transform(_cg_parameter_bind[i], m, gsg);
bind_cg_transform(_cg_parameter_bind[i], gsg);
// Pass in trans,tpose,row,col,xvec,yvec,zvec,pos parameters
for (int i=0; i<(int)_cg_transform_bind.size(); i++)
bind_cg_transform(_cg_transform_bind[i], m, gsg);
bind_cg_transform(_cg_transform_bind[i], gsg);
}
#endif
}
@ -213,11 +216,11 @@ issue_parameters(ShaderMode *m, GSG *gsg)
// Access: Public
// Description: This function is to be called whenever
// the external_transform has changed, but the
// Shader itself has not changed. It loads the
// ShaderExpansion itself has not changed. It loads the
// new transform into the already-bound shader.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
issue_transform(ShaderMode *m, GSG *gsg)
issue_transform(GSG *gsg)
{
#ifdef HAVE_CGGL
if (_cg_context != 0) {
@ -229,7 +232,7 @@ issue_transform(ShaderMode *m, GSG *gsg)
// Pass in trans,tpose,row,col,xvec,yvec,zvec,pos parameters
for (int i=0; i<(int)_cg_transform_bind.size(); i++)
bind_cg_transform(_cg_transform_bind[i], m, gsg);
bind_cg_transform(_cg_transform_bind[i], gsg);
}
#endif
}
@ -284,8 +287,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
gsg->_current_texture->get_on_stages();
if (texslot < (int)active_stages.size()) {
TextureStage *stage = active_stages[texslot];
const InternalName *slotname = stage->get_texcoord_name();
name = name->append(slotname->get_name());
name = name->append(stage->get_texcoord_name()->get_name());
}
}
if (gsg->_vertex_data->get_array_info(name,
@ -309,42 +311,43 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
////////////////////////////////////////////////////////////////////
// Function: GLShaderContext::bind_cg_transform
// Access: Public
// Description: Should deallocate all system resources (such as
// vertex program handles or Cg contexts).
// Description:
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
bind_cg_transform(const ShaderTransBind &stb, ShaderMode *m, GSG *gsg)
bind_cg_transform(const ShaderTransBind &stb, GSG *gsg)
{
CPT(TransformState) src;
CPT(TransformState) rel;
if (stb.src_argindex < 0) {
if (stb.src_argindex == SHADER_arg_camera)
src = TransformState::make_identity();
else if (stb.src_argindex == SHADER_arg_model)
src = gsg->get_transform();
else
src = gsg->get_scene()->get_world_transform();
if (stb.src_name == InternalName::get_camera()) {
src = TransformState::make_identity();
} else if (stb.src_name == InternalName::get_model()) {
src = gsg->get_transform();
} else if (stb.src_name == InternalName::get_world()) {
src = gsg->get_scene()->get_world_transform();
} else {
if ((int)m->_args.size() > stb.src_argindex) {
ShaderModeArg *arg = &(m->_args[stb.src_argindex]);
if (arg->_type == ShaderModeArg::SAT_NODEPATH)
src = gsg->get_scene()->get_world_transform()->compose(arg->_nvalue.get_net_transform());
const ShaderInput *input = gsg->_target._shader->get_input(stb.src_name);
if (input->get_nodepath().is_empty()) {
src = gsg->get_scene()->get_world_transform();
} else {
src = gsg->get_scene()->get_world_transform()->
compose(input->get_nodepath().get_net_transform());
}
}
if (stb.rel_argindex < 0) {
if (stb.rel_argindex == SHADER_arg_camera)
rel = TransformState::make_identity();
else if (stb.rel_argindex == SHADER_arg_model)
rel = gsg->get_transform();
else
rel = gsg->get_scene()->get_world_transform();
if (stb.rel_name == InternalName::get_camera()) {
rel = TransformState::make_identity();
} else if (stb.rel_name == InternalName::get_model()) {
rel = gsg->get_transform();
} else if (stb.rel_name == InternalName::get_world()) {
rel = gsg->get_scene()->get_world_transform();
} else {
if ((int)m->_args.size() > stb.rel_argindex) {
ShaderModeArg *arg = &(m->_args[stb.rel_argindex]);
if (arg->_type == ShaderModeArg::SAT_NODEPATH)
rel = gsg->get_scene()->get_world_transform()->compose(arg->_nvalue.get_net_transform());
const ShaderInput *input = gsg->_target._shader->get_input(stb.rel_name);
if (input->get_nodepath().is_empty()) {
rel = gsg->get_scene()->get_world_transform();
} else {
rel = gsg->get_scene()->get_world_transform()->
compose(input->get_nodepath().get_net_transform());
}
}
@ -526,7 +529,7 @@ errchk_cg_output(CGparameter p, const string &msg)
const char *ts = cgGetTypeString(cgGetParameterType(p));
string err;
string fn = _shader->_file;
string fn = _shader_expansion->get_name();
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
cerr << err << "\n";
}
@ -656,14 +659,8 @@ compile_cg_parameter(CGparameter p)
else if (pieces[0]=="col2") bind.trans_piece = SHADER_data_col2;
else if (pieces[0]=="col3") bind.trans_piece = SHADER_data_col3;
if (pieces[1] == "world") bind.src_argindex = SHADER_arg_world;
else if (pieces[1] == "camera") bind.src_argindex = SHADER_arg_camera;
else if (pieces[1] == "model") bind.src_argindex = SHADER_arg_model;
else bind.src_argindex = _shader->arg_index(pieces[1]);
if (pieces[3] == "world") bind.rel_argindex = SHADER_arg_world;
else if (pieces[3] == "camera") bind.rel_argindex = SHADER_arg_camera;
else if (pieces[3] == "model") bind.rel_argindex = SHADER_arg_model;
else bind.rel_argindex = _shader->arg_index(pieces[3]);
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 (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
@ -672,8 +669,8 @@ compile_cg_parameter(CGparameter p)
}
_cg_parameter_bind.push_back(bind);
if ((bind.src_argindex == SHADER_arg_model) ||
(bind.rel_argindex == SHADER_arg_model)) {
if ((bind.src_name == InternalName::get_model()) ||
(bind.rel_name == InternalName::get_model())) {
_cg_transform_bind.push_back(bind);
}
return true;
@ -692,17 +689,14 @@ compile_cg_parameter(CGparameter p)
ShaderTransBind bind;
bind.parameter = p;
if (pieces[0]=="wstrans") { bind.rel_argindex = SHADER_arg_world; bind.trans_piece = SHADER_data_matrix; }
else if (pieces[0]=="cstrans") { bind.rel_argindex = SHADER_arg_camera; bind.trans_piece = SHADER_data_matrix; }
else if (pieces[0]=="mstrans") { bind.rel_argindex = SHADER_arg_model; bind.trans_piece = SHADER_data_matrix; }
else if (pieces[0]=="wspos") { bind.rel_argindex = SHADER_arg_world; bind.trans_piece = SHADER_data_row3; }
else if (pieces[0]=="cspos") { bind.rel_argindex = SHADER_arg_camera; bind.trans_piece = SHADER_data_row3; }
else if (pieces[0]=="mspos") { bind.rel_argindex = SHADER_arg_model; bind.trans_piece = SHADER_data_row3; }
if (pieces[1] == "world") bind.src_argindex = SHADER_arg_world;
else if (pieces[1] == "camera") bind.src_argindex = SHADER_arg_camera;
else if (pieces[1] == "model") bind.src_argindex = SHADER_arg_model;
else bind.src_argindex = _shader->arg_index(pieces[1]);
if (pieces[0]=="wstrans") { bind.rel_name = InternalName::get_world(); 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]=="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; }
bind.src_name = InternalName::make(pieces[1]);
if ((bind.trans_piece == SHADER_data_matrix)||(bind.trans_piece == SHADER_data_transpose)) {
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
@ -710,9 +704,10 @@ compile_cg_parameter(CGparameter p)
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
}
_cg_parameter_bind.push_back(bind);
if ((bind.src_argindex == SHADER_arg_model) ||
(bind.rel_argindex == SHADER_arg_model))
if ((bind.src_name == InternalName::get_model()) ||
(bind.rel_name == InternalName::get_model())) {
_cg_transform_bind.push_back(bind);
}
return true;
}
@ -760,7 +755,7 @@ compile_cg_parameter(CGparameter p)
return false;
ShaderArgBind bind;
bind.parameter = p;
bind.argindex = _shader->arg_index(pieces[1]);
bind.name = InternalName::make(pieces[1]);
switch (cgGetParameterType(p)) {
case CG_FLOAT4: _cg_fbind.push_back(bind); break;
case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
@ -772,17 +767,17 @@ compile_cg_parameter(CGparameter p)
}
return true;
}
if (pieces[0] == "l") {
// IMPLEMENT THE ERROR CHECKING
return true; // Cg handles this automatically.
}
if (pieces[0] == "o") {
// IMPLEMENT THE ERROR CHECKING
return true; // Cg handles this automatically.
}
errchk_cg_output(p, "unrecognized parameter name");
return false;
}

View File

@ -17,11 +17,13 @@
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "shaderContext.h"
#ifdef HAVE_CGGL
#include "Cg/cgGL.h"
#endif
#include "string_utils.h"
#include "internalName.h"
#include "shaderExpansion.h"
#include "shaderContext.h"
class CLP(GraphicsStateGuardian);
@ -32,15 +34,15 @@ class CLP(GraphicsStateGuardian);
class EXPCL_GL CLP(ShaderContext): public ShaderContext {
public:
CLP(ShaderContext)(Shader *s);
CLP(ShaderContext)(ShaderExpansion *s);
~CLP(ShaderContext)();
typedef CLP(GraphicsStateGuardian) GSG;
INLINE bool valid(void);
void bind(ShaderMode *mode, GSG *gsg);
void bind(GSG *gsg);
void unbind();
void issue_parameters(ShaderMode *mode, GSG *gsg);
void issue_transform(ShaderMode *mode, GSG *gsg);
void issue_parameters(GSG *gsg);
void issue_transform(GSG *gsg);
void disable_shader_vertex_arrays(GSG *gsg);
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
@ -54,12 +56,12 @@ private:
};
struct ShaderArgBind {
CGparameter parameter;
int argindex;
PT(InternalName) name;
};
struct ShaderTransBind {
CGparameter parameter;
int src_argindex;
int rel_argindex;
PT(InternalName) src_name;
PT(InternalName) rel_name;
int trans_piece;
};
struct ShaderVarying {
@ -82,7 +84,7 @@ private:
vector <ShaderTransBind> _cg_parameter_bind;
vector <ShaderVarying> _cg_varying;
void bind_cg_transform(const ShaderTransBind &stb, ShaderMode *m,
void bind_cg_transform(const ShaderTransBind &stb,
CLP(GraphicsStateGuardian) *gsg);
bool compile_cg_parameter(CGparameter p);

View File

@ -42,7 +42,7 @@
#include "texture.h"
#include "textureStage.h"
#include "textureContext.h"
#include "shader.h"
#include "shaderExpansion.h"
#include "shaderContext.h"
#include "transformBlendTable.h"
#include "transformTable.h"
@ -249,7 +249,7 @@ ConfigureFn(config_gobj) {
Texture::init_type();
dDrawable::init_type();
TextureStage::init_type();
Shader::init_type();
ShaderExpansion::init_type();
ShaderContext::init_type();
TransformBlendTable::init_type();
TransformTable::init_type();
@ -278,7 +278,6 @@ ConfigureFn(config_gobj) {
MatrixLens::register_with_read_factory();
PerspectiveLens::register_with_read_factory();
SliderTable::register_with_read_factory();
Shader::register_with_read_factory();
Texture::register_with_read_factory();
TextureStage::register_with_read_factory();
TransformBlendTable::register_with_read_factory();

View File

@ -16,7 +16,7 @@
#include "textureContext.cxx"
#include "texturePool.cxx"
#include "textureStage.cxx"
#include "shader.cxx"
#include "shaderExpansion.cxx"
#include "shaderContext.cxx"
#include "transformBlend.cxx"
#include "transformBlendTable.cxx"

View File

@ -375,6 +375,53 @@ get_index() {
return _index;
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::get_world
// Access: Published, Static
// Description: Returns the standard InternalName "world". This is
// used as a keyword in the shader subsystem.
////////////////////////////////////////////////////////////////////
INLINE PT(InternalName) InternalName::
get_world() {
if (_world == (InternalName *)NULL) {
_world = InternalName::make("world");
}
return _world;
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::get_camera
// Access: Published, Static
// Description: Returns the standard InternalName "camera". This is
// used as a keyword in the shader subsystem.
////////////////////////////////////////////////////////////////////
INLINE PT(InternalName) InternalName::
get_camera() {
if (_camera == (InternalName *)NULL) {
_camera = InternalName::make("camera");
}
return _camera;
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::get_model
// Access: Published, Static
// Description: Returns the standard InternalName "model". This is
// used as a keyword in the shader subsystem.
////////////////////////////////////////////////////////////////////
INLINE PT(InternalName) InternalName::
get_model() {
if (_model == (InternalName *)NULL) {
_model = InternalName::make("model");
}
return _model;
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::output operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ostream &
operator << (ostream &out, const InternalName &tcn) {
tcn.output(out);

View File

@ -39,6 +39,9 @@ PT(InternalName) InternalName::_transform_blend;
PT(InternalName) InternalName::_transform_weight;
PT(InternalName) InternalName::_transform_index;
PT(InternalName) InternalName::_index;
PT(InternalName) InternalName::_world;
PT(InternalName) InternalName::_camera;
PT(InternalName) InternalName::_model;
TypeHandle InternalName::_type_handle;
TypeHandle InternalName::_texcoord_type_handle;

View File

@ -81,6 +81,9 @@ PUBLISHED:
INLINE static PT(InternalName) get_transform_index();
INLINE static PT(InternalName) get_morph(InternalName *column, const string &slider);
INLINE static PT(InternalName) get_index();
INLINE static PT(InternalName) get_world();
INLINE static PT(InternalName) get_camera();
INLINE static PT(InternalName) get_model();
private:
PT(InternalName) _parent;
@ -105,6 +108,9 @@ private:
static PT(InternalName) _transform_weight;
static PT(InternalName) _transform_index;
static PT(InternalName) _index;
static PT(InternalName) _world;
static PT(InternalName) _camera;
static PT(InternalName) _model;
public:
// Datagram stuff

View File

@ -24,7 +24,7 @@
#include "geom.h"
#include "geomVertexArrayData.h"
#include "geomPrimitive.h"
#include "shader.h"
#include "shaderExpansion.h"
#include "mutexHolder.h"
PStatCollector PreparedGraphicsObjects::_total_texusage_pcollector("Texture usage");
@ -83,7 +83,7 @@ PreparedGraphicsObjects::
sci != _prepared_shaders.end();
++sci) {
ShaderContext *sc = (*sci);
sc->_shader->clear_prepared(this);
sc->_shader_expansion->clear_prepared(this);
}
_prepared_shaders.clear();
@ -410,10 +410,10 @@ prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg) {
// do this (presumably at the next frame).
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
enqueue_shader(Shader *shader) {
enqueue_shader(ShaderExpansion *se) {
MutexHolder holder(_lock);
_enqueued_shaders.insert(shader);
_enqueued_shaders.insert(se);
}
////////////////////////////////////////////////////////////////////
@ -431,10 +431,10 @@ enqueue_shader(Shader *shader) {
// queued.
////////////////////////////////////////////////////////////////////
bool PreparedGraphicsObjects::
dequeue_shader(Shader *shader) {
dequeue_shader(ShaderExpansion *se) {
MutexHolder holder(_lock);
EnqueuedShaders::iterator qi = _enqueued_shaders.find(shader);
EnqueuedShaders::iterator qi = _enqueued_shaders.find(se);
if (qi != _enqueued_shaders.end()) {
_enqueued_shaders.erase(qi);
return true;
@ -459,12 +459,12 @@ void PreparedGraphicsObjects::
release_shader(ShaderContext *sc) {
MutexHolder holder(_lock);
sc->_shader->clear_prepared(this);
sc->_shader_expansion->clear_prepared(this);
// We have to set the Shader pointer to NULL at this point, since
// the Shader itself might destruct at any time after it has been
// released.
sc->_shader = (Shader *)NULL;
sc->_shader_expansion = (ShaderExpansion *)NULL;
bool removed = (_prepared_shaders.erase(sc) != 0);
nassertv(removed);
@ -491,8 +491,8 @@ release_all_shaders() {
sci != _prepared_shaders.end();
++sci) {
ShaderContext *sc = (*sci);
sc->_shader->clear_prepared(this);
sc->_shader = (Shader *)NULL;
sc->_shader_expansion->clear_prepared(this);
sc->_shader_expansion = (ShaderExpansion *)NULL;
_released_shaders.insert(sc);
}
@ -525,14 +525,14 @@ release_all_shaders() {
// ShaderContext will be deleted.
////////////////////////////////////////////////////////////////////
ShaderContext *PreparedGraphicsObjects::
prepare_shader_now(Shader *shader, GraphicsStateGuardianBase *gsg) {
prepare_shader_now(ShaderExpansion *se, GraphicsStateGuardianBase *gsg) {
MutexHolder holder(_lock);
// Ask the GSG to create a brand new ShaderContext. There might
// be several GSG's sharing the same set of shaders; if so, it
// doesn't matter which of them creates the context (since they're
// all shared anyway).
ShaderContext *sc = gsg->prepare_shader(shader);
ShaderContext *sc = gsg->prepare_shader(se);
if (sc != (ShaderContext *)NULL) {
bool prepared = _prepared_shaders.insert(sc).second;
@ -930,7 +930,7 @@ update(GraphicsStateGuardianBase *gsg) {
for (qsi = _enqueued_shaders.begin();
qsi != _enqueued_shaders.end();
++qsi) {
Shader *shader = (*qsi);
ShaderExpansion *shader = (*qsi);
shader->prepare_now(this, gsg);
}

View File

@ -25,7 +25,7 @@
#include "geom.h"
#include "geomVertexArrayData.h"
#include "geomPrimitive.h"
#include "shader.h"
#include "shaderExpansion.h"
#include "pointerTo.h"
#include "pStatCollector.h"
#include "pset.h"
@ -78,12 +78,12 @@ public:
GeomContext *prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg);
void enqueue_shader(Shader *shader);
bool dequeue_shader(Shader *shader);
void enqueue_shader(ShaderExpansion *shader);
bool dequeue_shader(ShaderExpansion *shader);
void release_shader(ShaderContext *sc);
int release_all_shaders();
ShaderContext *prepare_shader_now(Shader *shader, GraphicsStateGuardianBase *gsg);
ShaderContext *prepare_shader_now(ShaderExpansion *shader, GraphicsStateGuardianBase *gsg);
void enqueue_vertex_buffer(GeomVertexArrayData *data);
bool dequeue_vertex_buffer(GeomVertexArrayData *data);
@ -111,7 +111,7 @@ private:
typedef phash_set<GeomContext *, pointer_hash> Geoms;
typedef phash_set< PT(Geom) > EnqueuedGeoms;
typedef phash_set<ShaderContext *, pointer_hash> Shaders;
typedef phash_set< PT(Shader) > EnqueuedShaders;
typedef phash_set< PT(ShaderExpansion) > EnqueuedShaders;
typedef phash_set<VertexBufferContext *, pointer_hash> VertexBuffers;
typedef phash_set< PT(GeomVertexArrayData) > EnqueuedVertexBuffers;
typedef phash_set<IndexBufferContext *, pointer_hash> IndexBuffers;

View File

@ -22,8 +22,8 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderContext::
ShaderContext(Shader *s) :
_shader(s)
ShaderContext(ShaderExpansion *se) :
_shader_expansion(se)
{
}

View File

@ -22,7 +22,7 @@
#include "pandabase.h"
#include "internalName.h"
#include "savedContext.h"
#include "shader.h"
#include "shaderExpansion.h"
////////////////////////////////////////////////////////////////////
// Class : ShaderContext
@ -38,9 +38,9 @@
class EXPCL_PANDA ShaderContext: public SavedContext {
public:
INLINE ShaderContext(Shader *shader);
INLINE ShaderContext(ShaderExpansion *se);
Shader *_shader;
ShaderExpansion *_shader_expansion;
public:
// The following declarations represent useful routines
@ -51,11 +51,6 @@ public:
SHADER_type_frag=1,
SHADER_type_both=2,
};
enum {
SHADER_arg_world = -1,
SHADER_arg_camera = -2,
SHADER_arg_model = -3,
};
enum {
SHADER_data_matrix,
SHADER_data_transpose,

View File

@ -1,4 +1,4 @@
// Filename: shader.I
// Filename: shaderExpansion.I
// Heavily Modified: jyelon (Sep05)
//
////////////////////////////////////////////////////////////////////
@ -17,22 +17,22 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: Shader::get_text
// Function: ShaderExpansion::get_name
// Access: Public
// Description: Return the shader's text.
// Description: Return the ShaderExpansion's text.
////////////////////////////////////////////////////////////////////
INLINE const string &Shader::
get_text() {
INLINE const string &ShaderExpansion::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderExpansion::get_text
// Access: Public
// Description: Return the ShaderExpansion's text.
////////////////////////////////////////////////////////////////////
INLINE const string &ShaderExpansion::
get_text() const {
return _text;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::get_file
// Access: Public
// Description: Return the shader's filename, or null string.
////////////////////////////////////////////////////////////////////
INLINE const Filename &Shader::
get_file() {
return _file;
}

View File

@ -1,5 +1,5 @@
// Filename: shader.cxx
// Created by: jyelon (Sep05)
// Filename: shaderExpansion.cxx
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
@ -17,55 +17,76 @@
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "shader.h"
#include "shaderExpansion.h"
TypeHandle Shader::_type_handle;
TypeHandle ShaderExpansion::_type_handle;
ShaderExpansion::ExpansionCache ShaderExpansion::_expansion_cache;
////////////////////////////////////////////////////////////////////
// Function: Shader::Constructor
// Access: Public
// Description: Construct a Shader.
// Function: ShaderExpansion::Constructor
// Access: Private
// Description: Construct a ShaderExpansion.
////////////////////////////////////////////////////////////////////
Shader::
Shader(const string &text, const string &file) {
_text = text;
_file = file;
ShaderExpansion::
ShaderExpansion() {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::Destructor
// Function: ShaderExpansion::Destructor
// Access: Public
// Description: Delete the compiled code, if it exists.
////////////////////////////////////////////////////////////////////
Shader::
~Shader() {
ShaderExpansion::
~ShaderExpansion() {
release_all();
_expansion_cache.erase(ExpansionKey(_name,_text));
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_init
// Function: ShaderExpansion::make
// Access: Public, Static
// Description: Create a shader expansion (or reuse one from cache)
////////////////////////////////////////////////////////////////////
PT(ShaderExpansion) ShaderExpansion::
make(const string &name, const string &text) {
ExpansionKey key(name, text);
ExpansionCache::const_iterator i = _expansion_cache.find(key);
if (i != _expansion_cache.end()) {
return i->second;
}
ShaderExpansion *result = new ShaderExpansion();
result->_name = name;
result->_text = text;
_expansion_cache.insert(ExpansionCache::value_type(key,result));
return result;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderExpansion::parse_init
// Access: Public
// Description: Set a 'parse pointer' to the beginning of the shader.
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
parse_init() {
_parse = 0;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_line
// Function: ShaderExpansion::parse_line
// Access: Public
// Description: Parse a line of text. If 'lt' is true, trim blanks
// from the left end of the line. If 'rt' is true, trim
// blanks from the right end (the newline is always
// trimmed).
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
parse_line(string &result, bool lt, bool rt) {
int len = _text.size();
int head = _parse;
int tail = head;
while ((tail < len) && (_text[tail] != '\n')) tail++;
while ((tail < len) && (_text[tail] != '\n')) {
tail++;
}
if (tail < len) {
_parse = tail+1;
} else {
@ -79,19 +100,19 @@ parse_line(string &result, bool lt, bool rt) {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_upto
// Function: ShaderExpansion::parse_upto
// Access: Public
// Description: Parse lines until you read a line that matches the
// specified pattern. Returns all the preceding lines,
// and if the include flag is set, returns the final
// line as well.
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
parse_upto(string &result, string pattern, bool include) {
GlobPattern endpat(pattern);
int start = _parse;
int last = _parse;
while (_parse < (int)_text.size()) {
while (_parse < (int)(_text.size())) {
string t;
parse_line(t, true, true);
if (endpat.matches(t)) break;
@ -105,57 +126,43 @@ parse_upto(string &result, string pattern, bool include) {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_rest
// Function: ShaderExpansion::parse_rest
// Access: Public
// Description: Returns the rest of the text from the current
// parse location.
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
parse_rest(string &result) {
result = _text.substr(_parse, _text.size() - _parse);
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_lineno
// Function: ShaderExpansion::parse_lineno
// Access: Public
// Description: Returns the line number of the current parse pointer.
////////////////////////////////////////////////////////////////////
int Shader::
int ShaderExpansion::
parse_lineno() {
int result = 1;
for (int i=0; i<_parse; i++)
for (int i=0; i<_parse; i++) {
if (_text[i] == '\n') result += 1;
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::parse_eof
// Function: ShaderExpansion::parse_eof
// Access: Public
// Description: Returns true if the parse pointer is at the end of
// the shader.
////////////////////////////////////////////////////////////////////
bool Shader::
bool ShaderExpansion::
parse_eof() {
return (int)_text.size() == _parse;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::arg_index
// Access: Public
// Description: Allocates an integer index to the given
// shader parameter name.
////////////////////////////////////////////////////////////////////
int Shader::
arg_index(const string &id) {
for (int i=0; i<(int)(_args.size()); i++)
if (_args[i] == id)
return i;
_args.push_back(id);
return _args.size() - 1;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::prepare
// Function: ShaderExpansion::prepare
// Access: Published
// Description: Indicates that the shader should be enqueued to be
// prepared in the indicated prepared_objects at the
@ -166,19 +173,19 @@ arg_index(const string &id) {
// Use this function instead of prepare_now() to preload
// textures from a user interface standpoint.
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
prepare(PreparedGraphicsObjects *prepared_objects) {
prepared_objects->enqueue_shader(this);
}
////////////////////////////////////////////////////////////////////
// Function: Shader::release
// Function: ShaderExpansion::release
// Access: Published
// Description: Frees the texture context only on the indicated object,
// if it exists there. Returns true if it was released,
// false if it had not been prepared.
////////////////////////////////////////////////////////////////////
bool Shader::
bool ShaderExpansion::
release(PreparedGraphicsObjects *prepared_objects) {
Contexts::iterator ci;
ci = _contexts.find(prepared_objects);
@ -197,7 +204,7 @@ release(PreparedGraphicsObjects *prepared_objects) {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::prepare_now
// Function: ShaderExpansion::prepare_now
// Access: Public
// Description: Creates a context for the texture on the particular
// GSG, if it does not already exist. Returns the new
@ -212,7 +219,7 @@ release(PreparedGraphicsObjects *prepared_objects) {
// explicitly prepared by the user before it may be
// rendered.
////////////////////////////////////////////////////////////////////
ShaderContext *Shader::
ShaderContext *ShaderExpansion::
prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg) {
Contexts::const_iterator ci;
@ -228,15 +235,15 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
}
////////////////////////////////////////////////////////////////////
// Function: Shader::clear_prepared
// Function: ShaderExpansion::clear_prepared
// Access: Private
// Description: Removes the indicated PreparedGraphicsObjects table
// from the Shader's table, without actually releasing
// from the ShaderExpansion's table, without actually releasing
// the texture. This is intended to be called only from
// PreparedGraphicsObjects::release_texture(); it should
// never be called by user code.
////////////////////////////////////////////////////////////////////
void Shader::
void ShaderExpansion::
clear_prepared(PreparedGraphicsObjects *prepared_objects) {
Contexts::iterator ci;
ci = _contexts.find(prepared_objects);
@ -250,13 +257,13 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::release_all
// Function: ShaderExpansion::release_all
// Access: Published
// Description: Frees the context allocated on all objects for which
// the texture has been declared. Returns the number of
// contexts which have been freed.
////////////////////////////////////////////////////////////////////
int Shader::
int ShaderExpansion::
release_all() {
// We have to traverse a copy of the _contexts list, because the
// PreparedGraphicsObjects object will call clear_prepared() in response
@ -281,13 +288,3 @@ release_all() {
return num_freed;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::register_with_read_factory
// Access: Public, Static
// Description: Factory method to generate a Shader object
////////////////////////////////////////////////////////////////////
void Shader::
register_with_read_factory() {
// IMPLEMENT ME
}

View File

@ -1,4 +1,4 @@
// Filename: shader.h
// Filename: shaderExpansion.h
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
@ -16,19 +16,8 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
// Current Loose Ends:
// - BAM reading/writing not implemented on most classes.
// - ShaderPool not implemented.
// - compilation of shaders for OpenGL not implemented.
// - compilation of shaders for DirectX8 not implemented.
// - compilation of shaders for DirectX9 not implemented.
//
////////////////////////////////////////////////////////////////////
#ifndef SHADER_H
#define SHADER_H
#ifndef SHADEREXPANSION_H
#define SHADEREXPANSION_H
#include "pandabase.h"
#include "typedWritableReferenceCount.h"
@ -37,31 +26,27 @@
#include "internalName.h"
////////////////////////////////////////////////////////////////////
// Class : Shader
// Summary: The Shader object contains the string which
// is the shader's text, a filename that indicates
// where the shader came from (optional), and an
// argument-name to argument-index allocator. The
// allocator is there so that all the Shader and
// ShaderContext objects associated with this Shader
// can refer to arguments by index instead of by name,
// which could make the bind process significantly
// faster.
// Class : ShaderExpansion
// Summary: A shader can contain context-sensitive macros.
// A ShaderExpansion is the output you get when you
// run the macro preprocessor on a shader.
// The ShaderExpansion contains the shader's
// macroexpanded text, and a map of ShaderContext
// objects.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Shader: public TypedWritableReferenceCount {
class EXPCL_PANDA ShaderExpansion: public TypedReferenceCount {
PUBLISHED:
Shader(const string &text, const string &file);
~Shader();
INLINE const string &get_text();
INLINE const Filename &get_file();
static PT(ShaderExpansion) make(const string &name, const string &body);
INLINE const string &get_name() const;
INLINE const string &get_text() const;
void prepare(PreparedGraphicsObjects *prepared_objects);
bool release(PreparedGraphicsObjects *prepared_objects);
int release_all();
PUBLISHED:
// These routines help split the shader into sections,
// for those shader implementations that need to do so.
@ -73,28 +58,27 @@ PUBLISHED:
bool parse_eof();
public:
~ShaderExpansion();
INLINE int arg_count();
int arg_index(const string &id);
string _name;
string _text;
Filename _file;
int _parse;
vector<string> _args;
typedef pmap<PreparedGraphicsObjects *, ShaderContext *> Contexts;
Contexts _contexts;
static void register_with_read_factory();
typedef pair < string, string > ExpansionKey;
typedef pmap < ExpansionKey, ShaderExpansion * > ExpansionCache;
static ExpansionCache _expansion_cache;
friend class ShaderContext;
friend class PreparedGraphicsObjects;
typedef pmap <PreparedGraphicsObjects *, ShaderContext *> Contexts;
Contexts _contexts;
ShaderContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg);
private:
void parse();
ShaderExpansion();
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
public:
@ -102,9 +86,9 @@ public:
return _type_handle;
}
static void init_type() {
TypedWritableReferenceCount::init_type();
register_type(_type_handle, "Shader",
TypedWritableReferenceCount::get_class_type());
TypedReferenceCount::init_type();
register_type(_type_handle, "ShaderExpansion",
TypedReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
@ -115,6 +99,6 @@ private:
static TypeHandle _type_handle;
};
#include "shader.I"
#include "shaderExpansion.I"
#endif

View File

@ -61,9 +61,8 @@ class PreparedGraphicsObjects;
class GraphicsOutput;
class Texture;
class TextureContext;
class Shader;
class ShaderContext;
class ShaderMode;
class ShaderExpansion;
class RenderState;
class TransformState;
class Material;
@ -90,7 +89,6 @@ class ShadeModelAttrib;
class TransparencyAttrib;
class FogAttrib;
class DepthOffsetAttrib;
class ShaderAttrib;
class PointLight;
class DirectionalLight;
@ -139,7 +137,7 @@ public:
virtual GeomContext *prepare_geom(Geom *geom)=0;
virtual void release_geom(GeomContext *gc)=0;
virtual ShaderContext *prepare_shader(Shader *shader)=0;
virtual ShaderContext *prepare_shader(ShaderExpansion *shader)=0;
virtual void release_shader(ShaderContext *sc)=0;
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data)=0;

View File

@ -97,9 +97,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: AlphaTestAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void AlphaTestAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -209,9 +209,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: AntialiasAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void AntialiasAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -885,9 +885,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ClipPlaneAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ClipPlaneAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -135,9 +135,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ColorAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ColorAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -142,9 +142,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ColorBlendAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ColorBlendAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -260,9 +260,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ColorScaleAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -97,9 +97,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ColorWriteAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ColorWriteAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -80,8 +80,9 @@
#include "selectiveChildNode.h"
#include "sequenceNode.h"
#include "shadeModelAttrib.h"
#include "shaderMode.h"
#include "shaderInput.h"
#include "shaderAttrib.h"
#include "shader.h"
#include "showBoundsEffect.h"
#include "spotlight.h"
#include "stateMunger.h"
@ -321,8 +322,9 @@ init_libpgraph() {
SelectiveChildNode::init_type();
SequenceNode::init_type();
ShadeModelAttrib::init_type();
ShaderMode::init_type();
ShaderInput::init_type();
ShaderAttrib::init_type();
Shader::init_type();
ShowBoundsEffect::init_type();
Spotlight::init_type();
StateMunger::init_type();
@ -379,8 +381,9 @@ init_libpgraph() {
RenderState::register_with_read_factory();
SequenceNode::register_with_read_factory();
ShadeModelAttrib::register_with_read_factory();
ShaderMode::register_with_read_factory();
ShaderInput::register_with_read_factory();
ShaderAttrib::register_with_read_factory();
Shader::register_with_read_factory();
ShowBoundsEffect::register_with_read_factory();
Spotlight::register_with_read_factory();
SwitchNode::register_with_read_factory();

View File

@ -103,9 +103,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: CullBinAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void CullBinAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -246,9 +246,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: CullFaceAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void CullFaceAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -137,9 +137,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: DepthOffsetAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void DepthOffsetAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -90,9 +90,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: DepthTestAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void DepthTestAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -97,9 +97,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: DepthWriteAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void DepthWriteAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -114,9 +114,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: FogAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void FogAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -864,9 +864,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: LightAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void LightAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -114,9 +114,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: MaterialAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void MaterialAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -37,6 +37,7 @@
#include "alphaTestAttrib.h"
#include "depthTestAttrib.h"
#include "depthWriteAttrib.h"
#include "shaderAttrib.h"
#include "billboardEffect.h"
#include "compassEffect.h"
#include "showBoundsEffect.h"
@ -56,6 +57,8 @@
#include "textureCollection.h"
#include "textureStageCollection.h"
#include "globPattern.h"
#include "shader.h"
#include "shaderInput.h"
#include "config_gobj.h"
#include "bamFile.h"
#include "preparedGraphicsObjects.h"
@ -3058,6 +3061,229 @@ get_texture(TextureStage *stage) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader(Shader *sha, int priority) {
nassertv_always(!is_empty());
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
priority = max(priority,
node()->get_state()->get_override(ShaderAttrib::get_class_type()));
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
node()->set_attrib(sa->set_shader(sha, priority));
} else {
// Create a new ShaderAttrib for this node.
CPT(ShaderAttrib) sa = DCAST(ShaderAttrib, ShaderAttrib::make());
node()->set_attrib(sa->set_shader(sha, priority));
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_off
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_off(int priority) {
set_shader(NULL, priority);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::clear_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
clear_shader() {
nassertv_always(!is_empty());
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
node()->set_attrib(sa->clear_shader());
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::get_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
const Shader *NodePath::
get_shader() const {
nassertr_always(!is_empty(), NULL);
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
return sa->get_shader();
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(const ShaderInput *inp) {
nassertv_always(!is_empty());
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
node()->set_attrib(sa->add_input(inp));
} else {
// Create a new ShaderAttrib for this node.
CPT(ShaderAttrib) sa = DCAST(ShaderAttrib, ShaderAttrib::make());
node()->set_attrib(sa->add_input(inp));
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::get_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
const ShaderInput *NodePath::
get_shader_input(InternalName *id) const {
nassertr_always(!is_empty(), NULL);
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
return sa->get_input(id);
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::clear_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
clear_shader_input(InternalName *id) {
nassertv_always(!is_empty());
const RenderAttrib *attrib =
node()->get_attrib(ShaderAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const ShaderAttrib *sa = DCAST(ShaderAttrib, attrib);
node()->set_attrib(sa->clear_input(id));
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(InternalName *id, Texture *tex, int priority) {
set_shader_input(new ShaderInput(id,tex,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(InternalName *id, const NodePath &np, int priority) {
set_shader_input(new ShaderInput(id,np,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(InternalName *id, const LVector4f &v, int priority) {
set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(InternalName *id, double n1, double n2, double n3, double n4, int priority) {
set_shader_input(new ShaderInput(id,LVector4f(n1,n2,n3,n4),priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(const string &id, Texture *tex, int priority) {
set_shader_input(new ShaderInput(InternalName::make(id),tex,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(const string &id, const NodePath &np, int priority) {
set_shader_input(new ShaderInput(InternalName::make(id),np,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(const string &id, const LVector4f &v, int priority) {
set_shader_input(new ShaderInput(InternalName::make(id),v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
set_shader_input(const string &id, double n1, double n2, double n3, double n4, int priority) {
set_shader_input(new ShaderInput(InternalName::make(id),LVector4f(n1,n2,n3,n4),priority));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::get_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
const ShaderInput *NodePath::
get_shader_input(const string &id) const {
return get_shader_input(InternalName::make(id));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::clear_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
clear_shader_input(const string &id) {
clear_shader_input(InternalName::make(id));
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_tex_transform
// Access: Published

View File

@ -27,7 +27,6 @@
#include "renderModeAttrib.h"
#include "transparencyAttrib.h"
#include "nodePathComponent.h"
#include "pointerTo.h"
#include "referenceCount.h"
#include "notify.h"
@ -46,6 +45,8 @@ class Material;
class Fog;
class GlobPattern;
class PreparedGraphicsObjects;
class Shader;
class ShaderInput;
//
// A NodePath is the fundamental unit of high-level interaction with
@ -553,6 +554,24 @@ PUBLISHED:
Texture *get_texture() const;
Texture *get_texture(TextureStage *stage) const;
void set_shader(Shader *sha, int priority = 0);
void set_shader_off(int priority = 0);
void clear_shader();
const Shader *get_shader() const;
void set_shader_input(const ShaderInput *inp);
const ShaderInput *get_shader_input(InternalName *id) const;
void clear_shader_input(InternalName *id);
void set_shader_input(InternalName *id, Texture *tex, int priority=0);
void set_shader_input(InternalName *id, const NodePath &np, int priority=0);
void set_shader_input(InternalName *id, const LVector4f &v, int priority=0);
void set_shader_input(InternalName *id, double n1=0, double n2=0, double n3=0, double n4=1, int priority=0);
void set_shader_input(const string &id, Texture *tex, int priority=0);
void set_shader_input(const string &id, const NodePath &np, int priority=0);
void set_shader_input(const string &id, const LVector4f &v, int priority=0);
void set_shader_input(const string &id, double n1=0, double n2=0, double n3=0, double n4=1, int priority=0);
const ShaderInput *get_shader_input(const string &id) const;
void clear_shader_input(const string &id);
void set_tex_transform(TextureStage *stage, const TransformState *transform);
void clear_tex_transform();
void clear_tex_transform(TextureStage *stage);

View File

@ -9,7 +9,8 @@
#include "selectiveChildNode.cxx"
#include "sequenceNode.cxx"
#include "shadeModelAttrib.cxx"
#include "shaderMode.cxx"
#include "shader.cxx"
#include "shaderInput.cxx"
#include "shaderAttrib.cxx"
#include "showBoundsEffect.cxx"
#include "spotlight.cxx"

View File

@ -167,9 +167,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: RenderModeAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void RenderModeAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -560,6 +560,26 @@ compare_to(const Attribute &other) const {
return _override - other._override;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::get_shader_expansion
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderExpansion *RenderState::
get_shader_expansion() const {
return _shader_expansion;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::set_shader_expansion
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void RenderState::
set_shader_expansion(ShaderExpansion *exp) {
_shader_expansion = exp;
}
////////////////////////////////////////////////////////////////////
// Function: RenderState::CompositionCycleDescEntry::Constructor
// Access: Public

View File

@ -39,6 +39,7 @@
RenderState::States *RenderState::_states = NULL;
CPT(RenderState) RenderState::_empty_state;
UpdateSeq RenderState::_last_cycle_detect;
PStatCollector RenderState::_cache_update_pcollector("*:State Cache:Update");
PStatCollector RenderState::_state_compose_pcollector("*:State Cache:Compose State");
PStatCollector RenderState::_state_invert_pcollector("*:State Cache:Invert State");
@ -287,6 +288,7 @@ make(const AttribSlots *slots, int override) {
}
}
state->_attributes.reserve(state->_attributes.size());
state->_attributes.sort();
return return_new(state);
}

View File

@ -31,6 +31,7 @@
#include "texMatrixAttrib.h"
#include "geomMunger.h"
#include "weakPointerTo.h"
#include "shaderExpansion.h"
class GraphicsStateGuardianBase;
class FogAttrib;
@ -148,6 +149,8 @@ public:
void store_into_slots(AttribSlots *slots) const;
static void bin_removed(int bin_index);
INLINE ShaderExpansion *get_shader_expansion() const;
INLINE void set_shader_expansion(ShaderExpansion *exp);
private:
class CompositionCycleDescEntry {
@ -271,6 +274,11 @@ private:
int _bin_index;
int _draw_order;
// If this renderstate contains a Shader, then the macroexpansion
// of the shader needs to be cached (to avoid having to regenerate
// it each time this RenderState is applied).
PT(ShaderExpansion) _shader_expansion;
// We also cache the pointer to some critical attribs stored in the
// state, if they exist.
const FogAttrib *_fog;

View File

@ -119,9 +119,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: RescaleNormalAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void RescaleNormalAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -126,9 +126,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ShadeModelAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ShadeModelAttrib::
store_into_slot(AttribSlots *slots) const {

69
panda/src/pgraph/shader.I Normal file
View File

@ -0,0 +1,69 @@
// Filename: shader.I
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: Shader::get_file
// Access: Published
// Description: Returns null string if shader was not loaded from
// a source file.
////////////////////////////////////////////////////////////////////
INLINE const Filename &Shader::
get_file() const {
return _file;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::get_body
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const string &Shader::
get_body() const {
return _body;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::get_name
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const string &Shader::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::get_loaded
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool Shader::
get_loaded() const {
return _loaded;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::get_preprocessor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int Shader::
get_preprocessor() const {
return _preprocessor;
}

163
panda/src/pgraph/shader.cxx Normal file
View File

@ -0,0 +1,163 @@
// Filename: shader.cxx
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "shader.h"
#include "virtualFileSystem.h"
TypeHandle Shader::_type_handle;
Shader::LoadTable Shader::_load_table;
Shader::MakeTable Shader::_make_table;
////////////////////////////////////////////////////////////////////
// Function: Shader::Constructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
Shader::
Shader() {
}
////////////////////////////////////////////////////////////////////
// Function: Shader::Destructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
Shader::
~Shader() {
if (_loaded) {
LoadTableKey key(_file, _preprocessor);
_load_table.erase(key);
} else {
MakeTableKey key(_body, _preprocessor);
_make_table.erase(key);
}
}
////////////////////////////////////////////////////////////////////
// Function: Shader::load
// Access: Published, Static
// Description:
////////////////////////////////////////////////////////////////////
CPT(Shader) Shader::
load(const string &file, int preprocessor) {
return load(Filename(file), preprocessor);
}
////////////////////////////////////////////////////////////////////
// Function: Shader::load
// Access: Published, Static
// Description:
////////////////////////////////////////////////////////////////////
CPT(Shader) Shader::
load(const Filename &file, int preprocessor) {
LoadTableKey key(file, preprocessor);
LoadTable::const_iterator i = _load_table.find(key);
if (i != _load_table.end()) {
return i->second;
}
Shader *result = new Shader;
result->_name = file;
result->_file = file;
result->_loaded = true;
result->_preprocessor = preprocessor;
result->_fixed_expansion = 0;
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->read_file(file, result->_body)) {
cerr << "Could not read shader file: " << file << "\n";
result->_body = "";
}
_load_table[key] = result;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::make
// Access: Published, Static
// Description:
////////////////////////////////////////////////////////////////////
CPT(Shader) Shader::
make(const string &body, int preprocessor) {
MakeTableKey key(body, preprocessor);
MakeTable::const_iterator i = _make_table.find(key);
if (i != _make_table.end()) {
return i->second;
}
Shader *result = new Shader;
result->_name = "generated shader";
result->_file = "";
result->_loaded = false;
result->_preprocessor = preprocessor;
result->_fixed_expansion = 0;
result->_body = body;
_make_table[key] = result;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::macroexpand
// Access: Public
// Description: The eventual plan is that shaders will be run through
// a macro preprocessor in order to generate the actual
// shader text in Cg, GLSL, HLSL, or whatever. The
// macro preprocessor will be able to query the RenderState
// and generate different shader code for different states.
//
// The macroexpansion of the shader is stored in an object
// of class ShaderExpansion. This is somewhat expensive
// to generate, so the ShaderExpansion is cached inside the
// the RenderState itself. The ShaderExpansion contains
// a map of ShaderContexts, each containing a compiled
// copy of the shader's macroexpansion.
//
// Any given shader might not contain any ifdefs that
// depend on the RenderState. If macroexpand determines
// that a given shader is not state-sensitive, it can cache
// the macroexpansion in the field "_fixed_expansion."
//
// The preprocessing is usually done by a built-in macro
// preprocessing function. However, the user can write
// his own preprocessor if he wishes to do so. A user-
// supplied preprocessor can generate arbitrary code ---
// in fact, it doesn't need to look at the input string
// if it does not wish to do so.
//
// Currently, macroexpand is just a stub that returns an
// expansion which is exactly equal to the input string.
////////////////////////////////////////////////////////////////////
PT(ShaderExpansion) Shader::
macroexpand(const RenderState *context) const {
if (_fixed_expansion) {
return _fixed_expansion;
}
// I am casting away the 'const' so as to be able
// to write to this field. This field is just a cache.
((Shader*)this)->_fixed_expansion = ShaderExpansion::make(_name,_body);
return _fixed_expansion;
}
////////////////////////////////////////////////////////////////////
// Function: Shader::register_with_read_factory
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void Shader::
register_with_read_factory() {
// IMPLEMENT ME
}

93
panda/src/pgraph/shader.h Normal file
View File

@ -0,0 +1,93 @@
// Filename: shader.h
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef SHADER_H
#define SHADER_H
#include "pandabase.h"
#include "typedWritableReferenceCount.h"
#include "pointerTo.h"
#include "dcast.h"
class ShaderExpansion;
////////////////////////////////////////////////////////////////////
// Class : Shader
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Shader: public TypedWritableReferenceCount {
PUBLISHED:
static CPT(Shader) load(const Filename &file, int preprocessor=0);
static CPT(Shader) load(const string &file, int preprocessor=0);
static CPT(Shader) make(const string &body, int preprocessor=0);
INLINE const string &get_name() const;
INLINE const Filename &get_file() const;
INLINE const string &get_body() const;
INLINE int get_preprocessor() const;
INLINE bool get_loaded() const;
PT(ShaderExpansion) macroexpand(const RenderState *context) const;
public:
Shader();
~Shader();
private:
string _name;
Filename _file;
string _body;
bool _loaded;
int _preprocessor;
PT(ShaderExpansion) _fixed_expansion;
typedef pair < Filename, int > LoadTableKey;
typedef pair < string, int > MakeTableKey;
typedef pmap < LoadTableKey , Shader * > LoadTable;
typedef pmap < MakeTableKey , Shader * > MakeTable;
static LoadTable _load_table;
static MakeTable _make_table;
public:
static void register_with_read_factory();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedWritableReferenceCount::init_type();
register_type(_type_handle, "Shader",
TypedWritableReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "shader.I"
#endif SHADER_H

View File

@ -20,33 +20,74 @@
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::Constructor
// Access: Private
// Description: xyz
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderAttrib::
ShaderAttrib() {
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::is_off
// Function: ShaderAttrib::Copy Constructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderAttrib::
ShaderAttrib(const ShaderAttrib &copy) :
_shader(copy._shader),
_shader_priority(copy._shader_priority),
_has_shader(copy._has_shader),
_inputs(copy._inputs)
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader
// Access: Published
// Description: Returns true if the ShaderAttrib is an 'off'
// ShaderAttrib, indicating that it should disable
// the previous shader profiles
// Description: Returns the shader object associated with the node.
// If get_override returns true, but get_shader
// returns NULL, that means that this attribute should
// disable the shader.
////////////////////////////////////////////////////////////////////
INLINE const Shader *ShaderAttrib::
get_shader() const {
return _shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::has_shader
// Access: Published
// Description: If true, the shader field of this attribute overrides
// the shader field of the parent attribute.
////////////////////////////////////////////////////////////////////
INLINE bool ShaderAttrib::
is_off() const {
return _shader_mode == (ShaderMode *)NULL;
has_shader() const {
return _has_shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_mode
// Function: ShaderAttrib::get_shader_priority
// Access: Published
// Description: If the ShaderAttrib is not an 'off' ShaderAttrib,
// returns the ShaderMode that is associated. Otherwise,
// return NULL.
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderMode *ShaderAttrib::
get_shader_mode() const {
return _shader_mode;
INLINE int ShaderAttrib::
get_shader_priority() const {
return _shader_priority;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_input
// Access: Published
// Description: Returns the ShaderInput of the given name. If
// no such name is found, this function does not return
// NULL --- it returns the "blank" ShaderInput.
////////////////////////////////////////////////////////////////////
INLINE const ShaderInput *ShaderAttrib::
get_input(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
return ShaderInput::get_blank();
} else {
return (*i).second;
}
}

View File

@ -28,28 +28,114 @@
TypeHandle ShaderAttrib::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::make
// Function: ShaderAttrib::make_off
// Access: Published, Static
// Description: Constructs a new ShaderAttrib object suitable for
// process the indicated geometry with shaders
// Description: Constructs a new ShaderAttrib object that disables
// the use of shaders (it does not clear out all shader
// data, however.)
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
make(ShaderMode *shader_mode) {
ShaderAttrib *attrib = new ShaderAttrib;
attrib->_shader_mode = shader_mode;
return return_new(attrib);
make_off() {
static CPT(RenderAttrib) _off_attrib;
if (_off_attrib == 0) {
ShaderAttrib *attrib = new ShaderAttrib;
attrib->_shader = (Shader*)NULL;
attrib->_shader_priority = 0;
attrib->_has_shader = true;
_off_attrib = return_new(attrib);
}
return _off_attrib;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::make_off
// Function: ShaderAttrib::make
// Access: Published, Static
// Description: Constructs a new ShaderAttrib object suitable for
// rendering geometry with no shader interference
// Description: Constructs a new ShaderAttrib object with nothing
// set.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
make_off() {
ShaderAttrib *attrib = new ShaderAttrib;
return return_new(attrib);
make() {
static CPT(RenderAttrib) _null_attrib;
if (_null_attrib == 0) {
ShaderAttrib *attrib = new ShaderAttrib;
attrib->_shader = (Shader*)NULL;
attrib->_shader_priority = 0;
attrib->_has_shader = false;
_null_attrib = return_new(attrib);
}
return _null_attrib;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader(const Shader *s, int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = s;
result->_shader_priority = priority;
result->_has_shader = true;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_off
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_off(int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = priority;
result->_has_shader = true;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader() const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = 0;
result->_has_shader = false;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::add_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
add_input(const ShaderInput *input) const {
ShaderAttrib *result = new ShaderAttrib(*this);
Inputs::iterator i = result->_inputs.find(input->get_name());
if (i == result->_inputs.end()) {
result->_inputs.insert(Inputs::value_type(input->get_name(),input));
} else {
i->second = input;
}
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_input(const InternalName *id) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_inputs.erase(id);
return return_new(result);
}
////////////////////////////////////////////////////////////////////
@ -57,7 +143,7 @@ make_off() {
// Access: Protected, Virtual
// Description: Intended to be overridden by derived ShaderAttrib
// types to specify what the default property for a
// TexGenAttrib of this type should be.
// ShaderAttrib of this type should be.
//
// This should return a newly-allocated ShaderAttrib of
// the same type that corresponds to whatever the
@ -71,9 +157,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void ShaderAttrib::
store_into_slot(AttribSlots *slots) const {
@ -97,18 +182,75 @@ store_into_slot(AttribSlots *slots) const {
////////////////////////////////////////////////////////////////////
int ShaderAttrib::
compare_to_impl(const RenderAttrib *other) const {
const ShaderAttrib *cgsa;
DCAST_INTO_R(cgsa, other, 0);
const ShaderAttrib *that;
DCAST_INTO_R(that, other, 0);
// Comparing pointers by subtraction is problematic. Instead of
// doing this, we'll just depend on the built-in != and < operators
// for comparing pointers.
if (_shader_mode != cgsa->_shader_mode) {
return _shader_mode < cgsa->_shader_mode ? -1 : 1;
if (this->_shader != that->_shader) {
return (this->_shader < that->_shader) ? -1 : 1;
}
if (this->_shader_priority != that->_shader_priority) {
return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
}
if (this->_has_shader != that->_has_shader) {
return (this->_has_shader < that->_has_shader) ? -1 : 1;
}
Inputs::const_iterator i1 = this->_inputs.begin();
Inputs::const_iterator i2 = that->_inputs.begin();
while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
if (i1->second != i2->second) {
return (i1->second < i2->second) ? -1 : 1;
}
++i1;
++i2;
}
if (i1 != this->_inputs.end()) {
return 1;
}
if (i1 != that->_inputs.end()) {
return -1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::compose_impl
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
compose_impl(const RenderAttrib *other) const {
ShaderAttrib *attr = new ShaderAttrib(*this);
const ShaderAttrib *over;
DCAST_INTO_R(over, other, 0);
// Update the shader portion.
if (over->_has_shader) {
if ((attr->_has_shader == false) ||
(over->_shader_priority >= attr->_shader_priority)) {
attr->_shader = over->_shader;
attr->_shader_priority = over->_shader_priority;
attr->_has_shader = over->_has_shader;
}
}
// Update the shader-data portion.
Inputs::const_iterator iover;
for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
const InternalName *id = (*iover).first;
const ShaderInput *dover = (*iover).second;
Inputs::iterator iattr = attr->_inputs.find(id);
if (iattr == attr->_inputs.end()) {
attr->_inputs.insert(Inputs::value_type(id,dover));
} else {
const ShaderInput *dattr = (*iattr).second;
if (dattr->get_priority() <= dover->get_priority()) {
iattr->second = iover->second;
}
}
}
return return_new(attr);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::register_with_read_factory
// Access: Public, Static

View File

@ -1,5 +1,5 @@
// Filename: shaderAttrib.h
// Created by: sshodhan (10Jul04)
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
@ -20,45 +20,54 @@
#define SHADERATTRIB_H
#include "pandabase.h"
#include "luse.h"
#include "pmap.h"
#include "shader.h"
#include "renderAttrib.h"
#include "typedObject.h"
#include "typedReferenceCount.h"
#include "pointerTo.h"
#include "factoryParam.h"
#include "dcast.h"
#include "shaderMode.h"
#include "shaderInput.h"
#include "shader.h"
////////////////////////////////////////////////////////////////////
// Class : ShaderAttrib
// Description : fill me in
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ShaderAttrib: public RenderAttrib {
private:
INLINE ShaderAttrib();
INLINE ShaderAttrib(const ShaderAttrib &copy);
PUBLISHED:
static CPT(RenderAttrib) make(ShaderMode *sm);
static CPT(RenderAttrib) make();
static CPT(RenderAttrib) make_off();
INLINE bool is_off() const;
INLINE ShaderMode *get_shader_mode() const;
INLINE bool has_shader() const;
INLINE int get_shader_priority() const;
INLINE const Shader *get_shader() const;
INLINE const ShaderInput *get_input(const InternalName *id) const;
CPT(RenderAttrib) clear_shader() const;
CPT(RenderAttrib) set_shader(const Shader *s, int priority=0) const;
CPT(RenderAttrib) set_shader_off(int priority=0) const;
CPT(RenderAttrib) add_input(const ShaderInput *input) const;
CPT(RenderAttrib) clear_input(const InternalName *id) const;
static void register_with_read_factory();
public:
virtual void store_into_slot(AttribSlots *slots) const;
protected:
virtual RenderAttrib *make_default_impl() const;
virtual int compare_to_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
private:
PT(ShaderMode) _shader_mode;
CPT(Shader) _shader;
int _shader_priority;
bool _has_shader;
typedef pmap < CPT(InternalName), CPT(ShaderInput) > Inputs;
Inputs _inputs;
public:
static TypeHandle get_class_type() {

View File

@ -0,0 +1,152 @@
// Filename: shaderInput.I
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
~ShaderInput()
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(InternalName *name, int priority) :
_type(M_invalid),
_name(name),
_priority(priority),
_stored_texture(NULL),
_stored_nodepath(NodePath()),
_stored_vector(LVector4f(0,0,0,1))
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(InternalName *name, Texture *tex, int priority) :
_type(M_texture),
_name(name),
_priority(priority),
_stored_texture(tex),
_stored_nodepath(NodePath()),
_stored_vector(LVector4f(0,0,0,1))
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(InternalName *name, const NodePath &np, int priority) :
_type(M_nodepath),
_name(name),
_priority(priority),
_stored_texture(NULL),
_stored_nodepath(np),
_stored_vector(LVector4f(0,0,0,1))
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(InternalName *name, const LVector4f &vec, int priority) :
_type(M_vector),
_name(name),
_priority(priority),
_stored_texture(NULL),
_stored_nodepath(NodePath()),
_stored_vector(vec)
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_name
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE InternalName *ShaderInput::
get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_value_type
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int ShaderInput::
get_value_type() const {
return _type;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_priority
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int ShaderInput::
get_priority() const {
return _priority;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_texture
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE Texture *ShaderInput::
get_texture() const {
return _stored_texture;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_nodepath
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const NodePath &ShaderInput::
get_nodepath() const {
return _stored_nodepath;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_vector
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LVector4f &ShaderInput::
get_vector() const {
return _stored_vector;
}

View File

@ -1,5 +1,5 @@
// Filename: shaderMode.I
// Heavily Modified: jyelon (01Sep05)
// Filename: shaderInput.cxx
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
@ -16,32 +16,33 @@
//
////////////////////////////////////////////////////////////////////
#include "shaderInput.h"
TypeHandle ShaderInput::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ShaderModeArg::Constructor
// Access: Public
// Description: initialize a shader arg storage structure.
// Function: ShaderInput::get_blank
// Access: Public, Static
// Description: Returns a static ShaderInput object with
// name NULL, priority zero, type INVALID, and
// all value-fields cleared.
////////////////////////////////////////////////////////////////////
INLINE ShaderModeArg::
ShaderModeArg() {
_type = SAT_INVALID;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderModeArg::Destructor
// Access: Public
// Description: delete a shader arg storage structure.
////////////////////////////////////////////////////////////////////
INLINE ShaderModeArg::
~ShaderModeArg() {
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::get_shader
// Access: Public
// Description: Return the Shader associated with this shader mode.
////////////////////////////////////////////////////////////////////
INLINE Shader *ShaderMode::
get_shader() {
return _shader;
const ShaderInput *ShaderInput::
get_blank() {
static CPT(ShaderInput) blank;
if (blank == 0) {
blank = new ShaderInput(NULL, 0);
}
return blank;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::register_with_read_factory
// Access: Public, Static
// Description:
////////////////////////////////////////////////////////////////////
void ShaderInput::
register_with_read_factory() {
// IMPLEMENT ME
}

View File

@ -0,0 +1,93 @@
// Filename: shaderInput.h
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef SHADERINPUT_H
#define SHADERINPUT_H
#include "pandabase.h"
#include "typedWritableReferenceCount.h"
#include "pointerTo.h"
#include "nodePath.h"
////////////////////////////////////////////////////////////////////
// Class : ShaderInput
// Description : This is a small container class that can hold any
// one of the value types that can be passed as input
// to a shader.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ShaderInput: public TypedWritableReferenceCount {
public:
INLINE ~ShaderInput();
PUBLISHED:
static const ShaderInput *get_blank();
INLINE ShaderInput(InternalName *id, int priority=0);
INLINE ShaderInput(InternalName *id, const NodePath &np, int priority=0);
INLINE ShaderInput(InternalName *id, const LVector4f &v, int priority=0);
INLINE ShaderInput(InternalName *id, Texture *tex, int priority=0);
enum ShaderInputType {
M_invalid = 0,
M_texture,
M_nodepath,
M_vector
};
INLINE InternalName *get_name() const;
INLINE int get_value_type() const;
INLINE int get_priority() const;
INLINE Texture *get_texture() const;
INLINE const NodePath &get_nodepath() const;
INLINE const LVector4f &get_vector() const;
public:
static void register_with_read_factory();
private:
PT(InternalName) _name;
int _type;
int _priority;
PT(Texture) _stored_texture;
NodePath _stored_nodepath;
LVector4f _stored_vector;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ReferenceCount::init_type();
register_type(_type_handle, "ShaderInput",
ReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "shaderInput.I"
#endif // SHADERINPUT_H

View File

@ -1,237 +0,0 @@
// Filename: shaderMode.cxx
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "shader.h"
#include "shaderMode.h"
#include "virtualFileSystem.h"
TypeHandle ShaderMode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::load
// Access: Published
// Description: Obtain the shader associated with the specified
// file and construct a ShaderMode for that shader.
////////////////////////////////////////////////////////////////////
PT(ShaderMode) ShaderMode::
load(const Filename &file)
{
string text;
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->read_file(file, text)) {
cerr << "Could not read " << file << "\n";
return new ShaderMode(new Shader("", file));
}
return new ShaderMode(new Shader(text, file));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::load
// Access: Published
// Description: Obtain the shader associated with the specified
// file and construct a ShaderMode for that shader.
////////////////////////////////////////////////////////////////////
PT(ShaderMode) ShaderMode::
load(const string &file)
{
Filename fn(file);
return load(fn);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::make
// Access: Published
// Description: Obtain the shader associated with the specified
// text and construct a ShaderMode for that shader.
////////////////////////////////////////////////////////////////////
PT(ShaderMode) ShaderMode::
make(const string &text)
{
return new ShaderMode(new Shader(text, ""));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::Constructor
// Access: Published
// Description: Use to construct a new shader instance.
////////////////////////////////////////////////////////////////////
ShaderMode::
ShaderMode(Shader *shader) {
_shader = shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::Destructor
// Access: Public
// Description: delete a shader
////////////////////////////////////////////////////////////////////
ShaderMode::
~ShaderMode() {
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::mod_param
// Access: Private
// Description: To set a parameter, you must first access it and
// then clear it. This function accesses then clears
// the storage for a parameter, prior to setting it.
////////////////////////////////////////////////////////////////////
INLINE ShaderModeArg *ShaderMode::
mod_param(const string &pname, int t) {
int index = _shader->arg_index(pname);
if (index >= (int)(_args.size()))
_args.resize(index+1);
ShaderModeArg *arg = &(_args[index]);
arg->_type = t;
arg->_nvalue = NodePath();
arg->_tvalue = (Texture*)NULL;
arg->_fvalue = LVector4d(0,0,0,0);
return arg;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param texture
// Access: Public
// Description: Store texture in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, Texture *x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_TEXTURE);
arg->_tvalue = x;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param nodepath
// Access: Public
// Description: Store nodepath in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, const NodePath &x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_NODEPATH);
arg->_nvalue = x;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 1f
// Access: Public
// Description: Store 1f in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, float x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x,0,0,0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 2f
// Access: Public
// Description: Store 2f in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector2f x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x[0],x[1],0,0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 3f
// Access: Public
// Description: Store 3f in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector3f x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x[0],x[1],x[2],0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 4f
// Access: Public
// Description: Store 4f in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector4f x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x[0],x[1],x[2],x[3]);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 1d
// Access: Public
// Description: Store 1d in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, double x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x,0,0,0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 2d
// Access: Public
// Description: Store 2d in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector2d x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x[0],x[1],0,0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 3d
// Access: Public
// Description: Store 3d in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector3d x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = LVector4d(x[0],x[1],x[2],0);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::set_param 4d
// Access: Public
// Description: Store 4d in the map to associate with
// param name
////////////////////////////////////////////////////////////////////
void ShaderMode::
set_param(const string &pname, LVector4d x) {
ShaderModeArg *arg = mod_param(pname, ShaderModeArg::SAT_FLOAT);
arg->_fvalue = x;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderMode::register_with_read_factory
// Access: Public, Static
// Description: Factory method to generate a ShaderMode object
////////////////////////////////////////////////////////////////////
void ShaderMode::
register_with_read_factory() {
// IMPLEMENT ME
}

View File

@ -1,117 +0,0 @@
// Filename: shaderMode.h
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef SHADERMODE_H
#define SHADERMODE_H
#include "pandabase.h"
#include "nodePath.h"
////////////////////////////////////////////////////////////////////
// Class : ShaderModeArg
// Description : The ShaderModeArg is a small structure designed to hold
// any of the various kinds of values that can be
// passed to a shader. Basically, it is a temporary
// storage repository for shader input parameters.
////////////////////////////////////////////////////////////////////
class ShaderModeArg
{
public:
enum ShaderModeArgType
{
SAT_INVALID,
SAT_FLOAT,
SAT_TEXTURE,
SAT_NODEPATH,
};
INLINE ShaderModeArg();
INLINE ~ShaderModeArg();
int _type;
NodePath _nvalue;
PT(Texture) _tvalue;
LVector4d _fvalue;
};
////////////////////////////////////////////////////////////////////
// Class : ShaderMode
// Summary: The ShaderMode object contains a Shader and a
// list of input data to pass into the shader when
// it is executing.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ShaderMode: public TypedWritableReferenceCount {
public:
PT(Shader) _shader;
vector<ShaderModeArg> _args;
PUBLISHED:
ShaderMode(Shader *body);
static PT(ShaderMode) load(const string &file);
static PT(ShaderMode) load(const Filename &file);
static PT(ShaderMode) make(const string &text);
~ShaderMode();
INLINE Shader *get_shader();
// Overloaded set_param to be used based on your param type
void set_param(const string &pname, Texture *t);
void set_param(const string &pname, const NodePath &np);
void set_param(const string &pname, float p1f);
void set_param(const string &pname, LVector2f p2f);
void set_param(const string &pname, LVector3f p3f);
void set_param(const string &pname, LVector4f p4f);
void set_param(const string &pname, double p1d);
void set_param(const string &pname, LVector2d p2d);
void set_param(const string &pname, LVector3d p3d);
void set_param(const string &pname, LVector4d p4d);
static void register_with_read_factory();
private:
ShaderModeArg *mod_param(const string &pname, int kind);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedWritableReferenceCount::init_type();
register_type(_type_handle, "ShaderMode",
TypedWritableReferenceCount::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "shaderMode.I"
#endif

View File

@ -540,9 +540,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void TexGenAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -429,9 +429,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: TexMatrixAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void TexMatrixAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -688,9 +688,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void TextureAttrib::
store_into_slot(AttribSlots *slots) const {

View File

@ -117,9 +117,8 @@ make_default_impl() const {
////////////////////////////////////////////////////////////////////
// Function: TransparencyAttrib::store_into_slot
// Access: Public, Virtual
// Description: When attribs are stored in a slot-based attrib array,
// this returns the index of the appropriate slot
// for this attrib type.
// Description: Stores this attrib into the appropriate slot of
// an object of class AttribSlots.
////////////////////////////////////////////////////////////////////
void TransparencyAttrib::
store_into_slot(AttribSlots *slots) const {