mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
Shader vertex arrays implemented
This commit is contained in:
parent
09878b64b0
commit
83b88c1ac3
@ -707,6 +707,20 @@ set_transform(const TransformState *transform) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GraphicsStateGuardian::get_transform
|
||||||
|
// Access: Public
|
||||||
|
// Description: Fetches the external net transform. This
|
||||||
|
// transform is generally only set when geometry is
|
||||||
|
// about to be rendered. Therefore, this "get" function
|
||||||
|
// is typically only meaningful during the geometry
|
||||||
|
// rendering process.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPT(TransformState) GraphicsStateGuardian::
|
||||||
|
get_transform() {
|
||||||
|
return _external_transform;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GraphicsStateGuardian::get_current_display_region
|
// Function: GraphicsStateGuardian::get_current_display_region
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -209,6 +209,7 @@ public:
|
|||||||
INLINE void modify_state(const RenderState *state);
|
INLINE void modify_state(const RenderState *state);
|
||||||
INLINE void set_state(const RenderState *state);
|
INLINE void set_state(const RenderState *state);
|
||||||
INLINE void set_transform(const TransformState *transform);
|
INLINE void set_transform(const TransformState *transform);
|
||||||
|
INLINE CPT(TransformState) get_transform();
|
||||||
|
|
||||||
RenderBuffer get_render_buffer(int buffer_type);
|
RenderBuffer get_render_buffer(int buffer_type);
|
||||||
|
|
||||||
|
@ -771,8 +771,10 @@ reset() {
|
|||||||
|
|
||||||
_texgen_forced_normal = false;
|
_texgen_forced_normal = false;
|
||||||
|
|
||||||
_shader_mode = (ShaderMode *)NULL;
|
_current_shader_mode = (ShaderMode *)NULL;
|
||||||
_shader_context = (CLP(ShaderContext) *)NULL;
|
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
|
_vertex_array_shader_mode = (ShaderMode *)NULL;
|
||||||
|
_vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
|
|
||||||
// Count the max number of lights
|
// Count the max number of lights
|
||||||
GLint max_lights;
|
GLint max_lights;
|
||||||
@ -1297,8 +1299,53 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable the appropriate vertex arrays, and disable any
|
||||||
|
// extra vertex arrays used by the previous rendering mode.
|
||||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
_use_sender = !vertex_arrays;
|
_use_sender = !vertex_arrays;
|
||||||
|
#endif
|
||||||
|
if (_vertex_array_shader_context==0) {
|
||||||
|
if (_current_shader_context==0) {
|
||||||
|
update_standard_vertex_arrays();
|
||||||
|
} else {
|
||||||
|
disable_standard_vertex_arrays();
|
||||||
|
_current_shader_context->update_shader_vertex_arrays(NULL,this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_current_shader_context==0) {
|
||||||
|
_vertex_array_shader_context->disable_shader_vertex_arrays(this);
|
||||||
|
update_standard_vertex_arrays();
|
||||||
|
} else {
|
||||||
|
_current_shader_context->
|
||||||
|
update_shader_vertex_arrays(_vertex_array_shader_context,this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_vertex_array_shader_mode = _current_shader_mode;
|
||||||
|
_vertex_array_shader_context = _current_shader_context;
|
||||||
|
|
||||||
|
report_my_gl_errors();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::update_standard_vertex_arrays
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Disables any unneeded vertex arrays that
|
||||||
|
// were previously enabled, and enables any vertex
|
||||||
|
// arrays that are needed that were not previously
|
||||||
|
// enabled (or, sets up an immediate-mode sender).
|
||||||
|
// Called only from begin_draw_primitives.
|
||||||
|
// Used only when the standard (non-shader) pipeline
|
||||||
|
// is about to be used - glShaderContexts are responsible
|
||||||
|
// for setting up their own vertex arrays.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsStateGuardian)::
|
||||||
|
update_standard_vertex_arrays()
|
||||||
|
{
|
||||||
|
const GeomVertexAnimationSpec &animation =
|
||||||
|
_vertex_data->get_format()->get_animation();
|
||||||
|
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
|
||||||
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
if (_use_sender) {
|
if (_use_sender) {
|
||||||
// We must use immediate mode to render primitives.
|
// We must use immediate mode to render primitives.
|
||||||
_sender.clear();
|
_sender.clear();
|
||||||
@ -1500,9 +1547,46 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
|||||||
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays
|
||||||
|
// Access: Protected
|
||||||
|
// Description: Used to disable all the standard vertex arrays that
|
||||||
|
// are currently enabled. glShaderContexts are
|
||||||
|
// responsible for setting up their own vertex arrays,
|
||||||
|
// but before they can do so, the standard vertex
|
||||||
|
// arrays need to be disabled to get them "out of the
|
||||||
|
// way." Called only from begin_draw_primitives.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(GraphicsStateGuardian)::
|
||||||
|
disable_standard_vertex_arrays()
|
||||||
|
{
|
||||||
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
|
if (_use_sender) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLP(DisableClientState)(GL_NORMAL_ARRAY);
|
||||||
|
GLP(DisableClientState)(GL_COLOR_ARRAY);
|
||||||
|
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
report_my_gl_errors();
|
||||||
|
|
||||||
|
for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
|
||||||
|
_glClientActiveTexture(GL_TEXTURE0 + stage_index);
|
||||||
|
GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
}
|
||||||
|
_last_max_stage_index = 0;
|
||||||
|
report_my_gl_errors();
|
||||||
|
|
||||||
|
if (_supports_vertex_blend) {
|
||||||
|
GLP(DisableClientState)(GL_WEIGHT_ARRAY_ARB);
|
||||||
|
if (_supports_matrix_palette) {
|
||||||
|
GLP(DisableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLP(DisableClientState)(GL_VERTEX_ARRAY);
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1554,6 +1638,9 @@ draw_triangles(const GeomTriangles *primitive) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsStateGuardian)::
|
void CLP(GraphicsStateGuardian)::
|
||||||
draw_tristrips(const GeomTristrips *primitive) {
|
draw_tristrips(const GeomTristrips *primitive) {
|
||||||
|
|
||||||
|
report_my_gl_errors();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (GLCAT.is_spam()) {
|
if (GLCAT.is_spam()) {
|
||||||
GLCAT.spam() << "draw_tristrips: " << *primitive << "\n";
|
GLCAT.spam() << "draw_tristrips: " << *primitive << "\n";
|
||||||
@ -2558,6 +2645,9 @@ issue_transform(const TransformState *transform) {
|
|||||||
do_auto_rescale_normal();
|
do_auto_rescale_normal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_current_shader_context)
|
||||||
|
_current_shader_context->issue_transform(_current_shader_mode, this);
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2590,10 +2680,10 @@ void CLP(GraphicsStateGuardian)::
|
|||||||
issue_shader(const ShaderAttrib *attrib) {
|
issue_shader(const ShaderAttrib *attrib) {
|
||||||
ShaderMode *mode = attrib->get_shader_mode();
|
ShaderMode *mode = attrib->get_shader_mode();
|
||||||
if (mode == 0) {
|
if (mode == 0) {
|
||||||
if (_shader_context != 0) {
|
if (_current_shader_context != 0) {
|
||||||
_shader_context->unbind();
|
_current_shader_context->unbind();
|
||||||
_shader_context = 0;
|
_current_shader_mode = 0;
|
||||||
_shader_mode = 0;
|
_current_shader_context = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2601,23 +2691,35 @@ issue_shader(const ShaderAttrib *attrib) {
|
|||||||
Shader *shader = mode->get_shader();
|
Shader *shader = mode->get_shader();
|
||||||
CLP(ShaderContext) *context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
|
CLP(ShaderContext) *context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
|
||||||
|
|
||||||
if (context != _shader_context) {
|
if (context == 0) {
|
||||||
|
if (_current_shader_context != 0) {
|
||||||
|
_current_shader_context->unbind();
|
||||||
|
_current_shader_mode = 0;
|
||||||
|
_current_shader_context = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context != _current_shader_context) {
|
||||||
// Use a completely different shader than before.
|
// Use a completely different shader than before.
|
||||||
// Unbind old shader, bind the new one.
|
// Unbind old shader, bind the new one.
|
||||||
if (_shader_context != 0) {
|
if (_current_shader_context != 0) {
|
||||||
_shader_context->unbind();
|
_current_shader_context->unbind();
|
||||||
_shader_context = 0;
|
_current_shader_context = 0;
|
||||||
}
|
}
|
||||||
if (context != 0) {
|
if (context != 0) {
|
||||||
context->bind(mode, this);
|
context->bind(mode, this);
|
||||||
_shader_context = context;
|
_current_shader_mode = mode;
|
||||||
|
_current_shader_context = context;
|
||||||
}
|
}
|
||||||
_shader_mode = mode;
|
|
||||||
} else {
|
} else {
|
||||||
// Use the same shader as before, but with new input arguments.
|
// Use the same shader as before, but with new input arguments.
|
||||||
context->rebind(_shader_mode, mode);
|
_current_shader_mode = mode;
|
||||||
_shader_mode = mode;
|
_current_shader_context = context;
|
||||||
|
context->issue_parameters(mode, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
report_my_gl_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -73,6 +73,7 @@ class EXPCL_GL CLP(GraphicsStateGuardian) : public GraphicsStateGuardian {
|
|||||||
public:
|
public:
|
||||||
CLP(GraphicsStateGuardian)(const FrameBufferProperties &properties);
|
CLP(GraphicsStateGuardian)(const FrameBufferProperties &properties);
|
||||||
virtual ~CLP(GraphicsStateGuardian)();
|
virtual ~CLP(GraphicsStateGuardian)();
|
||||||
|
friend class CLP(ShaderContext);
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
|
|
||||||
@ -248,6 +249,9 @@ protected:
|
|||||||
static GLenum get_blend_func(ColorBlendAttrib::Operand operand);
|
static GLenum get_blend_func(ColorBlendAttrib::Operand operand);
|
||||||
static GLenum get_usage(Geom::UsageHint usage_hint);
|
static GLenum get_usage(Geom::UsageHint usage_hint);
|
||||||
|
|
||||||
|
void disable_standard_vertex_arrays();
|
||||||
|
void update_standard_vertex_arrays();
|
||||||
|
|
||||||
static CPT(RenderState) get_untextured_state();
|
static CPT(RenderState) get_untextured_state();
|
||||||
static CPT(RenderState) get_smooth_state();
|
static CPT(RenderState) get_smooth_state();
|
||||||
static CPT(RenderState) get_flat_state();
|
static CPT(RenderState) get_flat_state();
|
||||||
@ -296,8 +300,6 @@ protected:
|
|||||||
bool _polygon_offset_enabled;
|
bool _polygon_offset_enabled;
|
||||||
bool _flat_shade_model;
|
bool _flat_shade_model;
|
||||||
int _decal_level;
|
int _decal_level;
|
||||||
PT(ShaderMode) _shader_mode;
|
|
||||||
CLP(ShaderContext) *_shader_context;
|
|
||||||
|
|
||||||
bool _dithering_enabled;
|
bool _dithering_enabled;
|
||||||
bool _texgen_forced_normal;
|
bool _texgen_forced_normal;
|
||||||
@ -311,6 +313,11 @@ protected:
|
|||||||
bool _point_perspective;
|
bool _point_perspective;
|
||||||
bool _vertex_blending_enabled;
|
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;
|
||||||
|
|
||||||
CPT(DisplayRegion) _actual_display_region;
|
CPT(DisplayRegion) _actual_display_region;
|
||||||
|
|
||||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
|
@ -31,14 +31,13 @@ CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
|
|||||||
|
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
_cg_context = (CGcontext)0;
|
_cg_context = (CGcontext)0;
|
||||||
_cg_profile[VERT_SHADER] = (CGprofile)0;
|
_cg_profile[SHADER_type_vert] = (CGprofile)0;
|
||||||
_cg_profile[FRAG_SHADER] = (CGprofile)0;
|
_cg_profile[SHADER_type_frag] = (CGprofile)0;
|
||||||
_cg_program[VERT_SHADER] = (CGprogram)0;
|
_cg_program[SHADER_type_vert] = (CGprogram)0;
|
||||||
_cg_program[FRAG_SHADER] = (CGprogram)0;
|
_cg_program[SHADER_type_frag] = (CGprogram)0;
|
||||||
|
|
||||||
if (header == "Cg") {
|
if (header == "//Cg") {
|
||||||
|
|
||||||
CGerror err;
|
|
||||||
_cg_context = cgCreateContext();
|
_cg_context = cgCreateContext();
|
||||||
if (_cg_context == 0) {
|
if (_cg_context == 0) {
|
||||||
release_resources();
|
release_resources();
|
||||||
@ -46,46 +45,28 @@ CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cg_profile[VERT_SHADER] = cgGLGetLatestProfile(CG_GL_VERTEX);
|
_cg_profile[SHADER_type_vert] = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||||
_cg_profile[FRAG_SHADER] = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
_cg_profile[SHADER_type_frag] = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||||
if ((_cg_profile[VERT_SHADER] == CG_PROFILE_UNKNOWN)||
|
if ((_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN)||
|
||||||
(_cg_profile[FRAG_SHADER] == CG_PROFILE_UNKNOWN)) {
|
(_cg_profile[SHADER_type_frag] == CG_PROFILE_UNKNOWN)) {
|
||||||
release_resources();
|
release_resources();
|
||||||
cerr << "Cg not supported by this video card II\n";
|
cerr << "Cg not supported by this video card II\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgGetError();
|
cgGetError();
|
||||||
|
_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);
|
||||||
|
|
||||||
string commentary, stext[2];
|
cgGetError();
|
||||||
s->parse_upto(commentary, "---*---", false);
|
_cg_program[1] =
|
||||||
_cg_linebase[0] = s->parse_lineno();
|
cgCreateProgram(_cg_context, CG_SOURCE, s->_text.c_str(),
|
||||||
s->parse_upto(stext[0], "---*---", false);
|
_cg_profile[1], "fshader", (const char**)NULL);
|
||||||
_cg_linebase[1] = s->parse_lineno();
|
print_cg_compile_errors(s->_file, _cg_context);
|
||||||
s->parse_upto(stext[1], "---*---", false);
|
|
||||||
|
|
||||||
for (int progindex=0; progindex<2; progindex++) {
|
if ((_cg_program[SHADER_type_vert]==0)||(_cg_program[SHADER_type_frag]==0)) {
|
||||||
_cg_program[progindex] =
|
|
||||||
cgCreateProgram(_cg_context, CG_SOURCE, stext[progindex].c_str(),
|
|
||||||
_cg_profile[progindex], "main", (const char**)NULL);
|
|
||||||
err = cgGetError();
|
|
||||||
if (err != CG_NO_ERROR) {
|
|
||||||
if (err == CG_COMPILER_ERROR) {
|
|
||||||
string listing = cgGetLastListing(_cg_context);
|
|
||||||
vector_string errlines;
|
|
||||||
tokenize(listing, errlines, "\n");
|
|
||||||
for (int i=0; i<(int)errlines.size(); i++) {
|
|
||||||
string line = trim(errlines[i]);
|
|
||||||
if (line != "") {
|
|
||||||
cerr << s->_file << " " << (_cg_linebase[progindex]-1) << "+" << errlines[i] << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cerr << s->_file << ": " << cgGetErrorString(err) << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_cg_program[VERT_SHADER]==0)||(_cg_program[FRAG_SHADER]==0)) {
|
|
||||||
release_resources();
|
release_resources();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -104,8 +85,8 @@ CLP(ShaderContext)(Shader *s) : ShaderContext(s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgGLLoadProgram(_cg_program[VERT_SHADER]);
|
cgGLLoadProgram(_cg_program[SHADER_type_vert]);
|
||||||
cgGLLoadProgram(_cg_program[FRAG_SHADER]);
|
cgGLLoadProgram(_cg_program[SHADER_type_frag]);
|
||||||
|
|
||||||
cerr << s->_file << ": compiled ok.\n";
|
cerr << s->_file << ": compiled ok.\n";
|
||||||
return;
|
return;
|
||||||
@ -137,10 +118,10 @@ release_resources() {
|
|||||||
if (_cg_context) {
|
if (_cg_context) {
|
||||||
cgDestroyContext(_cg_context);
|
cgDestroyContext(_cg_context);
|
||||||
_cg_context = (CGcontext)0;
|
_cg_context = (CGcontext)0;
|
||||||
_cg_profile[VERT_SHADER] = (CGprofile)0;
|
_cg_profile[SHADER_type_vert] = (CGprofile)0;
|
||||||
_cg_profile[FRAG_SHADER] = (CGprofile)0;
|
_cg_profile[SHADER_type_frag] = (CGprofile)0;
|
||||||
_cg_program[VERT_SHADER] = (CGprogram)0;
|
_cg_program[SHADER_type_vert] = (CGprogram)0;
|
||||||
_cg_program[FRAG_SHADER] = (CGprogram)0;
|
_cg_program[SHADER_type_frag] = (CGprogram)0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -148,38 +129,24 @@ release_resources() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::bind
|
// Function: GLShaderContext::bind
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: xyz
|
// Description: This function is to be called to enable a new
|
||||||
|
// shader. It also initializes all of the shader's
|
||||||
|
// input parameters.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(ShaderContext)::
|
void CLP(ShaderContext)::
|
||||||
bind(ShaderMode *m, GraphicsStateGuardianBase *gsg) {
|
bind(ShaderMode *m, GSG *gsg) {
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
if (_cg_context != 0) {
|
if (_cg_context != 0) {
|
||||||
LVector4d tvec;
|
|
||||||
|
|
||||||
// Assign the uniform Auto-Matrices
|
// Pass in k-parameters and transform-parameters
|
||||||
for (int i=0; i<(int)_cg_autobind.size(); i++) {
|
issue_parameters(m, gsg);
|
||||||
cgGLSetStateMatrixParameter(_cg_autobind[i].parameter,
|
issue_transform(m, gsg);
|
||||||
_cg_autobind[i].matrix,
|
|
||||||
_cg_autobind[i].orientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind the shaders.
|
// Bind the shaders.
|
||||||
cgGLEnableProfile(_cg_profile[VERT_SHADER]);
|
cgGLEnableProfile(_cg_profile[SHADER_type_vert]);
|
||||||
cgGLBindProgram(_cg_program[VERT_SHADER]);
|
cgGLBindProgram(_cg_program[SHADER_type_vert]);
|
||||||
cgGLEnableProfile(_cg_profile[FRAG_SHADER]);
|
cgGLEnableProfile(_cg_profile[SHADER_type_frag]);
|
||||||
cgGLBindProgram(_cg_program[FRAG_SHADER]);
|
cgGLBindProgram(_cg_program[SHADER_type_frag]);
|
||||||
|
|
||||||
// Pass in uniform sampler2d parameters.
|
|
||||||
for (int i=0; i<(int)_cg_tbind2d.size(); i++) {
|
|
||||||
int index = _cg_tbind2d[i].argindex;
|
|
||||||
if (index >= (int)m->_args.size()) continue;
|
|
||||||
if (m->_args[index]._type != ShaderModeArg::SAT_TEXTURE) continue;
|
|
||||||
Texture *tex = m->_args[index]._tvalue;
|
|
||||||
TextureContext *tc = tex->prepare_now(gsg->get_prepared_objects(),gsg);
|
|
||||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
|
||||||
cgGLSetTextureParameter(_cg_tbind2d[i].parameter, gtc->_index);
|
|
||||||
cgGLEnableTextureParameter(_cg_tbind2d[i].parameter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -187,32 +154,222 @@ bind(ShaderMode *m, GraphicsStateGuardianBase *gsg) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::unbind
|
// Function: GLShaderContext::unbind
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: xyz
|
// Description: This function disables a currently-bound shader.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(ShaderContext)::
|
void CLP(ShaderContext)::
|
||||||
unbind() {
|
unbind()
|
||||||
|
{
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
if (_cg_context != 0) {
|
if (_cg_context != 0) {
|
||||||
// Disable texture parameters.
|
cgGLDisableProfile(_cg_profile[SHADER_type_vert]);
|
||||||
for (int i=0; i<(int)_cg_tbind2d.size(); i++)
|
cgGLDisableProfile(_cg_profile[SHADER_type_frag]);
|
||||||
cgGLDisableTextureParameter(_cg_tbind2d[i].parameter);
|
|
||||||
|
|
||||||
cgGLDisableProfile(_cg_profile[VERT_SHADER]);
|
|
||||||
cgGLDisableProfile(_cg_profile[FRAG_SHADER]);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::rebind
|
// Function: GLShaderContext::issue_parameters
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: xyz
|
// 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.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(ShaderContext)::
|
void CLP(ShaderContext)::
|
||||||
rebind(ShaderMode *oldmode, ShaderMode *newmode) {
|
issue_parameters(ShaderMode *m, 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLShaderContext::issue_transform
|
||||||
|
// 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
|
||||||
|
// new transform into the already-bound shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(ShaderContext)::
|
||||||
|
issue_transform(ShaderMode *m, GSG *gsg)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CGGL
|
||||||
|
if (_cg_context != 0) {
|
||||||
|
// Pass in modelview, projection, etc.
|
||||||
|
for (int i=0; i<(int)_cg_autobind.size(); i++)
|
||||||
|
cgGLSetStateMatrixParameter(_cg_autobind[i].parameter,
|
||||||
|
_cg_autobind[i].matrix,
|
||||||
|
_cg_autobind[i].orient);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLShaderContext::disable_shader_vertex_arrays
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disable all the vertex arrays used by this shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(ShaderContext)::
|
||||||
|
disable_shader_vertex_arrays(GSG *gsg)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_CGGL
|
||||||
|
if (_cg_context)
|
||||||
|
for (int i=0; i<(int)_cg_varying.size(); i++)
|
||||||
|
cgGLDisableClientState(_cg_varying[i].parameter);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLShaderContext::update_shader_vertex_arrays
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disables all vertex arrays used by the previous
|
||||||
|
// shader, then enables all the vertex arrays needed
|
||||||
|
// by this shader. Extracts the relevant vertex array
|
||||||
|
// data from the gsg.
|
||||||
|
// The current implementation is inefficient, because
|
||||||
|
// it may unnecessarily disable arrays then immediately
|
||||||
|
// reenable them. We may optimize this someday.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(ShaderContext)::
|
||||||
|
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||||
|
{
|
||||||
|
if (prev) prev->disable_shader_vertex_arrays(gsg);
|
||||||
|
#ifdef HAVE_CGGL
|
||||||
|
if (_cg_context) {
|
||||||
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
|
if (_use_sender) {
|
||||||
|
cerr << "immediate mode shaders not implemented yet\n";
|
||||||
|
} else
|
||||||
|
#endif // SUPPORT_IMMEDIATE_MODE
|
||||||
|
{
|
||||||
|
const GeomVertexArrayData *array_data;
|
||||||
|
Geom::NumericType numeric_type;
|
||||||
|
int start, stride, num_values;
|
||||||
|
int nvarying = _cg_varying.size();
|
||||||
|
for (int i=0; i<nvarying; i++) {
|
||||||
|
InternalName *name = _cg_varying[i].name;
|
||||||
|
int texslot = _cg_varying[i].append_uv;
|
||||||
|
if (texslot >= 0) {
|
||||||
|
const Geom::ActiveTextureStages &active_stages =
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gsg->_vertex_data->get_array_info(name,
|
||||||
|
array_data, num_values, numeric_type,
|
||||||
|
start, stride)) {
|
||||||
|
const unsigned char *client_pointer = gsg->setup_array_data(array_data);
|
||||||
|
cgGLSetParameterPointer(_cg_varying[i].parameter,
|
||||||
|
num_values, gsg->get_numeric_type(numeric_type),
|
||||||
|
stride, client_pointer + start);
|
||||||
|
cgGLEnableClientState(_cg_varying[i].parameter);
|
||||||
|
} else {
|
||||||
|
cgGLDisableClientState(_cg_varying[i].parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_CGGL
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLShaderContext::bind_cg_transform
|
||||||
|
// Access: Public
|
||||||
|
// Description: Should deallocate all system resources (such as
|
||||||
|
// vertex program handles or Cg contexts).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(ShaderContext)::
|
||||||
|
bind_cg_transform(const ShaderTransBind &stb, ShaderMode *m, 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();
|
||||||
|
} 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
} 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPT(TransformState) total = rel->invert_compose(src);
|
||||||
|
const float *data = total->get_mat().get_data();
|
||||||
|
// cerr << "Input for " << cgGetParameterName(stb.parameter) << " is\n" <<
|
||||||
|
// data[ 0] << " " << data[ 1] << " " << data[ 2] << " " << data[ 3] << "\n" <<
|
||||||
|
// data[ 4] << " " << data[ 5] << " " << data[ 6] << " " << data[ 7] << "\n" <<
|
||||||
|
// data[ 8] << " " << data[ 9] << " " << data[10] << " " << data[11] << "\n" <<
|
||||||
|
// data[12] << " " << data[13] << " " << data[14] << " " << data[15] << "\n";
|
||||||
|
|
||||||
|
switch (stb.trans_piece) {
|
||||||
|
case SHADER_data_matrix: cgGLSetMatrixParameterfc(stb.parameter, data); break;
|
||||||
|
case SHADER_data_transpose: cgGLSetMatrixParameterfr(stb.parameter, data); break;
|
||||||
|
case SHADER_data_row0: cgGLSetParameter4fv(stb.parameter, data+ 0); break;
|
||||||
|
case SHADER_data_row1: cgGLSetParameter4fv(stb.parameter, data+ 4); break;
|
||||||
|
case SHADER_data_row2: cgGLSetParameter4fv(stb.parameter, data+ 8); break;
|
||||||
|
case SHADER_data_row3: cgGLSetParameter4fv(stb.parameter, data+12); break;
|
||||||
|
case SHADER_data_col0: cgGLSetParameter4f(stb.parameter, data[0], data[4], data[ 8], data[12]); break;
|
||||||
|
case SHADER_data_col1: cgGLSetParameter4f(stb.parameter, data[1], data[5], data[ 9], data[13]); break;
|
||||||
|
case SHADER_data_col2: cgGLSetParameter4f(stb.parameter, data[2], data[6], data[10], data[14]); break;
|
||||||
|
case SHADER_data_col3: cgGLSetParameter4f(stb.parameter, data[3], data[7], data[11], data[15]); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::errchk_cg_parameter_words
|
// Function: Shader::errchk_cg_parameter_words
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -291,28 +448,6 @@ errchk_cg_parameter_prog(CGparameter p, CGprogram prog, const string &msg)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Shader::errchk_cg_parameter_semantic
|
|
||||||
// Access: Public, Static
|
|
||||||
// Description: Make sure the provided Cg parameter has the
|
|
||||||
// correct semantic string. If not, print
|
|
||||||
// error message and return false.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool CLP(ShaderContext)::
|
|
||||||
errchk_cg_parameter_semantic(CGparameter p, const string &semantic)
|
|
||||||
{
|
|
||||||
if (semantic != cgGetParameterSemantic(p)) {
|
|
||||||
if (semantic == "") {
|
|
||||||
errchk_cg_output(p, "parameter should have no semantic string");
|
|
||||||
} else {
|
|
||||||
string msg = "parameter should have the semantic string ";
|
|
||||||
errchk_cg_output(p, msg + semantic);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::errchk_cg_parameter_type
|
// Function: Shader::errchk_cg_parameter_type
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -368,7 +503,7 @@ errchk_cg_parameter_sampler(CGparameter p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Shader::errchk_cg_parameter_direction
|
// Function: Shader::errchk_cg_output
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
// Description: Print an error message including a description
|
// Description: Print an error message including a description
|
||||||
// of the specified Cg parameter.
|
// of the specified Cg parameter.
|
||||||
@ -389,18 +524,42 @@ errchk_cg_output(CGparameter p, const string &msg)
|
|||||||
if (d == CG_INOUT) dstr = "inout ";
|
if (d == CG_INOUT) dstr = "inout ";
|
||||||
|
|
||||||
const char *ts = cgGetTypeString(cgGetParameterType(p));
|
const char *ts = cgGetTypeString(cgGetParameterType(p));
|
||||||
const char *ss = cgGetParameterSemantic(p);
|
|
||||||
|
|
||||||
string err;
|
string err;
|
||||||
string fn = _shader->_file;
|
string fn = _shader->_file;
|
||||||
if (ss) {
|
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
|
||||||
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ":" + ss + ")\n";
|
|
||||||
} else {
|
|
||||||
err = fn + ": " + msg + " (" + vstr + dstr + ts + " " + cgGetParameterName(p) + ")\n";
|
|
||||||
}
|
|
||||||
cerr << err << "\n";
|
cerr << err << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Shader::print_cg_compile_errors
|
||||||
|
// Access: Public, Static
|
||||||
|
// Description: Used only after a Cg compile command, to print
|
||||||
|
// out any error messages that may have occurred
|
||||||
|
// during the Cg shader compilation. The 'file'
|
||||||
|
// is the name of the file containing the Cg code.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(ShaderContext)::
|
||||||
|
print_cg_compile_errors(const string &file, CGcontext ctx)
|
||||||
|
{
|
||||||
|
CGerror err = cgGetError();
|
||||||
|
if (err != CG_NO_ERROR) {
|
||||||
|
if (err == CG_COMPILER_ERROR) {
|
||||||
|
string listing = cgGetLastListing(ctx);
|
||||||
|
vector_string errlines;
|
||||||
|
tokenize(listing, errlines, "\n");
|
||||||
|
for (int i=0; i<(int)errlines.size(); i++) {
|
||||||
|
string line = trim(errlines[i]);
|
||||||
|
if (line != "") {
|
||||||
|
cerr << file << " " << errlines[i] << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cerr << file << ": " << cgGetErrorString(err) << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::compile_cg_parameter
|
// Function: GLShaderContext::compile_cg_parameter
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -418,39 +577,53 @@ compile_cg_parameter(CGparameter p)
|
|||||||
vector_string pieces;
|
vector_string pieces;
|
||||||
tokenize(pname, pieces, "_");
|
tokenize(pname, pieces, "_");
|
||||||
|
|
||||||
if (pieces[0] == "vtx") {
|
if (pieces.size() < 2) {
|
||||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
errchk_cg_output(p,"invalid parameter name");
|
||||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
|
||||||
(!errchk_cg_parameter_variance(p, CG_VARYING)) ||
|
|
||||||
(!errchk_cg_parameter_prog(p, _cg_program[VERT_SHADER], "vertex")))
|
|
||||||
return false;
|
|
||||||
if (pieces[1] == "position") {
|
|
||||||
if (!errchk_cg_parameter_semantic(p,"POSITION")) return false;
|
|
||||||
if (!errchk_cg_parameter_float(p)) return false;
|
|
||||||
return true; // Cg handles this automatically.
|
|
||||||
}
|
|
||||||
if (pieces[1] == "normal") {
|
|
||||||
if (!errchk_cg_parameter_semantic(p,"NORMAL")) return false;
|
|
||||||
if (!errchk_cg_parameter_float(p)) return false;
|
|
||||||
return true; // Cg handles this automatically.
|
|
||||||
}
|
|
||||||
if (pieces[1] == "color") {
|
|
||||||
if (!errchk_cg_parameter_semantic(p,"COLOR")) return false;
|
|
||||||
if (!errchk_cg_parameter_float(p)) return false;
|
|
||||||
return true; // Cg handles this automatically.
|
|
||||||
}
|
|
||||||
if (pieces[1].substr(0,8) == "texcoord") {
|
|
||||||
string ss = upcase(pieces[1]);
|
|
||||||
if (!errchk_cg_parameter_semantic(p,ss)) return false;
|
|
||||||
if (!errchk_cg_parameter_float(p)) return false;
|
|
||||||
return true; // Cg handles this automatically.
|
|
||||||
}
|
|
||||||
// Handle an arbitrary column taken from the vertex array.
|
|
||||||
// IMPLEMENT ME.
|
|
||||||
errchk_cg_output(p, "Arbitrary vertex fields not implemented yet");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pieces[0] == "vtx") {
|
||||||
|
if ((!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||||
|
(!errchk_cg_parameter_variance(p, CG_VARYING)) ||
|
||||||
|
(!errchk_cg_parameter_float(p)) ||
|
||||||
|
(!errchk_cg_parameter_prog(p, _cg_program[SHADER_type_vert], "vertex")))
|
||||||
|
return false;
|
||||||
|
ShaderVarying bind;
|
||||||
|
bind.parameter = p;
|
||||||
|
if (pieces.size() == 2) {
|
||||||
|
if (pieces[1]=="position") {
|
||||||
|
bind.name = InternalName::get_vertex();
|
||||||
|
bind.append_uv = -1;
|
||||||
|
_cg_varying.push_back(bind);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pieces[1].substr(0,8)=="texcoord") {
|
||||||
|
bind.name = InternalName::get_root();
|
||||||
|
bind.append_uv = atoi(pieces[1].c_str()+8);
|
||||||
|
_cg_varying.push_back(bind);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pieces[1].substr(0,7)=="tangent") {
|
||||||
|
bind.name = InternalName::get_tangent();
|
||||||
|
bind.append_uv = atoi(pieces[1].c_str()+7);
|
||||||
|
_cg_varying.push_back(bind);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pieces[1].substr(0,8)=="binormal") {
|
||||||
|
bind.name = InternalName::get_binormal();
|
||||||
|
bind.append_uv = atoi(pieces[1].c_str()+8);
|
||||||
|
_cg_varying.push_back(bind);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bind.name = InternalName::get_root();
|
||||||
|
bind.append_uv = -1;
|
||||||
|
for (int i=1; i<(int)(pieces.size()-0); i++)
|
||||||
|
bind.name = bind.name->append(pieces[i]);
|
||||||
|
_cg_varying.push_back(bind);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pieces[0] == "trans")||
|
if ((pieces[0] == "trans")||
|
||||||
(pieces[0] == "tpose")||
|
(pieces[0] == "tpose")||
|
||||||
(pieces[0] == "row0")||
|
(pieces[0] == "row0")||
|
||||||
@ -460,57 +633,48 @@ compile_cg_parameter(CGparameter p)
|
|||||||
(pieces[0] == "col0")||
|
(pieces[0] == "col0")||
|
||||||
(pieces[0] == "col1")||
|
(pieces[0] == "col1")||
|
||||||
(pieces[0] == "col2")||
|
(pieces[0] == "col2")||
|
||||||
(pieces[0] == "col3")||
|
(pieces[0] == "col3")) {
|
||||||
(pieces[0] == "xvec")||
|
|
||||||
(pieces[0] == "yvec")||
|
|
||||||
(pieces[0] == "zvec")||
|
|
||||||
(pieces[0] == "pos")) {
|
|
||||||
if ((!errchk_cg_parameter_words(p,4)) ||
|
if ((!errchk_cg_parameter_words(p,4)) ||
|
||||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
|
||||||
(!errchk_cg_parameter_semantic(p, "")))
|
|
||||||
return false;
|
return false;
|
||||||
if (pieces[2] != "rel") {
|
if ((pieces[2] != "rel")&&(pieces[2] != "to")) {
|
||||||
errchk_cg_output(p, "syntax error");
|
errchk_cg_output(p, "syntax error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ShaderTransBind bind;
|
ShaderTransBind bind;
|
||||||
bind.parameter = p;
|
bind.parameter = p;
|
||||||
|
|
||||||
if (pieces[0]=="trans") bind.trans_piece = TRANS_NORMAL;
|
if (pieces[0]=="trans") bind.trans_piece = SHADER_data_matrix;
|
||||||
else if (pieces[0]=="tpose") bind.trans_piece = TRANS_TPOSE;
|
else if (pieces[0]=="tpose") bind.trans_piece = SHADER_data_transpose;
|
||||||
else if (pieces[0]=="row0") bind.trans_piece = TRANS_ROW0;
|
else if (pieces[0]=="row0") bind.trans_piece = SHADER_data_row0;
|
||||||
else if (pieces[0]=="row1") bind.trans_piece = TRANS_ROW1;
|
else if (pieces[0]=="row1") bind.trans_piece = SHADER_data_row1;
|
||||||
else if (pieces[0]=="row2") bind.trans_piece = TRANS_ROW2;
|
else if (pieces[0]=="row2") bind.trans_piece = SHADER_data_row2;
|
||||||
else if (pieces[0]=="row3") bind.trans_piece = TRANS_ROW3;
|
else if (pieces[0]=="row3") bind.trans_piece = SHADER_data_row3;
|
||||||
else if (pieces[0]=="col0") bind.trans_piece = TRANS_COL0;
|
else if (pieces[0]=="col0") bind.trans_piece = SHADER_data_col0;
|
||||||
else if (pieces[0]=="col1") bind.trans_piece = TRANS_COL1;
|
else if (pieces[0]=="col1") bind.trans_piece = SHADER_data_col1;
|
||||||
else if (pieces[0]=="col2") bind.trans_piece = TRANS_COL2;
|
else if (pieces[0]=="col2") bind.trans_piece = SHADER_data_col2;
|
||||||
else if (pieces[0]=="col3") bind.trans_piece = TRANS_COL3;
|
else if (pieces[0]=="col3") bind.trans_piece = SHADER_data_col3;
|
||||||
else if (pieces[0]=="xvec") bind.trans_piece = TRANS_ROW0;
|
|
||||||
else if (pieces[0]=="yvec") bind.trans_piece = TRANS_ROW1;
|
|
||||||
else if (pieces[0]=="zvec") bind.trans_piece = TRANS_ROW2;
|
|
||||||
else if (pieces[0]=="pos") bind.trans_piece = TRANS_ROW3;
|
|
||||||
|
|
||||||
if (pieces[1] == "world") bind.src_argindex = ARGINDEX_WORLD;
|
if (pieces[1] == "world") bind.src_argindex = SHADER_arg_world;
|
||||||
else if (pieces[1] == "camera") bind.src_argindex = ARGINDEX_CAMERA;
|
else if (pieces[1] == "camera") bind.src_argindex = SHADER_arg_camera;
|
||||||
else if (pieces[1] == "model") bind.src_argindex = ARGINDEX_MODEL;
|
else if (pieces[1] == "model") bind.src_argindex = SHADER_arg_model;
|
||||||
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
||||||
if (pieces[3] == "world") bind.rel_argindex = ARGINDEX_WORLD;
|
if (pieces[3] == "world") bind.rel_argindex = SHADER_arg_world;
|
||||||
else if (pieces[3] == "camera") bind.rel_argindex = ARGINDEX_CAMERA;
|
else if (pieces[3] == "camera") bind.rel_argindex = SHADER_arg_camera;
|
||||||
else if (pieces[3] == "model") bind.rel_argindex = ARGINDEX_MODEL;
|
else if (pieces[3] == "model") bind.rel_argindex = SHADER_arg_model;
|
||||||
else bind.rel_argindex = _shader->arg_index(pieces[3]);
|
else bind.rel_argindex = _shader->arg_index(pieces[3]);
|
||||||
|
|
||||||
if ((bind.trans_piece == TRANS_NORMAL)||(bind.trans_piece == TRANS_TPOSE)) {
|
if ((bind.trans_piece == SHADER_data_matrix)||(bind.trans_piece == SHADER_data_transpose)) {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||||
} else {
|
} else {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cg_trans_bind.push_back(bind);
|
_cg_parameter_bind.push_back(bind);
|
||||||
if ((bind.src_argindex == ARGINDEX_MODEL) ||
|
if ((bind.src_argindex == SHADER_arg_model) ||
|
||||||
(bind.rel_argindex == ARGINDEX_MODEL)) {
|
(bind.rel_argindex == SHADER_arg_model)) {
|
||||||
_cg_trans_rebind.push_back(bind);
|
_cg_transform_bind.push_back(bind);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -523,34 +687,32 @@ compile_cg_parameter(CGparameter p)
|
|||||||
(pieces[0]=="wspos")) {
|
(pieces[0]=="wspos")) {
|
||||||
if ((!errchk_cg_parameter_words(p,2)) ||
|
if ((!errchk_cg_parameter_words(p,2)) ||
|
||||||
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
(!errchk_cg_parameter_direction(p, CG_IN)) ||
|
||||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
(!errchk_cg_parameter_variance(p, CG_UNIFORM)))
|
||||||
(!errchk_cg_parameter_semantic(p, "")))
|
|
||||||
return false;
|
return false;
|
||||||
ShaderTransBind bind;
|
ShaderTransBind bind;
|
||||||
bind.parameter = p;
|
bind.parameter = p;
|
||||||
|
|
||||||
if (pieces[0]=="wstrans") { bind.rel_argindex = ARGINDEX_WORLD; bind.trans_piece = TRANS_NORMAL; }
|
if (pieces[0]=="wstrans") { bind.rel_argindex = SHADER_arg_world; bind.trans_piece = SHADER_data_matrix; }
|
||||||
else if (pieces[0]=="cstrans") { bind.rel_argindex = ARGINDEX_CAMERA; bind.trans_piece = TRANS_NORMAL; }
|
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 = ARGINDEX_MODEL; bind.trans_piece = TRANS_NORMAL; }
|
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 = ARGINDEX_WORLD; bind.trans_piece = TRANS_ROW3; }
|
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 = ARGINDEX_CAMERA; bind.trans_piece = TRANS_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 = ARGINDEX_MODEL; bind.trans_piece = TRANS_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 = ARGINDEX_WORLD;
|
if (pieces[1] == "world") bind.src_argindex = SHADER_arg_world;
|
||||||
else if (pieces[1] == "camera") bind.src_argindex = ARGINDEX_CAMERA;
|
else if (pieces[1] == "camera") bind.src_argindex = SHADER_arg_camera;
|
||||||
else if (pieces[1] == "model") bind.src_argindex = ARGINDEX_MODEL;
|
else if (pieces[1] == "model") bind.src_argindex = SHADER_arg_model;
|
||||||
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
else bind.src_argindex = _shader->arg_index(pieces[1]);
|
||||||
|
|
||||||
if ((bind.trans_piece == TRANS_NORMAL)||(bind.trans_piece == TRANS_TPOSE)) {
|
if ((bind.trans_piece == SHADER_data_matrix)||(bind.trans_piece == SHADER_data_transpose)) {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4x4)) return false;
|
||||||
} else {
|
} else {
|
||||||
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
if (!errchk_cg_parameter_type(p, CG_FLOAT4)) return false;
|
||||||
}
|
}
|
||||||
_cg_trans_bind.push_back(bind);
|
_cg_parameter_bind.push_back(bind);
|
||||||
if ((bind.src_argindex == ARGINDEX_MODEL) ||
|
if ((bind.src_argindex == SHADER_arg_model) ||
|
||||||
(bind.rel_argindex == ARGINDEX_MODEL)) {
|
(bind.rel_argindex == SHADER_arg_model))
|
||||||
_cg_trans_rebind.push_back(bind);
|
_cg_transform_bind.push_back(bind);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,10 +735,10 @@ compile_cg_parameter(CGparameter p)
|
|||||||
errchk_cg_output(p, "unrecognized matrix name");
|
errchk_cg_output(p, "unrecognized matrix name");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pieces[0]=="mat") bind.orientation = CG_GL_MATRIX_IDENTITY;
|
if (pieces[0]=="mat") bind.orient = CG_GL_MATRIX_IDENTITY;
|
||||||
else if (pieces[0]=="inv") bind.orientation = CG_GL_MATRIX_INVERSE;
|
else if (pieces[0]=="inv") bind.orient = CG_GL_MATRIX_INVERSE;
|
||||||
else if (pieces[0]=="tps") bind.orientation = CG_GL_MATRIX_TRANSPOSE;
|
else if (pieces[0]=="tps") bind.orient = CG_GL_MATRIX_TRANSPOSE;
|
||||||
else if (pieces[0]=="itp") bind.orientation = CG_GL_MATRIX_INVERSE_TRANSPOSE;
|
else if (pieces[0]=="itp") bind.orient = CG_GL_MATRIX_INVERSE_TRANSPOSE;
|
||||||
_cg_autobind.push_back(bind);
|
_cg_autobind.push_back(bind);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -587,10 +749,7 @@ compile_cg_parameter(CGparameter p)
|
|||||||
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
(!errchk_cg_parameter_variance(p, CG_UNIFORM)) ||
|
||||||
(!errchk_cg_parameter_sampler(p)))
|
(!errchk_cg_parameter_sampler(p)))
|
||||||
return false;
|
return false;
|
||||||
if (cgGetParameterSemantic(p)[0]!=0) {
|
// IMPLEMENT ME
|
||||||
string texunit = "TEX"+upcase(pieces[1]);
|
|
||||||
if (!errchk_cg_parameter_semantic(p, texunit)) return false;
|
|
||||||
}
|
|
||||||
return true; // Cg handles this automatically.
|
return true; // Cg handles this automatically.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,10 +762,7 @@ compile_cg_parameter(CGparameter p)
|
|||||||
bind.parameter = p;
|
bind.parameter = p;
|
||||||
bind.argindex = _shader->arg_index(pieces[1]);
|
bind.argindex = _shader->arg_index(pieces[1]);
|
||||||
switch (cgGetParameterType(p)) {
|
switch (cgGetParameterType(p)) {
|
||||||
case CG_FLOAT1: _cg_vbind1.push_back(bind); break;
|
case CG_FLOAT4: _cg_fbind.push_back(bind); break;
|
||||||
case CG_FLOAT2: _cg_vbind2.push_back(bind); break;
|
|
||||||
case CG_FLOAT3: _cg_vbind3.push_back(bind); break;
|
|
||||||
case CG_FLOAT4: _cg_vbind4.push_back(bind); break;
|
|
||||||
case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
|
case CG_SAMPLER2D: _cg_tbind2d.push_back(bind); break;
|
||||||
case CG_SAMPLER3D: _cg_tbind3d.push_back(bind); break;
|
case CG_SAMPLER3D: _cg_tbind3d.push_back(bind); break;
|
||||||
case CG_FLOAT4x4: _cg_npbind.push_back(bind); break;
|
case CG_FLOAT4x4: _cg_npbind.push_back(bind); break;
|
||||||
@ -631,3 +787,4 @@ compile_cg_parameter(CGparameter p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
|
||||||
|
class CLP(GraphicsStateGuardian);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : GLShaderContext
|
// Class : GLShaderContext
|
||||||
// Description : xyz
|
// Description : xyz
|
||||||
@ -32,36 +34,23 @@ class EXPCL_GL CLP(ShaderContext): public ShaderContext {
|
|||||||
public:
|
public:
|
||||||
CLP(ShaderContext)(Shader *s);
|
CLP(ShaderContext)(Shader *s);
|
||||||
~CLP(ShaderContext)();
|
~CLP(ShaderContext)();
|
||||||
|
typedef CLP(GraphicsStateGuardian) GSG;
|
||||||
|
|
||||||
INLINE bool valid(void);
|
INLINE bool valid(void);
|
||||||
void bind(ShaderMode *mode, GraphicsStateGuardianBase *gsg);
|
void bind(ShaderMode *mode, GSG *gsg);
|
||||||
void unbind();
|
void unbind();
|
||||||
void rebind(ShaderMode *oldmode, ShaderMode *newmode);
|
void issue_parameters(ShaderMode *mode, GSG *gsg);
|
||||||
|
void issue_transform(ShaderMode *mode, GSG *gsg);
|
||||||
|
void disable_shader_vertex_arrays(GSG *gsg);
|
||||||
|
void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef HAVE_CGGL
|
#ifdef HAVE_CGGL
|
||||||
enum {
|
|
||||||
ARGINDEX_WORLD =-1,
|
|
||||||
ARGINDEX_CAMERA=-2,
|
|
||||||
ARGINDEX_MODEL =-3
|
|
||||||
};
|
|
||||||
enum {
|
|
||||||
TRANS_NORMAL,
|
|
||||||
TRANS_TPOSE,
|
|
||||||
TRANS_ROW0,
|
|
||||||
TRANS_ROW1,
|
|
||||||
TRANS_ROW2,
|
|
||||||
TRANS_ROW3,
|
|
||||||
TRANS_COL0,
|
|
||||||
TRANS_COL1,
|
|
||||||
TRANS_COL2,
|
|
||||||
TRANS_COL3,
|
|
||||||
};
|
|
||||||
struct ShaderAutoBind {
|
struct ShaderAutoBind {
|
||||||
CGparameter parameter;
|
CGparameter parameter;
|
||||||
CGGLenum matrix;
|
CGGLenum matrix;
|
||||||
CGGLenum orientation;
|
CGGLenum orient;
|
||||||
};
|
};
|
||||||
struct ShaderArgBind {
|
struct ShaderArgBind {
|
||||||
CGparameter parameter;
|
CGparameter parameter;
|
||||||
@ -73,34 +62,39 @@ private:
|
|||||||
int rel_argindex;
|
int rel_argindex;
|
||||||
int trans_piece;
|
int trans_piece;
|
||||||
};
|
};
|
||||||
|
struct ShaderVarying {
|
||||||
|
CGparameter parameter;
|
||||||
|
PT(InternalName) name;
|
||||||
|
int append_uv;
|
||||||
|
};
|
||||||
CGcontext _cg_context;
|
CGcontext _cg_context;
|
||||||
CGprofile _cg_profile[2];
|
CGprofile _cg_profile[2];
|
||||||
CGprogram _cg_program[2];
|
CGprogram _cg_program[2];
|
||||||
int _cg_linebase[2];
|
|
||||||
|
|
||||||
// These arrays contain lists of "bindings." They
|
// These arrays contain lists of "bindings." They
|
||||||
// tell us how to fill the shader's input parameters.
|
// tell us how to fill the shader's input parameters.
|
||||||
vector <ShaderAutoBind> _cg_autobind;
|
vector <ShaderAutoBind> _cg_autobind;
|
||||||
vector <ShaderArgBind> _cg_tbind2d;
|
vector <ShaderArgBind> _cg_tbind2d;
|
||||||
vector <ShaderArgBind> _cg_tbind3d;
|
vector <ShaderArgBind> _cg_tbind3d;
|
||||||
vector <ShaderArgBind> _cg_vbind1;
|
vector <ShaderArgBind> _cg_fbind;
|
||||||
vector <ShaderArgBind> _cg_vbind2;
|
|
||||||
vector <ShaderArgBind> _cg_vbind3;
|
|
||||||
vector <ShaderArgBind> _cg_vbind4;
|
|
||||||
vector <ShaderArgBind> _cg_npbind;
|
vector <ShaderArgBind> _cg_npbind;
|
||||||
vector <ShaderTransBind> _cg_trans_bind;
|
vector <ShaderTransBind> _cg_transform_bind;
|
||||||
vector <ShaderTransBind> _cg_trans_rebind;
|
vector <ShaderTransBind> _cg_parameter_bind;
|
||||||
|
vector <ShaderVarying> _cg_varying;
|
||||||
|
|
||||||
|
void bind_cg_transform(const ShaderTransBind &stb, ShaderMode *m,
|
||||||
|
CLP(GraphicsStateGuardian) *gsg);
|
||||||
|
|
||||||
bool compile_cg_parameter(CGparameter p);
|
bool compile_cg_parameter(CGparameter p);
|
||||||
bool errchk_cg_parameter_words(CGparameter p, int len);
|
bool errchk_cg_parameter_words(CGparameter p, int len);
|
||||||
bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);
|
bool errchk_cg_parameter_direction(CGparameter p, CGenum dir);
|
||||||
bool errchk_cg_parameter_variance(CGparameter p, CGenum var);
|
bool errchk_cg_parameter_variance(CGparameter p, CGenum var);
|
||||||
bool errchk_cg_parameter_prog(CGparameter p, CGprogram prog, const string &msg);
|
bool errchk_cg_parameter_prog(CGparameter p, CGprogram prog, const string &msg);
|
||||||
bool errchk_cg_parameter_semantic(CGparameter p, const string &semantic);
|
|
||||||
bool errchk_cg_parameter_type(CGparameter p, CGtype dt);
|
bool errchk_cg_parameter_type(CGparameter p, CGtype dt);
|
||||||
bool errchk_cg_parameter_float(CGparameter p);
|
bool errchk_cg_parameter_float(CGparameter p);
|
||||||
bool errchk_cg_parameter_sampler(CGparameter p);
|
bool errchk_cg_parameter_sampler(CGparameter p);
|
||||||
void errchk_cg_output(CGparameter p, const string &msg);
|
void errchk_cg_output(CGparameter p, const string &msg);
|
||||||
|
void print_cg_compile_errors(const string &file, CGcontext ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void release_resources(void);
|
void release_resources(void);
|
||||||
|
@ -42,10 +42,31 @@ public:
|
|||||||
|
|
||||||
Shader *_shader;
|
Shader *_shader;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// The following declarations represent useful routines
|
||||||
|
// and constants that can be used by shader implementations.
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
VERT_SHADER=0,
|
SHADER_type_vert=0,
|
||||||
FRAG_SHADER=1,
|
SHADER_type_frag=1,
|
||||||
BOTH_SHADER=2,
|
SHADER_type_both=2,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
SHADER_arg_world = -1,
|
||||||
|
SHADER_arg_camera = -2,
|
||||||
|
SHADER_arg_model = -3,
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
SHADER_data_matrix,
|
||||||
|
SHADER_data_transpose,
|
||||||
|
SHADER_data_row0,
|
||||||
|
SHADER_data_row1,
|
||||||
|
SHADER_data_row2,
|
||||||
|
SHADER_data_row3,
|
||||||
|
SHADER_data_col0,
|
||||||
|
SHADER_data_col1,
|
||||||
|
SHADER_data_col2,
|
||||||
|
SHADER_data_col3,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -355,6 +355,25 @@ get_clip_plane() const {
|
|||||||
return _clip_plane;
|
return _clip_plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: RenderState::get_shader
|
||||||
|
// Access: Published
|
||||||
|
// Description: This function is provided as an optimization, to
|
||||||
|
// speed up the render-time checking for the existance
|
||||||
|
// of a ShaderAttrib on this state. It returns a
|
||||||
|
// pointer to the ShaderAttrib, if there is one, or
|
||||||
|
// NULL if there is not.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const ShaderAttrib *RenderState::
|
||||||
|
get_shader() const {
|
||||||
|
if ((_flags & F_checked_shader) == 0) {
|
||||||
|
// We pretend this function is const, even though it transparently
|
||||||
|
// modifies the internal shader cache.
|
||||||
|
((RenderState *)this)->determine_shader();
|
||||||
|
}
|
||||||
|
return _shader;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::set_destructing
|
// Function: RenderState::set_destructing
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "colorScaleAttrib.h"
|
#include "colorScaleAttrib.h"
|
||||||
#include "textureAttrib.h"
|
#include "textureAttrib.h"
|
||||||
#include "texGenAttrib.h"
|
#include "texGenAttrib.h"
|
||||||
|
#include "shaderAttrib.h"
|
||||||
#include "pStatTimer.h"
|
#include "pStatTimer.h"
|
||||||
#include "config_pgraph.h"
|
#include "config_pgraph.h"
|
||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
@ -1663,6 +1664,21 @@ determine_clip_plane() {
|
|||||||
_flags |= F_checked_clip_plane;
|
_flags |= F_checked_clip_plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: RenderState::determine_shader
|
||||||
|
// Access: Private
|
||||||
|
// Description: This is the private implementation of get_shader().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void RenderState::
|
||||||
|
determine_shader() {
|
||||||
|
const RenderAttrib *attrib = get_attrib(ShaderAttrib::get_class_type());
|
||||||
|
_shader = (const ShaderAttrib *)NULL;
|
||||||
|
if (attrib != (const RenderAttrib *)NULL) {
|
||||||
|
_shader = DCAST(ShaderAttrib, attrib);
|
||||||
|
}
|
||||||
|
_flags |= F_checked_shader;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: RenderState::update_pstats
|
// Function: RenderState::update_pstats
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -41,6 +41,7 @@ class ColorScaleAttrib;
|
|||||||
class TextureAttrib;
|
class TextureAttrib;
|
||||||
class TexGenAttrib;
|
class TexGenAttrib;
|
||||||
class ClipPlaneAttrib;
|
class ClipPlaneAttrib;
|
||||||
|
class ShaderAttrib;
|
||||||
class FactoryParams;
|
class FactoryParams;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -135,6 +136,7 @@ PUBLISHED:
|
|||||||
INLINE const TexMatrixAttrib *get_tex_matrix() const;
|
INLINE const TexMatrixAttrib *get_tex_matrix() const;
|
||||||
INLINE const RenderModeAttrib *get_render_mode() const;
|
INLINE const RenderModeAttrib *get_render_mode() const;
|
||||||
INLINE const ClipPlaneAttrib *get_clip_plane() const;
|
INLINE const ClipPlaneAttrib *get_clip_plane() const;
|
||||||
|
INLINE const ShaderAttrib *get_shader() const;
|
||||||
|
|
||||||
int get_geom_rendering(int geom_rendering) const;
|
int get_geom_rendering(int geom_rendering) const;
|
||||||
|
|
||||||
@ -180,6 +182,7 @@ private:
|
|||||||
void determine_tex_matrix();
|
void determine_tex_matrix();
|
||||||
void determine_render_mode();
|
void determine_render_mode();
|
||||||
void determine_clip_plane();
|
void determine_clip_plane();
|
||||||
|
void determine_shader();
|
||||||
|
|
||||||
INLINE void set_destructing();
|
INLINE void set_destructing();
|
||||||
INLINE bool is_destructing() const;
|
INLINE bool is_destructing() const;
|
||||||
@ -278,6 +281,7 @@ private:
|
|||||||
const TexMatrixAttrib *_tex_matrix;
|
const TexMatrixAttrib *_tex_matrix;
|
||||||
const RenderModeAttrib *_render_mode;
|
const RenderModeAttrib *_render_mode;
|
||||||
const ClipPlaneAttrib *_clip_plane;
|
const ClipPlaneAttrib *_clip_plane;
|
||||||
|
const ShaderAttrib *_shader;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
F_checked_bin_index = 0x0001,
|
F_checked_bin_index = 0x0001,
|
||||||
@ -291,6 +295,7 @@ private:
|
|||||||
F_checked_tex_matrix = 0x0100,
|
F_checked_tex_matrix = 0x0100,
|
||||||
F_checked_render_mode = 0x0200,
|
F_checked_render_mode = 0x0200,
|
||||||
F_checked_clip_plane = 0x0400,
|
F_checked_clip_plane = 0x0400,
|
||||||
|
F_checked_shader = 0x0800,
|
||||||
F_is_destructing = 0x8000,
|
F_is_destructing = 0x8000,
|
||||||
};
|
};
|
||||||
unsigned short _flags;
|
unsigned short _flags;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user