15 #include "dxGraphicsStateGuardian9.h" 16 #include "dxShaderContext9.h" 17 #include "dxVertexBufferContext9.h" 23 #include <sys/types.h> 27 #include <Cg/cgD3D9.h> 30 #define DEBUG_SHADER 0 41 _vertex_element_array = NULL;
42 _vertex_declaration = NULL;
44 _num_bound_streams = 0;
46 _name = s->get_filename();
51 if (s->get_language() == Shader::SL_Cg) {
54 if (!s->cg_compile_for(gsg->_shader_caps, context,
55 _cg_program, _cg_parameter_map)) {
60 DWORD assembly_flags = 0;
62 assembly_flags |= D3DXSHADER_DEBUG;
67 hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
70 <<
"cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
72 CGerror error = cgGetError();
73 if (error != CG_NO_ERROR) {
74 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
91 if ( _vertex_declaration != NULL ) {
92 _vertex_declaration->Release();
93 _vertex_declaration = NULL;
96 if ( _vertex_element_array != NULL ) {
97 delete _vertex_element_array;
98 _vertex_element_array = NULL;
157 release_resources() {
160 cgDestroyProgram(_cg_program);
162 _cg_parameter_map.clear();
181 bool bind_state =
false;
187 gsg -> _last_fvf = 0;
190 issue_parameters(gsg, Shader::SSD_general);
196 hr = cgD3D9BindProgram(_cg_program);
198 dxgsg9_cat.error() <<
"cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
200 CGerror error = cgGetError();
201 if (error != CG_NO_ERROR) {
202 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
224 hr = cgD3D9UnbindProgram(_cg_program);
227 <<
"cgD3D9UnbindProgram failed " << D3DERRORSTRING(hr);
250 PN_stdfloat *global_data = 0;
251 ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0;
252 InternalName *global_internal_name_0 = 0;
253 InternalName *global_internal_name_1 = 0;
257 issue_parameters(
GSG *gsg,
int altered) {
262 for (
size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
265 if (altered & (spec._dep[0] | spec._dep[1])) {
268 if (ptr_data == NULL) {
275 int input_size = min(abs(spec._dim[0] * spec._dim[1] * spec._dim[2]), ptr_data->_size);
277 CGparameter p = _cg_parameter_map[spec._id._seqno];
278 switch (ptr_data->_type) {
279 case Shader::SPT_int:
280 cgSetParameterValueic(p, input_size, (
int *)ptr_data->_ptr);
283 case Shader::SPT_double:
284 cgSetParameterValuedc(p, input_size, (
double *)ptr_data->_ptr);
287 case Shader::SPT_float:
288 cgSetParameterValuefc(p, input_size, (
float *)ptr_data->_ptr);
293 << spec._id._name <<
": unrecognized parameter type\n";
300 for (
size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
303 if (altered & (spec._dep[0] | spec._dep[1])) {
304 CGparameter p = _cg_parameter_map[spec._id._seqno];
312 LMatrix4f temp_matrix = LCAST(
float, *val);
321 global_data = (PN_stdfloat *) data;
322 global_shader_mat_spec = &spec;
323 global_internal_name_0 = global_shader_mat_spec -> _arg [0];
324 global_internal_name_1 = global_shader_mat_spec -> _arg [1];
327 switch (spec._piece) {
328 case Shader::SMP_whole:
330 temp_matrix.transpose_in_place();
333 hr = cgD3D9SetUniform (p, data);
336 case Shader::SMP_transpose:
338 hr = cgD3D9SetUniform (p, data);
341 case Shader::SMP_row0:
342 hr = cgD3D9SetUniform (p, data + 0);
344 case Shader::SMP_row1:
345 hr = cgD3D9SetUniform (p, data + 4);
347 case Shader::SMP_row2:
348 hr = cgD3D9SetUniform (p, data + 8);
350 case Shader::SMP_row3x1:
351 case Shader::SMP_row3x2:
352 case Shader::SMP_row3x3:
353 case Shader::SMP_row3:
354 hr = cgD3D9SetUniform (p, data + 12);
357 case Shader::SMP_col0:
358 v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
359 hr = cgD3D9SetUniform (p, v);
361 case Shader::SMP_col1:
362 v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
363 hr = cgD3D9SetUniform (p, v);
365 case Shader::SMP_col2:
366 v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
367 hr = cgD3D9SetUniform (p, v);
369 case Shader::SMP_col3:
370 v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
371 hr = cgD3D9SetUniform (p, v);
376 <<
"issue_parameters ( ) SMP parameter type not implemented " << spec._piece <<
"\n";
381 string name =
"unnamed";
384 name = spec._arg[0]->get_basename();
388 <<
"NAME " << name <<
"\n" <<
"MAT TYPE " << spec._piece
389 <<
" cgD3D9SetUniform failed " << D3DERRORSTRING(hr);
391 CGerror error = cgGetError();
392 if (error != CG_NO_ERROR) {
393 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
409 disable_shader_vertex_arrays(
GSG *gsg) {
410 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
412 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index )
414 device->SetStreamSource( array_index, NULL, 0, 0 );
416 _num_bound_streams = 0;
432 if (prev) prev->disable_shader_vertex_arrays(gsg);
438 #ifdef SUPPORT_IMMEDIATE_MODE 444 #endif // SUPPORT_IMMEDIATE_MODE 446 int nvarying = _shader->_var_spec.size();
447 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
451 if ( _vertex_element_array != NULL ) {
452 delete _vertex_element_array;
463 int number_of_arrays = gsg->_data_reader->get_num_arrays();
464 for (
int array_index = 0; array_index < number_of_arrays; ++array_index ) {
466 gsg->_data_reader->get_array_reader( array_index );
467 if ( array_reader == NULL ) {
468 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
472 for (
int var_index = 0; var_index < nvarying; ++var_index ) {
473 CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
476 "No parameter in map for parameter " << var_index <<
477 " (probably optimized away)\n";
481 InternalName *name = _shader->_var_spec[var_index]._name;
485 int texslot = _shader->_var_spec[var_index]._append_uv;
486 if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
487 TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
489 if (name == InternalName::get_texcoord()) {
491 }
else if (texname != InternalName::get_texcoord()) {
492 name = name->append(texname->get_basename());
497 Geom::NumericType numeric_type;
501 if ( gsg->_data_reader->get_array_info( name,
502 param_array_reader, num_values, numeric_type,
503 start, stride ) == false ) {
509 dxgsg9_cat.info() <<
"Geometry contains no data for shader parameter " << *name <<
"\n";
514 if ( param_array_reader != array_reader ) {
518 const char* semantic = cgGetParameterSemantic( p );
519 if ( semantic == NULL ) {
520 dxgsg9_cat.error() <<
"Unable to retrieve semantic for parameter " << var_index <<
"\n";
524 if ( strncmp( semantic,
"POSITION", strlen(
"POSITION" ) ) == 0 ) {
525 if (numeric_type == Geom::NT_float32) {
526 switch (num_values) {
528 vertex_element_array->add_position_xyz_vertex_element(array_index, start);
531 vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
534 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex coordinate elements " << num_values <<
"\n";
538 dxgsg9_cat.error() <<
"VE ERROR: invalid vertex type " << numeric_type <<
"\n";
540 }
else if ( strncmp( semantic,
"TEXCOORD", strlen(
"TEXCOORD" ) ) == 0 ) {
541 int slot = atoi( semantic + strlen(
"TEXCOORD" ) );
542 if (numeric_type == Geom::NT_float32) {
543 switch (num_values) {
545 vertex_element_array->add_u_vertex_element(array_index, start, slot);
548 vertex_element_array->add_uv_vertex_element(array_index, start, slot);
551 vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
554 vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
557 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<
"\n";
561 dxgsg9_cat.error() <<
"VE ERROR: invalid texture coordinate type " << numeric_type <<
"\n";
563 }
else if ( strncmp( semantic,
"COLOR", strlen(
"COLOR" ) ) == 0 ) {
564 if (numeric_type == Geom::NT_packed_dcba ||
565 numeric_type == Geom::NT_packed_dabc ||
566 numeric_type == Geom::NT_uint8) {
567 switch (num_values) {
569 vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
572 dxgsg9_cat.error() <<
"VE ERROR: invalid color coordinates " << num_values <<
"\n";
576 dxgsg9_cat.error() <<
"VE ERROR: invalid color type " << numeric_type <<
"\n";
578 }
else if ( strncmp( semantic,
"NORMAL", strlen(
"NORMAL" ) ) == 0 ) {
579 if (numeric_type == Geom::NT_float32) {
580 switch (num_values) {
582 vertex_element_array->add_normal_vertex_element(array_index, start);
585 dxgsg9_cat.error() <<
"VE ERROR: invalid number of normal coordinate elements " << num_values <<
"\n";
589 dxgsg9_cat.error() <<
"VE ERROR: invalid normal type " << numeric_type <<
"\n";
591 }
else if ( strncmp( semantic,
"BINORMAL", strlen(
"BINORMAL" ) ) == 0 ) {
592 if (numeric_type == Geom::NT_float32) {
593 switch (num_values) {
595 vertex_element_array->add_binormal_vertex_element(array_index, start);
598 dxgsg9_cat.error() <<
"VE ERROR: invalid number of binormal coordinate elements " << num_values <<
"\n";
602 dxgsg9_cat.error() <<
"VE ERROR: invalid binormal type " << numeric_type <<
"\n";
604 }
else if ( strncmp( semantic,
"TANGENT", strlen(
"TANGENT" ) ) == 0 ) {
605 if (numeric_type == Geom::NT_float32) {
606 switch (num_values) {
608 vertex_element_array->add_tangent_vertex_element(array_index, start);
611 dxgsg9_cat.error() <<
"VE ERROR: invalid number of tangent coordinate elements " << num_values <<
"\n";
615 dxgsg9_cat.error() <<
"VE ERROR: invalid tangent type " << numeric_type <<
"\n";
618 dxgsg9_cat.error() <<
"Unsupported semantic " << semantic <<
" for parameter " << var_index <<
"\n";
625 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
630 const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
631 hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
633 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
637 _num_bound_streams = number_of_arrays;
639 if (( _vertex_element_array != NULL ) &&
640 ( _vertex_element_array->add_end_vertex_element() != false )) {
641 if (dxgsg9_cat.is_debug()) {
645 if (cgD3D9ValidateVertexDeclaration(_cg_program,
646 _vertex_element_array->_vertex_element_array) == CG_TRUE) {
647 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration succeeded\n";
649 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration failed\n";
654 if ( _vertex_declaration != NULL ) {
655 _vertex_declaration->Release();
656 _vertex_declaration = NULL;
659 hr = device->CreateVertexDeclaration( _vertex_element_array->_vertex_element_array,
660 &_vertex_declaration );
662 dxgsg9_cat.error() <<
"CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
664 hr = device->SetVertexDeclaration( _vertex_declaration );
666 dxgsg9_cat.error() <<
"SetVertexDeclaration failed" << D3DERRORSTRING(hr);
670 dxgsg9_cat.error() <<
"VertexElementArray creation failed\n";
684 disable_shader_texture_bindings(
GSG *gsg)
688 for (
int i=0; i<(int)_shader->_tex_spec.size(); i++) {
689 CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
693 int texunit = cgGetParameterResourceIndex(p);
697 hr = gsg -> _d3d_device -> SetTexture (texunit, NULL);
703 << D3DERRORSTRING(hr);
724 prev->disable_shader_texture_bindings(gsg);
729 for (
size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
731 CGparameter p = _cg_parameter_map[spec._id._seqno];
737 int view = gsg->get_current_tex_view_offset();
740 if (spec._name != NULL) {
741 const ShaderInput *input = gsg->_target_shader->get_shader_input(spec._name);
742 tex = input->get_texture();
743 sampler = input->get_sampler();
760 if (spec._suffix != 0) {
777 int texunit = cgGetParameterResourceIndex(p);
785 void assemble_shader_test(
char *file_path)
789 LPD3DXINCLUDE include;
791 LPD3DXBUFFER error_messages;
799 D3DXAssembleShaderFromFile (file_path, defines, include, flags, &shader, &error_messages);
804 error_message = (
char *) (error_messages -> GetBufferPointer ( ));
807 dxgsg9_cat.error() << error_message;
810 error_messages -> Release ( );
A GraphicsStateGuardian for rendering into DirectX9 contexts.
bool setup_array_data(DXVertexBufferContext9 *&vbc, const GeomVertexArrayDataHandle *data, bool force)
Internal function to bind a buffer object for the indicated data array, if appropriate, or to unbind a buffer object if it should be rendered from client memory.
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler)
Makes the texture the currently available texture for rendering on the ith stage. ...
This is a special class object that holds all the information returned by a particular GSG to indicat...
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
The ShaderContext is meant to contain the compiled version of a shader string.
This class gives the ability for a user-friendly way of creating a vertex declaration for DirectX 9...
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
const SamplerState & get_on_sampler(TextureStage *stage) const
Returns the sampler associated with the indicated stage, or the one associated with its texture if no...
Texture * get_on_texture(TextureStage *stage) const
Returns the texture associated with the indicated stage, or NULL if no texture is associated...
This is a 4-by-4 transform matrix.
const Shader::ShaderPtrData * fetch_ptr_parameter(const Shader::ShaderPtrSpec &spec)
Return a pointer to struct ShaderPtrData.
Texture * load_related(const InternalName *suffix) const
Loads a texture whose filename is derived by concatenating a suffix to the filename of this texture...
TextureStage * get_on_stage(int n) const
Returns the nth stage turned on by the attribute, sorted in render order.
InternalName * get_texcoord_name() const
See set_texcoord_name.
int get_tex_view_offset() const
Returns the current setting of the tex_view_offset.
const float * get_data() const
Returns the address of the first of the nine data elements in the matrix.
Represents a set of settings that indicate how a texture is sampled.
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
This is a special class object that holds all the information returned by a particular GSG to indicat...
int get_num_on_stages() const
Returns the number of stages that are turned on by the attribute.
TypeHandle is the identifier used to differentiate C++ class types.
const LMatrix4 * fetch_specified_value(Shader::ShaderMatSpec &spec, int altered)
The gsg contains a large number of useful matrices:
Defines the properties of a named stage of the multitexture pipeline.