mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Clean up glShaderContext, separate GLSL shader context from Cg shader context
This commit is contained in:
parent
bddb2f6806
commit
ce6f243019
67
panda/src/glstuff/glCgShaderContext_src.I
Executable file
67
panda/src/glstuff/glCgShaderContext_src.I
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
// Filename: glCgShaderContext_src.h
|
||||||
|
// Created by: rdb (27Jun14)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef OPENGLES_1
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::valid
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the shader is "valid", ie, if the
|
||||||
|
// compilation was successful. The compilation could
|
||||||
|
// fail if there is a syntax error in the shader, or
|
||||||
|
// if the current video card isn't shader-capable,
|
||||||
|
// or if no shader languages are compiled into panda.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool CLP(CgShaderContext)::
|
||||||
|
valid() {
|
||||||
|
if (_shader->get_error_flag()) return false;
|
||||||
|
if (_shader->get_language() != Shader::SL_Cg) return false;
|
||||||
|
if (_cg_context) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::uses_standard_vertex_arrays
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns true if the shader may need to access
|
||||||
|
// standard vertex attributes as passed by
|
||||||
|
// glVertexPointer and the like.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool CLP(CgShaderContext)::
|
||||||
|
uses_standard_vertex_arrays() {
|
||||||
|
return _uses_standard_vertex_arrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::uses_custom_vertex_arrays
|
||||||
|
// Access: Public
|
||||||
|
// Description: Always true, for now.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool CLP(CgShaderContext)::
|
||||||
|
uses_custom_vertex_arrays() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::uses_custom_texture_bindings
|
||||||
|
// Access: Public
|
||||||
|
// Description: Always true, for now.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool CLP(CgShaderContext)::
|
||||||
|
uses_custom_texture_bindings() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OPENGLES_1
|
||||||
|
|
589
panda/src/glstuff/glCgShaderContext_src.cxx
Executable file
589
panda/src/glstuff/glCgShaderContext_src.cxx
Executable file
@ -0,0 +1,589 @@
|
|||||||
|
// Filename: glCgShaderContext_src.cxx
|
||||||
|
// Created by: jyelon (01Sep05)
|
||||||
|
// Updated by: fperazzi, PandaSE (29Apr10) (updated CLP with note that some
|
||||||
|
// parameter types only supported under Cg)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(HAVE_CG) && !defined(OPENGLES)
|
||||||
|
|
||||||
|
#include "Cg/cgGL.h"
|
||||||
|
|
||||||
|
#include "pStatTimer.h"
|
||||||
|
|
||||||
|
TypeHandle CLP(CgShaderContext)::_type_handle;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define cg_report_errors() { \
|
||||||
|
CGerror err = cgGetError(); \
|
||||||
|
if (err != CG_NO_ERROR) { \
|
||||||
|
GLCAT.error() << __FILE__ ", line " << __LINE__ << ": " << cgGetErrorString(err) << "\n"; \
|
||||||
|
} }
|
||||||
|
#else
|
||||||
|
#define cg_report_errors()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description: xyz
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CLP(CgShaderContext)::
|
||||||
|
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext(s) {
|
||||||
|
_glgsg = glgsg;
|
||||||
|
_uses_standard_vertex_arrays = false;
|
||||||
|
_cg_context = 0;
|
||||||
|
_cg_vprofile = CG_PROFILE_UNKNOWN;
|
||||||
|
_cg_fprofile = CG_PROFILE_UNKNOWN;
|
||||||
|
_cg_gprofile = CG_PROFILE_UNKNOWN;
|
||||||
|
|
||||||
|
nassertv(s->get_language() == Shader::SL_Cg);
|
||||||
|
|
||||||
|
// Ask the shader to compile itself for us and
|
||||||
|
// to give us the resulting Cg program objects.
|
||||||
|
if (!s->cg_compile_for(_glgsg->_shader_caps,
|
||||||
|
_cg_context,
|
||||||
|
_cg_vprogram,
|
||||||
|
_cg_fprogram,
|
||||||
|
_cg_gprogram,
|
||||||
|
_cg_parameter_map)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the program.
|
||||||
|
if (_cg_vprogram != 0) {
|
||||||
|
_cg_vprofile = cgGetProgramProfile(_cg_vprogram);
|
||||||
|
cgGLLoadProgram(_cg_vprogram);
|
||||||
|
CGerror verror = cgGetError();
|
||||||
|
if (verror != CG_NO_ERROR) {
|
||||||
|
const char *str = cgGetErrorString(verror);
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Could not load Cg vertex program: " << s->get_filename(Shader::ST_vertex)
|
||||||
|
<< " (" << cgGetProfileString(_cg_vprofile) << " " << str << ")\n";
|
||||||
|
release_resources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cg_fprogram != 0) {
|
||||||
|
_cg_fprofile = cgGetProgramProfile(_cg_fprogram);
|
||||||
|
cgGLLoadProgram(_cg_fprogram);
|
||||||
|
CGerror ferror = cgGetError();
|
||||||
|
if (ferror != CG_NO_ERROR) {
|
||||||
|
const char *str = cgGetErrorString(ferror);
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Could not load Cg fragment program: " << s->get_filename(Shader::ST_fragment)
|
||||||
|
<< " (" << cgGetProfileString(_cg_fprofile) << " " << str << ")\n";
|
||||||
|
release_resources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cg_gprogram != 0) {
|
||||||
|
_cg_gprofile = cgGetProgramProfile(_cg_gprogram);
|
||||||
|
cgGLLoadProgram(_cg_gprogram);
|
||||||
|
CGerror gerror = cgGetError();
|
||||||
|
if (gerror != CG_NO_ERROR) {
|
||||||
|
const char *str = cgGetErrorString(gerror);
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Could not load Cg geometry program: " << s->get_filename(Shader::ST_geometry)
|
||||||
|
<< " (" << cgGetProfileString(_cg_gprofile) << " " << str << ")\n";
|
||||||
|
release_resources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description: xyz
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
CLP(CgShaderContext)::
|
||||||
|
~CLP(CgShaderContext)() {
|
||||||
|
release_resources();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::release_resources
|
||||||
|
// Access: Public
|
||||||
|
// Description: Should deallocate all system resources (such as
|
||||||
|
// vertex program handles or Cg contexts).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
release_resources() {
|
||||||
|
if (_cg_context) {
|
||||||
|
cgDestroyContext(_cg_context);
|
||||||
|
_cg_context = 0;
|
||||||
|
// Do *NOT* destroy the programs here! It causes problems.
|
||||||
|
// if (_cg_vprogram != 0) cgDestroyProgram(_cg_vprogram);
|
||||||
|
// if (_cg_fprogram != 0) cgDestroyProgram(_cg_fprogram);
|
||||||
|
// if (_cg_gprogram != 0) cgDestroyProgram(_cg_gprogram);
|
||||||
|
_cg_vprogram = 0;
|
||||||
|
_cg_fprogram = 0;
|
||||||
|
_cg_gprogram = 0;
|
||||||
|
_cg_parameter_map.clear();
|
||||||
|
}
|
||||||
|
if (_glgsg) {
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
} else if (glGetError() != GL_NO_ERROR) {
|
||||||
|
GLCAT.error() << "GL error in ShaderContext destructor\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glgsg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::bind
|
||||||
|
// Access: Public
|
||||||
|
// Description: This function is to be called to enable a new
|
||||||
|
// shader. It also initializes all of the shader's
|
||||||
|
// input parameters.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
bind(bool reissue_parameters) {
|
||||||
|
if (reissue_parameters) {
|
||||||
|
// Pass in k-parameters and transform-parameters
|
||||||
|
issue_parameters(Shader::SSD_general);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_cg_context != 0) {
|
||||||
|
// Bind the shaders.
|
||||||
|
if (_cg_vprogram != 0) {
|
||||||
|
cgGLEnableProfile(_cg_vprofile);
|
||||||
|
cgGLBindProgram(_cg_vprogram);
|
||||||
|
}
|
||||||
|
if (_cg_fprogram != 0) {
|
||||||
|
cgGLEnableProfile(_cg_fprofile);
|
||||||
|
cgGLBindProgram(_cg_fprogram);
|
||||||
|
}
|
||||||
|
if (_cg_gprogram != 0) {
|
||||||
|
cgGLEnableProfile(_cg_gprofile);
|
||||||
|
cgGLBindProgram(_cg_gprogram);
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::unbind
|
||||||
|
// Access: Public
|
||||||
|
// Description: This function disables a currently-bound shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
unbind() {
|
||||||
|
if (_cg_context != 0) {
|
||||||
|
if (_cg_vprogram != 0) {
|
||||||
|
cgGLUnbindProgram(_cg_vprofile);
|
||||||
|
cgGLDisableProfile(_cg_vprofile);
|
||||||
|
}
|
||||||
|
if (_cg_fprogram != 0) {
|
||||||
|
cgGLUnbindProgram(_cg_fprofile);
|
||||||
|
cgGLDisableProfile(_cg_fprofile);
|
||||||
|
}
|
||||||
|
if (_cg_gprogram != 0) {
|
||||||
|
cgGLUnbindProgram(_cg_gprofile);
|
||||||
|
cgGLDisableProfile(_cg_gprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::issue_parameters
|
||||||
|
// Access: Public
|
||||||
|
// Description: This function gets called whenever the RenderState
|
||||||
|
// or TransformState has changed, but the Shader
|
||||||
|
// itself has not changed. It loads new values into the
|
||||||
|
// shader's parameters.
|
||||||
|
//
|
||||||
|
// If "altered" is false, that means you promise that
|
||||||
|
// the parameters for this shader context have already
|
||||||
|
// been issued once, and that since the last time the
|
||||||
|
// parameters were issued, no part of the render
|
||||||
|
// state has changed except the external and internal
|
||||||
|
// transforms.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
issue_parameters(int altered) {
|
||||||
|
PStatTimer timer(_glgsg->_draw_set_state_shader_parameters_pcollector);
|
||||||
|
|
||||||
|
if (!valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through _ptr parameters
|
||||||
|
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
|
||||||
|
if (altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
|
||||||
|
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
|
||||||
|
Shader::ShaderPtrData* ptr_data =
|
||||||
|
const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
|
||||||
|
|
||||||
|
if (ptr_data == NULL){ //the input is not contained in ShaderPtrData
|
||||||
|
release_resources();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//check if the data must be shipped to the GPU
|
||||||
|
/*if (!ptr_data->_updated)
|
||||||
|
continue;
|
||||||
|
ptr_data->_updated = false;*/
|
||||||
|
|
||||||
|
//Check if the size of the shader input and ptr_data match
|
||||||
|
int input_size = _ptr._dim[0] * _ptr._dim[1] * _ptr._dim[2];
|
||||||
|
|
||||||
|
// dimension is negative only if the parameter had the (deprecated)k_ prefix.
|
||||||
|
if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) {
|
||||||
|
GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected "
|
||||||
|
<< input_size <<" got " << ptr_data->_size << "\n";
|
||||||
|
release_resources();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
|
||||||
|
|
||||||
|
switch (ptr_data->_type) {
|
||||||
|
case Shader::SPT_float:
|
||||||
|
switch(_ptr._info._class) {
|
||||||
|
case Shader::SAC_scalar: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_vector:
|
||||||
|
switch(_ptr._info._type) {
|
||||||
|
case Shader::SAT_vec1: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec2: cgSetParameter2fv(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec3: cgSetParameter3fv(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec4: cgSetParameter4fv(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
case Shader::SAC_matrix: cgGLSetMatrixParameterfc(p,(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_array: {
|
||||||
|
switch(_ptr._info._subclass) {
|
||||||
|
case Shader::SAC_scalar:
|
||||||
|
cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_vector:
|
||||||
|
switch(_ptr._dim[2]) {
|
||||||
|
case 1: cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
case 2: cgGLSetParameterArray2f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
case 3: cgGLSetParameterArray3f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
case 4: cgGLSetParameterArray4f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
case Shader::SAC_matrix:
|
||||||
|
cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Shader::SPT_double:
|
||||||
|
switch(_ptr._info._class) {
|
||||||
|
case Shader::SAC_scalar: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_vector:
|
||||||
|
switch(_ptr._info._type) {
|
||||||
|
case Shader::SAT_vec1: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec2: cgSetParameter2dv(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec3: cgSetParameter3dv(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAT_vec4: cgSetParameter4dv(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
case Shader::SAC_matrix: cgGLSetMatrixParameterdc(p,(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_array: {
|
||||||
|
switch(_ptr._info._subclass) {
|
||||||
|
case Shader::SAC_scalar:
|
||||||
|
cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
case Shader::SAC_vector:
|
||||||
|
switch(_ptr._dim[2]) {
|
||||||
|
case 1: cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
case 2: cgGLSetParameterArray2d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
case 3: cgGLSetParameterArray3d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
case 4: cgGLSetParameterArray4d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
case Shader::SAC_matrix:
|
||||||
|
cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
|
||||||
|
release_resources();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: this could be much faster if we used deferred parameter setting.
|
||||||
|
|
||||||
|
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
|
||||||
|
if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
|
||||||
|
const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);
|
||||||
|
if (!val) continue;
|
||||||
|
#ifndef STDFLOAT_DOUBLE
|
||||||
|
// In this case, the data is already single-precision.
|
||||||
|
const PN_float32 *data = val->get_data();
|
||||||
|
#else
|
||||||
|
// In this case, we have to convert it.
|
||||||
|
LMatrix4f valf = LCAST(PN_float32, *val);
|
||||||
|
const PN_float32 *data = valf.get_data();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
|
||||||
|
switch (_shader->_mat_spec[i]._piece) {
|
||||||
|
case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue;
|
||||||
|
case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue;
|
||||||
|
case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue;
|
||||||
|
case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue;
|
||||||
|
case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue;
|
||||||
|
case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue;
|
||||||
|
case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue;
|
||||||
|
case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue;
|
||||||
|
case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue;
|
||||||
|
case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue;
|
||||||
|
case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue;
|
||||||
|
case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue;
|
||||||
|
case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue;
|
||||||
|
case Shader::SMP_upper3x3:
|
||||||
|
{
|
||||||
|
LMatrix3f upper3 = val->get_upper_3();
|
||||||
|
GLfc(cgGLSetMatrixParameter)(p, upper3.get_data());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case Shader::SMP_transpose3x3:
|
||||||
|
{
|
||||||
|
LMatrix3f upper3 = val->get_upper_3();
|
||||||
|
GLfr(cgGLSetMatrixParameter)(p, upper3.get_data());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::disable_shader_vertex_arrays
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disable all the vertex arrays used by this shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
disable_shader_vertex_arrays() {
|
||||||
|
if (!valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<(int)_shader->_var_spec.size(); i++) {
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||||
|
if (p == 0) continue;
|
||||||
|
cgGLDisableClientState(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool CLP(CgShaderContext)::
|
||||||
|
update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
||||||
|
if (prev) prev->disable_shader_vertex_arrays();
|
||||||
|
if (!valid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cg_report_errors();
|
||||||
|
|
||||||
|
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||||
|
if (_glgsg->_use_sender) {
|
||||||
|
GLCAT.error() << "immediate mode shaders not implemented yet\n";
|
||||||
|
} else
|
||||||
|
#endif // SUPPORT_IMMEDIATE_MODE
|
||||||
|
{
|
||||||
|
const GeomVertexArrayDataHandle *array_reader;
|
||||||
|
Geom::NumericType numeric_type;
|
||||||
|
int start, stride, num_values;
|
||||||
|
int nvarying = _shader->_var_spec.size();
|
||||||
|
for (int i = 0; i < nvarying; ++i) {
|
||||||
|
if (_cg_parameter_map[_shader->_var_spec[i]._id._seqno] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalName *name = _shader->_var_spec[i]._name;
|
||||||
|
int texslot = _shader->_var_spec[i]._append_uv;
|
||||||
|
if (texslot >= 0 && texslot < _glgsg->_state_texture->get_num_on_stages()) {
|
||||||
|
TextureStage *stage = _glgsg->_state_texture->get_on_stage(texslot);
|
||||||
|
InternalName *texname = stage->get_texcoord_name();
|
||||||
|
|
||||||
|
if (name == InternalName::get_texcoord()) {
|
||||||
|
name = texname;
|
||||||
|
} else if (texname != InternalName::get_texcoord()) {
|
||||||
|
name = name->append(texname->get_basename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_glgsg->_data_reader->get_array_info(name,
|
||||||
|
array_reader, num_values, numeric_type,
|
||||||
|
start, stride)) {
|
||||||
|
const unsigned char *client_pointer;
|
||||||
|
if (!_glgsg->setup_array_data(client_pointer, array_reader, force)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||||
|
cgGLSetParameterPointer(p,
|
||||||
|
num_values, _glgsg->get_numeric_type(numeric_type),
|
||||||
|
stride, client_pointer + start);
|
||||||
|
cgGLEnableClientState(p);
|
||||||
|
} else {
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||||
|
cgGLDisableClientState(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::disable_shader_texture_bindings
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disable all the texture bindings used by this shader.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
disable_shader_texture_bindings() {
|
||||||
|
if (!valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef OPENGLES_2
|
||||||
|
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
||||||
|
if (p == 0) continue;
|
||||||
|
int texunit = cgGetParameterResourceIndex(p);
|
||||||
|
_glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
|
||||||
|
#ifndef OPENGLES
|
||||||
|
glBindTexture(GL_TEXTURE_1D, 0);
|
||||||
|
#endif // OPENGLES
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
#ifndef OPENGLES_1
|
||||||
|
if (_glgsg->_supports_3d_texture) {
|
||||||
|
glBindTexture(GL_TEXTURE_3D, 0);
|
||||||
|
}
|
||||||
|
#endif // OPENGLES_1
|
||||||
|
#ifndef OPENGLES
|
||||||
|
if (_glgsg->_supports_2d_texture_array) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (_glgsg->_supports_cube_map) {
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
}
|
||||||
|
// This is probably faster - but maybe not as safe?
|
||||||
|
// cgGLDisableTextureParameter(p);
|
||||||
|
}
|
||||||
|
#endif // OPENGLES_2
|
||||||
|
_stage_offset = 0;
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: GLCgShaderContext::update_shader_texture_bindings
|
||||||
|
// Access: Public
|
||||||
|
// Description: Disables all texture bindings used by the previous
|
||||||
|
// shader, then enables all the texture bindings needed
|
||||||
|
// by this shader. Extracts the relevant vertex array
|
||||||
|
// data from the gsg.
|
||||||
|
// The current implementation is inefficient, because
|
||||||
|
// it may unnecessarily disable textures then immediately
|
||||||
|
// reenable them. We may optimize this someday.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CLP(CgShaderContext)::
|
||||||
|
update_shader_texture_bindings(ShaderContext *prev) {
|
||||||
|
if (prev) {
|
||||||
|
prev->disable_shader_texture_bindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We get the TextureAttrib directly from the _target_rs, not the
|
||||||
|
// filtered TextureAttrib in _target_texture.
|
||||||
|
const TextureAttrib *texattrib = DCAST(TextureAttrib, _glgsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
|
||||||
|
nassertv(texattrib != (TextureAttrib *)NULL);
|
||||||
|
_stage_offset = texattrib->get_num_on_stages();
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
|
||||||
|
InternalName *id = _shader->_tex_spec[i]._name;
|
||||||
|
|
||||||
|
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
|
||||||
|
if (p == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int texunit = cgGetParameterResourceIndex(p);
|
||||||
|
|
||||||
|
Texture *tex = 0;
|
||||||
|
int view = _glgsg->get_current_tex_view_offset();
|
||||||
|
if (id != 0) {
|
||||||
|
const ShaderInput *input = _glgsg->_target_shader->get_shader_input(id);
|
||||||
|
tex = input->get_texture();
|
||||||
|
} else {
|
||||||
|
if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
|
||||||
|
tex = texattrib->get_on_texture(stage);
|
||||||
|
view += stage->get_tex_view_offset();
|
||||||
|
}
|
||||||
|
if (_shader->_tex_spec[i]._suffix != 0) {
|
||||||
|
// The suffix feature is inefficient. It is a temporary hack.
|
||||||
|
if (tex == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tex = tex->load_related(_shader->_tex_spec[i]._suffix);
|
||||||
|
}
|
||||||
|
if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
|
||||||
|
|
||||||
|
TextureContext *tc = tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg);
|
||||||
|
if (tc == (TextureContext*)NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum target = _glgsg->get_texture_target(tex->get_texture_type());
|
||||||
|
if (target == GL_NONE) {
|
||||||
|
// Unsupported texture mode.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glgsg->update_texture(tc, false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cg_report_errors();
|
||||||
|
_glgsg->report_my_gl_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OPENGLES_1
|
92
panda/src/glstuff/glCgShaderContext_src.h
Executable file
92
panda/src/glstuff/glCgShaderContext_src.h
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
// Filename: glShaderContext_src.h
|
||||||
|
// Created by: jyelon (01Sep05)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the revised BSD
|
||||||
|
// license. You should have received a copy of this license along
|
||||||
|
// with this source code in a file named "LICENSE."
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined(HAVE_CG) && !defined(OPENGLES)
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
#include "string_utils.h"
|
||||||
|
#include "internalName.h"
|
||||||
|
#include "shader.h"
|
||||||
|
#include "shaderContext.h"
|
||||||
|
#include "deletedChain.h"
|
||||||
|
|
||||||
|
#include <Cg/cg.h>
|
||||||
|
|
||||||
|
class CLP(GraphicsStateGuardian);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : GLShaderContext
|
||||||
|
// Description : xyz
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_GL CLP(CgShaderContext) : public ShaderContext {
|
||||||
|
public:
|
||||||
|
friend class CLP(GraphicsStateGuardian);
|
||||||
|
|
||||||
|
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
|
||||||
|
~CLP(CgShaderContext)();
|
||||||
|
ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
|
||||||
|
|
||||||
|
INLINE bool valid(void);
|
||||||
|
void bind(bool reissue_parameters = true);
|
||||||
|
void unbind();
|
||||||
|
void issue_parameters(int altered);
|
||||||
|
void disable_shader_vertex_arrays();
|
||||||
|
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
|
||||||
|
void disable_shader_texture_bindings();
|
||||||
|
void update_shader_texture_bindings(ShaderContext *prev);
|
||||||
|
|
||||||
|
INLINE bool uses_standard_vertex_arrays(void);
|
||||||
|
INLINE bool uses_custom_vertex_arrays(void);
|
||||||
|
INLINE bool uses_custom_texture_bindings(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CGcontext _cg_context;
|
||||||
|
CGprogram _cg_vprogram;
|
||||||
|
CGprogram _cg_fprogram;
|
||||||
|
CGprogram _cg_gprogram;
|
||||||
|
CGprofile _cg_vprofile;
|
||||||
|
CGprofile _cg_fprofile;
|
||||||
|
CGprofile _cg_gprofile;
|
||||||
|
|
||||||
|
pvector <CGparameter> _cg_parameter_map;
|
||||||
|
|
||||||
|
int _stage_offset;
|
||||||
|
CLP(GraphicsStateGuardian) *_glgsg;
|
||||||
|
|
||||||
|
bool _uses_standard_vertex_arrays;
|
||||||
|
|
||||||
|
void release_resources();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
TypedObject::init_type();
|
||||||
|
register_type(_type_handle, CLASSPREFIX_QUOTED "CgShaderContext",
|
||||||
|
TypedObject::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 "glCgShaderContext_src.I"
|
||||||
|
|
||||||
|
#endif // OPENGLES_1
|
||||||
|
|
@ -2431,17 +2431,17 @@ end_frame(Thread *current_thread) {
|
|||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
// This breaks shaders across multiple regions.
|
// This breaks shaders across multiple regions.
|
||||||
if (_vertex_array_shader_context != 0) {
|
if (_vertex_array_shader_context != 0) {
|
||||||
_vertex_array_shader_context->disable_shader_vertex_arrays(this);
|
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||||
_vertex_array_shader = (Shader *)NULL;
|
_vertex_array_shader = (Shader *)NULL;
|
||||||
_vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
|
_vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
}
|
}
|
||||||
if (_texture_binding_shader_context != 0) {
|
if (_texture_binding_shader_context != 0) {
|
||||||
_texture_binding_shader_context->disable_shader_texture_bindings(this);
|
_texture_binding_shader_context->disable_shader_texture_bindings();
|
||||||
_texture_binding_shader = (Shader *)NULL;
|
_texture_binding_shader = (Shader *)NULL;
|
||||||
_texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
|
_texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
}
|
}
|
||||||
if (_current_shader_context != 0) {
|
if (_current_shader_context != 0) {
|
||||||
_current_shader_context->unbind(this);
|
_current_shader_context->unbind();
|
||||||
_current_shader = (Shader *)NULL;
|
_current_shader = (Shader *)NULL;
|
||||||
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
_current_shader_context = (CLP(ShaderContext) *)NULL;
|
||||||
}
|
}
|
||||||
@ -2737,7 +2737,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||||||
if (_current_shader_context == 0) {
|
if (_current_shader_context == 0) {
|
||||||
// No shader.
|
// No shader.
|
||||||
if (_vertex_array_shader_context != 0) {
|
if (_vertex_array_shader_context != 0) {
|
||||||
_vertex_array_shader_context->disable_shader_vertex_arrays(this);
|
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||||
}
|
}
|
||||||
if (!update_standard_vertex_arrays(force)) {
|
if (!update_standard_vertex_arrays(force)) {
|
||||||
return false;
|
return false;
|
||||||
@ -2759,11 +2759,11 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||||||
if (_current_shader_context->uses_custom_vertex_arrays()) {
|
if (_current_shader_context->uses_custom_vertex_arrays()) {
|
||||||
// The current shader also uses custom vertex arrays.
|
// The current shader also uses custom vertex arrays.
|
||||||
if (!_current_shader_context->
|
if (!_current_shader_context->
|
||||||
update_shader_vertex_arrays(_vertex_array_shader_context, this, force)) {
|
update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_vertex_array_shader_context->disable_shader_vertex_arrays(this);
|
_vertex_array_shader_context->disable_shader_vertex_arrays();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3834,29 +3834,48 @@ release_geom(GeomContext *gc) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLGraphicsStateGuardian::prepare_shader
|
// Function: GLGraphicsStateGuardian::prepare_shader
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: yadda.
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
ShaderContext *CLP(GraphicsStateGuardian)::
|
ShaderContext *CLP(GraphicsStateGuardian)::
|
||||||
prepare_shader(Shader *se) {
|
prepare_shader(Shader *se) {
|
||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
|
ShaderContext *result = NULL;
|
||||||
if (result->valid()) return result;
|
|
||||||
delete result;
|
switch (se->get_language()) {
|
||||||
|
case Shader::SL_GLSL:
|
||||||
|
result = new CLP(ShaderContext)(this, se);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if defined(HAVE_CG) && !defined(OPENGLES)
|
||||||
|
case Shader::SL_Cg:
|
||||||
|
result = new CLP(CgShaderContext)(this, se);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
GLCAT.error()
|
||||||
|
<< "Tried to load shader with unsupported shader language!\n";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result->valid()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
#endif // OPENGLES_1
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLGraphicsStateGuardian::release_shader
|
// Function: GLGraphicsStateGuardian::release_shader
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
// Description: yadda.
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CLP(GraphicsStateGuardian)::
|
void CLP(GraphicsStateGuardian)::
|
||||||
release_shader(ShaderContext *sc) {
|
release_shader(ShaderContext *sc) {
|
||||||
#ifndef OPENGLES_1
|
delete sc;
|
||||||
CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
|
|
||||||
delete gsc;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -4807,7 +4826,7 @@ do_issue_transform() {
|
|||||||
|
|
||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
if (_current_shader_context) {
|
if (_current_shader_context) {
|
||||||
_current_shader_context->issue_parameters(this, Shader::SSD_transform);
|
_current_shader_context->issue_parameters(Shader::SSD_transform);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -4868,7 +4887,7 @@ do_issue_shader(bool state_has_changed) {
|
|||||||
|
|
||||||
if (context == 0 || (context->valid() == false)) {
|
if (context == 0 || (context->valid() == false)) {
|
||||||
if (_current_shader_context != 0) {
|
if (_current_shader_context != 0) {
|
||||||
_current_shader_context->unbind(this);
|
_current_shader_context->unbind();
|
||||||
_current_shader = 0;
|
_current_shader = 0;
|
||||||
_current_shader_context = 0;
|
_current_shader_context = 0;
|
||||||
}
|
}
|
||||||
@ -4877,19 +4896,19 @@ do_issue_shader(bool state_has_changed) {
|
|||||||
// 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 (_current_shader_context != 0) {
|
if (_current_shader_context != 0) {
|
||||||
_current_shader_context->unbind(this);
|
_current_shader_context->unbind();
|
||||||
}
|
}
|
||||||
context->bind(this);
|
context->bind();
|
||||||
_current_shader = shader;
|
_current_shader = shader;
|
||||||
_current_shader_context = context;
|
_current_shader_context = context;
|
||||||
context->issue_parameters(this, Shader::SSD_shaderinputs);
|
context->issue_parameters(Shader::SSD_shaderinputs);
|
||||||
} else {
|
} else {
|
||||||
#ifdef OPENGLES_2
|
#ifdef OPENGLES_2
|
||||||
context->bind(this, false);
|
context->bind(false);
|
||||||
#endif
|
#endif
|
||||||
if (state_has_changed) {
|
if (state_has_changed) {
|
||||||
// Use the same shader as before, but with new input arguments.
|
// Use the same shader as before, but with new input arguments.
|
||||||
context->issue_parameters(this, Shader::SSD_shaderinputs);
|
context->issue_parameters(Shader::SSD_shaderinputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7856,8 +7875,8 @@ set_state_and_transform(const RenderState *target,
|
|||||||
_state_mask.set_bit(color_scale_slot);
|
_state_mask.set_bit(color_scale_slot);
|
||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
if (_current_shader_context) {
|
if (_current_shader_context) {
|
||||||
_current_shader_context->issue_parameters(this, Shader::SSD_color);
|
_current_shader_context->issue_parameters(Shader::SSD_color);
|
||||||
_current_shader_context->issue_parameters(this, Shader::SSD_colorscale);
|
_current_shader_context->issue_parameters(Shader::SSD_colorscale);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -8008,7 +8027,7 @@ set_state_and_transform(const RenderState *target,
|
|||||||
_state_mask.set_bit(material_slot);
|
_state_mask.set_bit(material_slot);
|
||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
if (_current_shader_context) {
|
if (_current_shader_context) {
|
||||||
_current_shader_context->issue_parameters(this, Shader::SSD_material);
|
_current_shader_context->issue_parameters(Shader::SSD_material);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -8037,7 +8056,7 @@ set_state_and_transform(const RenderState *target,
|
|||||||
_state_mask.set_bit(fog_slot);
|
_state_mask.set_bit(fog_slot);
|
||||||
#ifndef OPENGLES_1
|
#ifndef OPENGLES_1
|
||||||
if (_current_shader_context) {
|
if (_current_shader_context) {
|
||||||
_current_shader_context->issue_parameters(this, Shader::SSD_fog);
|
_current_shader_context->issue_parameters(Shader::SSD_fog);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -8136,16 +8155,16 @@ do_issue_texture() {
|
|||||||
if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
|
if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
|
||||||
// No shader, or a non-Cg shader.
|
// No shader, or a non-Cg shader.
|
||||||
if (_texture_binding_shader_context != 0) {
|
if (_texture_binding_shader_context != 0) {
|
||||||
_texture_binding_shader_context->disable_shader_texture_bindings(this);
|
_texture_binding_shader_context->disable_shader_texture_bindings();
|
||||||
}
|
}
|
||||||
update_standard_texture_bindings();
|
update_standard_texture_bindings();
|
||||||
} else {
|
} else {
|
||||||
if (_texture_binding_shader_context == 0) {
|
if (_texture_binding_shader_context == 0) {
|
||||||
disable_standard_texture_bindings();
|
disable_standard_texture_bindings();
|
||||||
_current_shader_context->update_shader_texture_bindings(NULL,this);
|
_current_shader_context->update_shader_texture_bindings(NULL);
|
||||||
} else {
|
} else {
|
||||||
_current_shader_context->
|
_current_shader_context->
|
||||||
update_shader_texture_bindings(_texture_binding_shader_context,this);
|
update_shader_texture_bindings(_texture_binding_shader_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,6 +775,7 @@ private:
|
|||||||
friend class CLP(VertexBufferContext);
|
friend class CLP(VertexBufferContext);
|
||||||
friend class CLP(IndexBufferContext);
|
friend class CLP(IndexBufferContext);
|
||||||
friend class CLP(ShaderContext);
|
friend class CLP(ShaderContext);
|
||||||
|
friend class CLP(CgShaderContext);
|
||||||
friend class CLP(GraphicsBuffer);
|
friend class CLP(GraphicsBuffer);
|
||||||
friend class CLP(OcclusionQueryContext);
|
friend class CLP(OcclusionQueryContext);
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef OPENGLES_1
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: GLShaderContext::valid
|
// Function: GLShaderContext::valid
|
||||||
@ -26,11 +25,10 @@
|
|||||||
INLINE bool CLP(ShaderContext)::
|
INLINE bool CLP(ShaderContext)::
|
||||||
valid() {
|
valid() {
|
||||||
if (_shader->get_error_flag()) return false;
|
if (_shader->get_error_flag()) return false;
|
||||||
if (_shader->get_language() == Shader::SL_none) return false;
|
if (_shader->get_language() != Shader::SL_GLSL) {
|
||||||
#if defined(HAVE_CG) && !defined(OPENGLES)
|
return false;
|
||||||
if (_cg_context) return true;
|
}
|
||||||
#endif
|
if (_glsl_program != 0) {
|
||||||
if (_shader->get_language() == Shader::SL_GLSL && _glsl_program != 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -67,6 +65,3 @@ INLINE bool CLP(ShaderContext)::
|
|||||||
uses_custom_texture_bindings() {
|
uses_custom_texture_bindings() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // OPENGLES_1
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,10 +21,6 @@
|
|||||||
#include "shaderContext.h"
|
#include "shaderContext.h"
|
||||||
#include "deletedChain.h"
|
#include "deletedChain.h"
|
||||||
|
|
||||||
#if defined(HAVE_CG) && !defined(OPENGLES)
|
|
||||||
#include <Cg/cg.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CLP(GraphicsStateGuardian);
|
class CLP(GraphicsStateGuardian);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -34,40 +30,25 @@ class CLP(GraphicsStateGuardian);
|
|||||||
class EXPCL_GL CLP(ShaderContext) : public ShaderContext {
|
class EXPCL_GL CLP(ShaderContext) : public ShaderContext {
|
||||||
public:
|
public:
|
||||||
friend class CLP(GraphicsStateGuardian);
|
friend class CLP(GraphicsStateGuardian);
|
||||||
typedef CLP(GraphicsStateGuardian) GSG;
|
|
||||||
|
|
||||||
CLP(ShaderContext)(Shader *s, GSG *gsg);
|
CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
|
||||||
~CLP(ShaderContext)();
|
~CLP(ShaderContext)();
|
||||||
ALLOC_DELETED_CHAIN(CLP(ShaderContext));
|
ALLOC_DELETED_CHAIN(CLP(ShaderContext));
|
||||||
|
|
||||||
INLINE bool valid(void);
|
INLINE bool valid(void);
|
||||||
void bind(GSG *gsg, bool reissue_parameters = true);
|
void bind(bool reissue_parameters = true);
|
||||||
void unbind(GSG *gsg);
|
void unbind();
|
||||||
void issue_parameters(GSG *gsg, int altered);
|
void issue_parameters(int altered);
|
||||||
void disable_shader_vertex_arrays(GSG *gsg);
|
void disable_shader_vertex_arrays();
|
||||||
bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
|
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
|
||||||
bool force);
|
void disable_shader_texture_bindings();
|
||||||
void disable_shader_texture_bindings(GSG *gsg);
|
void update_shader_texture_bindings(ShaderContext *prev);
|
||||||
void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
|
|
||||||
|
|
||||||
INLINE bool uses_standard_vertex_arrays(void);
|
INLINE bool uses_standard_vertex_arrays(void);
|
||||||
INLINE bool uses_custom_vertex_arrays(void);
|
INLINE bool uses_custom_vertex_arrays(void);
|
||||||
INLINE bool uses_custom_texture_bindings(void);
|
INLINE bool uses_custom_texture_bindings(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if defined(HAVE_CG) && !defined(OPENGLES)
|
|
||||||
CGcontext _cg_context;
|
|
||||||
CGprogram _cg_vprogram;
|
|
||||||
CGprogram _cg_fprogram;
|
|
||||||
CGprogram _cg_gprogram;
|
|
||||||
CGprofile _cg_vprofile;
|
|
||||||
CGprofile _cg_fprofile;
|
|
||||||
CGprofile _cg_gprofile;
|
|
||||||
|
|
||||||
pvector <CGparameter> _cg_parameter_map;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLuint _glsl_program;
|
GLuint _glsl_program;
|
||||||
GLuint _glsl_vshader;
|
GLuint _glsl_vshader;
|
||||||
GLuint _glsl_fshader;
|
GLuint _glsl_fshader;
|
||||||
@ -81,18 +62,16 @@ private:
|
|||||||
pvector<CPT(InternalName)> _glsl_img_inputs;
|
pvector<CPT(InternalName)> _glsl_img_inputs;
|
||||||
|
|
||||||
int _stage_offset;
|
int _stage_offset;
|
||||||
// Avoid using this! It merely exists so the
|
CLP(GraphicsStateGuardian) *_glgsg;
|
||||||
// destructor has access to the extension functions.
|
|
||||||
WPT(GSG) _last_gsg;
|
|
||||||
|
|
||||||
bool _uses_standard_vertex_arrays;
|
bool _uses_standard_vertex_arrays;
|
||||||
|
|
||||||
void glsl_report_shader_errors(GSG *gsg, unsigned int shader);
|
void glsl_report_shader_errors(unsigned int shader);
|
||||||
void glsl_report_program_errors(GSG *gsg, unsigned int program);
|
void glsl_report_program_errors(unsigned int program);
|
||||||
unsigned int glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type);
|
unsigned int glsl_compile_entry_point(Shader::ShaderType type);
|
||||||
bool glsl_compile_shader(GSG *gsg);
|
bool glsl_compile_shader();
|
||||||
bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
|
bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
|
||||||
void release_resources(GSG *gsg);
|
void release_resources();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
@ -115,4 +94,3 @@ private:
|
|||||||
#include "glShaderContext_src.I"
|
#include "glShaderContext_src.I"
|
||||||
|
|
||||||
#endif // OPENGLES_1
|
#endif // OPENGLES_1
|
||||||
|
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "glGeomContext_src.cxx"
|
#include "glGeomContext_src.cxx"
|
||||||
#include "glGeomMunger_src.cxx"
|
#include "glGeomMunger_src.cxx"
|
||||||
#include "glShaderContext_src.cxx"
|
#include "glShaderContext_src.cxx"
|
||||||
|
#include "glCgShaderContext_src.cxx"
|
||||||
#include "glImmediateModeSender_src.cxx"
|
#include "glImmediateModeSender_src.cxx"
|
||||||
#include "glGraphicsBuffer_src.cxx"
|
#include "glGraphicsBuffer_src.cxx"
|
||||||
#include "glGraphicsStateGuardian_src.cxx"
|
#include "glGraphicsStateGuardian_src.cxx"
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "glGeomContext_src.h"
|
#include "glGeomContext_src.h"
|
||||||
#include "glGeomMunger_src.h"
|
#include "glGeomMunger_src.h"
|
||||||
#include "glShaderContext_src.h"
|
#include "glShaderContext_src.h"
|
||||||
|
#include "glCgShaderContext_src.h"
|
||||||
#include "glImmediateModeSender_src.h"
|
#include "glImmediateModeSender_src.h"
|
||||||
#include "glGraphicsBuffer_src.h"
|
#include "glGraphicsBuffer_src.h"
|
||||||
#include "glGraphicsStateGuardian_src.h"
|
#include "glGraphicsStateGuardian_src.h"
|
||||||
|
@ -36,6 +36,19 @@ class EXPCL_PANDA_GOBJ ShaderContext: public SavedContext {
|
|||||||
public:
|
public:
|
||||||
INLINE ShaderContext(Shader *se);
|
INLINE ShaderContext(Shader *se);
|
||||||
|
|
||||||
|
INLINE virtual bool valid() { return false; }
|
||||||
|
INLINE virtual void bind(bool reissue_parameters = true) {};
|
||||||
|
INLINE virtual void unbind() {};
|
||||||
|
INLINE virtual void issue_parameters(int altered) {};
|
||||||
|
INLINE virtual void disable_shader_vertex_arrays() {};
|
||||||
|
INLINE virtual bool update_shader_vertex_arrays(ShaderContext *prev, bool force) { return false; };
|
||||||
|
INLINE virtual void disable_shader_texture_bindings() {};
|
||||||
|
INLINE virtual void update_shader_texture_bindings(ShaderContext *prev) {};
|
||||||
|
|
||||||
|
INLINE virtual bool uses_standard_vertex_arrays(void) { return true; };
|
||||||
|
INLINE virtual bool uses_custom_vertex_arrays(void) { return false; };
|
||||||
|
INLINE virtual bool uses_custom_texture_bindings(void) { return false; };
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE Shader *get_shader() const;
|
INLINE Shader *get_shader() const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user