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) {
55 if (!s->cg_compile_for(gsg->_shader_caps, context,
56 _cg_program, _cg_parameter_map)) {
61 DWORD assembly_flags = 0;
63 assembly_flags |= D3DXSHADER_DEBUG;
68 hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
71 <<
"cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
73 CGerror error = cgGetError();
74 if (error != CG_NO_ERROR) {
75 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
92 if ( _vertex_declaration != NULL ) {
93 _vertex_declaration->Release();
94 _vertex_declaration = NULL;
97 if ( _vertex_element_array != NULL ) {
98 delete _vertex_element_array;
99 _vertex_element_array = NULL;
158 release_resources() {
161 cgDestroyProgram(_cg_program);
163 _cg_parameter_map.clear();
182 bool bind_state =
false;
188 gsg -> _last_fvf = 0;
191 issue_parameters(gsg, Shader::SSD_general);
197 hr = cgD3D9BindProgram(_cg_program);
199 dxgsg9_cat.error() <<
"cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
201 CGerror error = cgGetError();
202 if (error != CG_NO_ERROR) {
203 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
225 hr = cgD3D9UnbindProgram(_cg_program);
228 <<
"cgD3D9UnbindProgram failed " << D3DERRORSTRING(hr);
251 PN_stdfloat *global_data = 0;
252 ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0;
253 InternalName *global_internal_name_0 = 0;
254 InternalName *global_internal_name_1 = 0;
258 issue_parameters(
GSG *gsg, int altered) {
263 for (
int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
264 if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])){
270 if (_ptr_data == NULL){
275 CGparameter p = _cg_parameter_map[_ptr._id._seqno];
277 switch(_ptr_data->_type) {
278 case Shader::SPT_float:
279 cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
284 << _ptr._id._name <<
":" <<
"unrecognized parameter type\n";
292 for (
int i=0; i<(int)_shader->_mat_spec.size(); i++) {
293 if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
294 CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
298 const LMatrix4 *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
302 LMatrix4f temp_matrix = LCAST(
float, *val);
311 global_data = (PN_stdfloat *) data;
312 global_shader_mat_spec = &_shader->_mat_spec[i];
313 global_internal_name_0 = global_shader_mat_spec -> _arg [0];
314 global_internal_name_1 = global_shader_mat_spec -> _arg [1];
317 switch (_shader->_mat_spec[i]._piece) {
318 case Shader::SMP_whole:
320 temp_matrix.transpose_in_place();
323 hr = cgD3D9SetUniform (p, data);
326 case Shader::SMP_transpose:
328 hr = cgD3D9SetUniform (p, data);
331 case Shader::SMP_row0:
332 hr = cgD3D9SetUniform (p, data + 0);
334 case Shader::SMP_row1:
335 hr = cgD3D9SetUniform (p, data + 4);
337 case Shader::SMP_row2:
338 hr = cgD3D9SetUniform (p, data + 8);
340 case Shader::SMP_row3x1:
341 case Shader::SMP_row3x2:
342 case Shader::SMP_row3x3:
343 case Shader::SMP_row3:
344 hr = cgD3D9SetUniform (p, data + 12);
347 case Shader::SMP_col0:
348 v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
349 hr = cgD3D9SetUniform (p, v);
351 case Shader::SMP_col1:
352 v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
353 hr = cgD3D9SetUniform (p, v);
355 case Shader::SMP_col2:
356 v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
357 hr = cgD3D9SetUniform (p, v);
359 case Shader::SMP_col3:
360 v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
361 hr = cgD3D9SetUniform (p, v);
366 <<
"issue_parameters ( ) SMP parameter type not implemented " << _shader->_mat_spec[i]._piece <<
"\n";
372 string name =
"unnamed";
374 if (_shader->_mat_spec[i]._arg [0]) {
375 name = _shader->_mat_spec[i]._arg [0] -> get_basename ( );
379 <<
"NAME " << name <<
"\n"
381 << _shader->_mat_spec[i]._piece
382 <<
" cgD3D9SetUniform failed "
383 << D3DERRORSTRING(hr);
385 CGerror error = cgGetError ();
386 if (error != CG_NO_ERROR) {
387 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
403 disable_shader_vertex_arrays(
GSG *gsg) {
404 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
406 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index )
408 device->SetStreamSource( array_index, NULL, 0, 0 );
410 _num_bound_streams = 0;
426 if (prev) prev->disable_shader_vertex_arrays(gsg);
432 #ifdef SUPPORT_IMMEDIATE_MODE
438 #endif // SUPPORT_IMMEDIATE_MODE
440 int nvarying = _shader->_var_spec.size();
441 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
445 if ( _vertex_element_array != NULL ) {
446 delete _vertex_element_array;
457 int number_of_arrays = gsg->_data_reader->get_num_arrays();
458 for (
int array_index = 0; array_index < number_of_arrays; ++array_index ) {
460 gsg->_data_reader->get_array_reader( array_index );
461 if ( array_reader == NULL ) {
462 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
466 for (
int var_index = 0; var_index < nvarying; ++var_index ) {
467 CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
470 "No parameter in map for parameter " << var_index <<
471 " (probably optimized away)\n";
475 InternalName *name = _shader->_var_spec[var_index]._name;
479 int texslot = _shader->_var_spec[var_index]._append_uv;
480 if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
481 TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
483 if (name == InternalName::get_texcoord()) {
485 }
else if (texname != InternalName::get_texcoord()) {
486 name = name->append(texname->get_basename());
491 Geom::NumericType numeric_type;
495 if ( gsg->_data_reader->get_array_info( name,
496 param_array_reader, num_values, numeric_type,
497 start, stride ) == false ) {
503 dxgsg9_cat.info() <<
"Geometry contains no data for shader parameter " << *name <<
"\n";
508 if ( param_array_reader != array_reader ) {
512 const char* semantic = cgGetParameterSemantic( p );
513 if ( semantic == NULL ) {
514 dxgsg9_cat.error() <<
"Unable to retrieve semantic for parameter " << var_index <<
"\n";
518 if ( strncmp( semantic,
"POSITION", strlen(
"POSITION" ) ) == 0 ) {
519 if (numeric_type == Geom::NT_float32) {
520 switch (num_values) {
522 vertex_element_array->add_position_xyz_vertex_element(array_index, start);
525 vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
528 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex coordinate elements " << num_values <<
"\n";
532 dxgsg9_cat.error() <<
"VE ERROR: invalid vertex type " << numeric_type <<
"\n";
534 }
else if ( strncmp( semantic,
"TEXCOORD", strlen(
"TEXCOORD" ) ) == 0 ) {
535 int slot = atoi( semantic + strlen(
"TEXCOORD" ) );
536 if (numeric_type == Geom::NT_float32) {
537 switch (num_values) {
539 vertex_element_array->add_u_vertex_element(array_index, start, slot);
542 vertex_element_array->add_uv_vertex_element(array_index, start, slot);
545 vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
548 vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
551 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<
"\n";
555 dxgsg9_cat.error() <<
"VE ERROR: invalid texture coordinate type " << numeric_type <<
"\n";
557 }
else if ( strncmp( semantic,
"COLOR", strlen(
"COLOR" ) ) == 0 ) {
558 if (numeric_type == Geom::NT_packed_dcba ||
559 numeric_type == Geom::NT_packed_dabc ||
560 numeric_type == Geom::NT_uint8) {
561 switch (num_values) {
563 vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
566 dxgsg9_cat.error() <<
"VE ERROR: invalid color coordinates " << num_values <<
"\n";
570 dxgsg9_cat.error() <<
"VE ERROR: invalid color type " << numeric_type <<
"\n";
572 }
else if ( strncmp( semantic,
"NORMAL", strlen(
"NORMAL" ) ) == 0 ) {
573 if (numeric_type == Geom::NT_float32) {
574 switch (num_values) {
576 vertex_element_array->add_normal_vertex_element(array_index, start);
579 dxgsg9_cat.error() <<
"VE ERROR: invalid number of normal coordinate elements " << num_values <<
"\n";
583 dxgsg9_cat.error() <<
"VE ERROR: invalid normal type " << numeric_type <<
"\n";
585 }
else if ( strncmp( semantic,
"BINORMAL", strlen(
"BINORMAL" ) ) == 0 ) {
586 if (numeric_type == Geom::NT_float32) {
587 switch (num_values) {
589 vertex_element_array->add_binormal_vertex_element(array_index, start);
592 dxgsg9_cat.error() <<
"VE ERROR: invalid number of binormal coordinate elements " << num_values <<
"\n";
596 dxgsg9_cat.error() <<
"VE ERROR: invalid binormal type " << numeric_type <<
"\n";
598 }
else if ( strncmp( semantic,
"TANGENT", strlen(
"TANGENT" ) ) == 0 ) {
599 if (numeric_type == Geom::NT_float32) {
600 switch (num_values) {
602 vertex_element_array->add_tangent_vertex_element(array_index, start);
605 dxgsg9_cat.error() <<
"VE ERROR: invalid number of tangent coordinate elements " << num_values <<
"\n";
609 dxgsg9_cat.error() <<
"VE ERROR: invalid tangent type " << numeric_type <<
"\n";
612 dxgsg9_cat.error() <<
"Unsupported semantic " << semantic <<
" for parameter " << var_index <<
"\n";
618 if (!gsg->setup_array_data(dvbc, array_reader, force)) {
619 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
624 const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
625 hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
627 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
631 _num_bound_streams = number_of_arrays;
633 if (( _vertex_element_array != NULL ) &&
634 ( _vertex_element_array->add_end_vertex_element() != false )) {
635 if (dxgsg9_cat.is_debug()) {
639 if (cgD3D9ValidateVertexDeclaration(_cg_program,
640 _vertex_element_array->_vertex_element_array) == CG_TRUE) {
641 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration succeeded\n";
643 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration failed\n";
648 if ( _vertex_declaration != NULL ) {
649 _vertex_declaration->Release();
650 _vertex_declaration = NULL;
653 hr = device->CreateVertexDeclaration( _vertex_element_array->_vertex_element_array,
654 &_vertex_declaration );
656 dxgsg9_cat.error() <<
"CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
658 hr = device->SetVertexDeclaration( _vertex_declaration );
660 dxgsg9_cat.error() <<
"SetVertexDeclaration failed" << D3DERRORSTRING(hr);
664 dxgsg9_cat.error() <<
"VertexElementArray creation failed\n";
678 disable_shader_texture_bindings(
GSG *gsg)
682 for (
int i=0; i<(int)_shader->_tex_spec.size(); i++) {
683 CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
687 int texunit = cgGetParameterResourceIndex(p);
691 hr = gsg -> _d3d_device -> SetTexture (texunit, NULL);
697 << D3DERRORSTRING(hr);
718 if (prev) prev->disable_shader_texture_bindings(gsg);
723 for (
int i=0; i<(int)_shader->_tex_spec.size(); i++) {
724 CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
729 int view = gsg->get_current_tex_view_offset();
730 InternalName *
id = _shader->_tex_spec[i]._name;
734 const ShaderInput *input = gsg->_target_shader->get_shader_input(
id);
735 tex = input->get_texture();
736 sampler = input->get_sampler();
752 if (_shader->_tex_spec[i]._suffix != 0) {
759 if ((tex == 0) || (tex->
get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
767 int texunit = cgGetParameterResourceIndex(p);
769 gsg->apply_texture(texunit, tc, sampler);
776 void assemble_shader_test(
char *file_path)
780 LPD3DXINCLUDE include;
782 LPD3DXBUFFER error_messages;
790 D3DXAssembleShaderFromFile (file_path, defines, include, flags, &shader, &error_messages);
795 error_message = (
char *) (error_messages -> GetBufferPointer ( ));
798 dxgsg9_cat.error() << error_message;
801 error_messages -> Release ( );
A GraphicsStateGuardian for rendering into DirectX9 contexts.
Texture * load_related(const InternalName *suffix) const
Loads a texture whose filename is derived by concatenating a suffix to the filename of this texture...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
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.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
TextureStage * get_on_stage(int n) const
Returns the nth stage turned on by the attribute, sorted in render order.
const float * get_data() const
Returns the address of the first of the nine data elements in the matrix.
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...
InternalName * get_texcoord_name() const
See set_texcoord_name.
This is a 4-by-4 transform matrix.
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...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
int get_tex_view_offset() const
Returns the current setting of the tex_view_offset.
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...
TypeHandle is the identifier used to differentiate C++ class types.
Defines the properties of a named stage of the multitexture pipeline.