22 #include <sys/types.h> 26 #include <Cg/cgD3D9.h> 29 #define DEBUG_SHADER 0 38 _vertex_element_array =
nullptr;
39 _vertex_declaration =
nullptr;
41 _num_bound_streams = 0;
51 if (!s->cg_compile_for(gsg->_shader_caps, context,
52 _cg_program, _cg_parameter_map)) {
57 DWORD assembly_flags = 0;
59 assembly_flags |= D3DXSHADER_DEBUG;
64 hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
67 <<
"cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
69 CGerror error = cgGetError();
70 if (error != CG_NO_ERROR) {
71 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
86 if (_vertex_declaration !=
nullptr) {
87 _vertex_declaration->Release();
88 _vertex_declaration =
nullptr;
91 if (_vertex_element_array !=
nullptr) {
92 delete _vertex_element_array;
93 _vertex_element_array =
nullptr;
101 void DXShaderContext9::
102 release_resources() {
105 cgDestroyProgram(_cg_program);
107 _cg_parameter_map.clear();
121 bool DXShaderContext9::
123 bool bind_state =
false;
139 hr = cgD3D9BindProgram(_cg_program);
141 dxgsg9_cat.error() <<
"cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
143 CGerror error = cgGetError();
144 if (error != CG_NO_ERROR) {
145 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
159 void DXShaderContext9::
164 hr = cgD3D9UnbindProgram(_cg_program);
167 <<
"cgD3D9UnbindProgram failed " << D3DERRORSTRING(hr);
185 PN_stdfloat *global_data = 0;
186 ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0;
197 for (
size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
200 if (altered & (spec._dep[0] | spec._dep[1])) {
203 if (ptr_data ==
nullptr) {
210 int input_size = std::min(abs(spec._dim[0] * spec._dim[1] * spec._dim[2]), (
int)ptr_data->_size);
212 CGparameter p = _cg_parameter_map[spec._id._seqno];
213 switch (ptr_data->_type) {
214 case Shader::SPT_int:
215 cgSetParameterValueic(p, input_size, (
int *)ptr_data->_ptr);
218 case Shader::SPT_double:
219 cgSetParameterValuedc(p, input_size, (
double *)ptr_data->_ptr);
222 case Shader::SPT_float:
223 cgSetParameterValuefc(p, input_size, (
float *)ptr_data->_ptr);
228 << spec._id._name <<
": unrecognized parameter type\n";
235 for (
size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
238 if (altered & (spec._dep[0] | spec._dep[1])) {
239 CGparameter p = _cg_parameter_map[spec._id._seqno];
247 LMatrix4f temp_matrix = LCAST(
float, *val);
252 data = temp_matrix.get_data();
256 global_data = (PN_stdfloat *)data;
257 global_shader_mat_spec = &spec;
258 global_internal_name_0 = global_shader_mat_spec->_arg[0];
259 global_internal_name_1 = global_shader_mat_spec->_arg[1];
262 switch (spec._piece) {
263 case Shader::SMP_whole:
265 temp_matrix.transpose_in_place();
266 data = temp_matrix.get_data();
268 hr = cgD3D9SetUniform(p, data);
271 case Shader::SMP_transpose:
273 hr = cgD3D9SetUniform(p, data);
276 case Shader::SMP_row0:
277 hr = cgD3D9SetUniform(p, data + 0);
279 case Shader::SMP_row1:
280 hr = cgD3D9SetUniform(p, data + 4);
282 case Shader::SMP_row2:
283 hr = cgD3D9SetUniform(p, data + 8);
285 case Shader::SMP_row3x1:
286 case Shader::SMP_row3x2:
287 case Shader::SMP_row3x3:
288 case Shader::SMP_row3:
289 hr = cgD3D9SetUniform(p, data + 12);
292 case Shader::SMP_col0:
293 v[0] = data[0]; v[1] = data[4]; v[2] = data[8]; v[3] = data[12];
294 hr = cgD3D9SetUniform(p, v);
296 case Shader::SMP_col1:
297 v[0] = data[1]; v[1] = data[5]; v[2] = data[9]; v[3] = data[13];
298 hr = cgD3D9SetUniform(p, v);
300 case Shader::SMP_col2:
301 v[0] = data[2]; v[1] = data[6]; v[2] = data[10]; v[3] = data[14];
302 hr = cgD3D9SetUniform(p, v);
304 case Shader::SMP_col3:
305 v[0] = data[3]; v[1] = data[7]; v[2] = data[11]; v[3] = data[15];
306 hr = cgD3D9SetUniform(p, v);
311 <<
"issue_parameters () SMP parameter type not implemented " << spec._piece <<
"\n";
316 std::string name =
"unnamed";
319 name = spec._arg[0]->get_basename();
323 <<
"NAME " << name <<
"\n" <<
"MAT TYPE " << spec._piece
324 <<
" cgD3D9SetUniform failed " << D3DERRORSTRING(hr);
326 CGerror error = cgGetError();
327 if (error != CG_NO_ERROR) {
328 dxgsg9_cat.error() <<
" CG ERROR: " << cgGetErrorString(error) <<
"\n";
341 void DXShaderContext9::
342 disable_shader_vertex_arrays(
GSG *gsg) {
343 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
345 for (
int array_index = 0; array_index < _num_bound_streams; ++array_index) {
346 device->SetStreamSource(array_index,
nullptr, 0, 0);
348 _num_bound_streams = 0;
366 #ifdef SUPPORT_IMMEDIATE_MODE 372 #endif // SUPPORT_IMMEDIATE_MODE 374 int nvarying = _shader->_var_spec.size();
375 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
380 if (_vertex_element_array !=
nullptr) {
381 delete _vertex_element_array;
393 bool apply_white_color =
false;
395 int number_of_arrays = gsg->_data_reader->get_num_arrays();
396 for (
int array_index = 0; array_index < number_of_arrays; ++array_index) {
398 gsg->_data_reader->get_array_reader(array_index);
399 if (array_reader ==
nullptr) {
400 dxgsg9_cat.error() <<
"Unable to get reader for array " << array_index <<
"\n";
404 for (
int var_index = 0; var_index < nvarying; ++var_index) {
405 CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
408 "No parameter in map for parameter " << var_index <<
409 " (probably optimized away)\n";
413 InternalName *name = _shader->_var_spec[var_index]._name;
417 int texslot = _shader->_var_spec[var_index]._append_uv;
418 if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
419 TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
421 if (name == InternalName::get_texcoord()) {
423 }
else if (texname != InternalName::get_texcoord()) {
428 if (name == InternalName::get_color() && !gsg->_vertex_colors_enabled) {
429 apply_white_color =
true;
434 Geom::NumericType numeric_type;
435 int num_values, start, stride;
436 if (!gsg->_data_reader->get_array_info(name, param_array_reader,
437 num_values, numeric_type,
444 dxgsg9_cat.info() <<
"Geometry contains no data for shader parameter " << *name <<
"\n";
445 if (name == InternalName::get_color()) {
446 apply_white_color =
true;
452 if (param_array_reader != array_reader) {
456 const char *semantic = cgGetParameterSemantic(p);
457 if (semantic ==
nullptr) {
458 dxgsg9_cat.error() <<
"Unable to retrieve semantic for parameter " << var_index <<
"\n";
462 if (strncmp(semantic,
"POSITION", strlen(
"POSITION")) == 0) {
463 if (numeric_type == Geom::NT_float32) {
464 switch (num_values) {
466 vertex_element_array->add_position_xyz_vertex_element(array_index, start);
469 vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
472 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex coordinate elements " << num_values <<
"\n";
476 dxgsg9_cat.error() <<
"VE ERROR: invalid vertex type " << numeric_type <<
"\n";
478 }
else if (strncmp(semantic,
"TEXCOORD", strlen(
"TEXCOORD")) == 0) {
479 int slot = atoi(semantic + strlen(
"TEXCOORD"));
480 if (numeric_type == Geom::NT_float32) {
481 switch (num_values) {
483 vertex_element_array->add_u_vertex_element(array_index, start, slot);
486 vertex_element_array->add_uv_vertex_element(array_index, start, slot);
489 vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
492 vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
495 dxgsg9_cat.error() <<
"VE ERROR: invalid number of vertex texture coordinate elements " << num_values <<
"\n";
499 dxgsg9_cat.error() <<
"VE ERROR: invalid texture coordinate type " << numeric_type <<
"\n";
501 }
else if (strncmp(semantic,
"COLOR", strlen(
"COLOR")) == 0) {
502 if (numeric_type == Geom::NT_packed_dcba ||
503 numeric_type == Geom::NT_packed_dabc ||
504 numeric_type == Geom::NT_uint8) {
505 switch (num_values) {
507 vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
510 dxgsg9_cat.error() <<
"VE ERROR: invalid color coordinates " << num_values <<
"\n";
514 dxgsg9_cat.error() <<
"VE ERROR: invalid color type " << numeric_type <<
"\n";
516 }
else if (strncmp(semantic,
"NORMAL", strlen(
"NORMAL")) == 0) {
517 if (numeric_type == Geom::NT_float32) {
518 switch (num_values) {
520 vertex_element_array->add_normal_vertex_element(array_index, start);
523 dxgsg9_cat.error() <<
"VE ERROR: invalid number of normal coordinate elements " << num_values <<
"\n";
527 dxgsg9_cat.error() <<
"VE ERROR: invalid normal type " << numeric_type <<
"\n";
529 }
else if (strncmp(semantic,
"BINORMAL", strlen(
"BINORMAL")) == 0) {
530 if (numeric_type == Geom::NT_float32) {
531 switch (num_values) {
533 vertex_element_array->add_binormal_vertex_element(array_index, start);
536 dxgsg9_cat.error() <<
"VE ERROR: invalid number of binormal coordinate elements " << num_values <<
"\n";
540 dxgsg9_cat.error() <<
"VE ERROR: invalid binormal type " << numeric_type <<
"\n";
542 }
else if (strncmp(semantic,
"TANGENT", strlen(
"TANGENT")) == 0) {
543 if (numeric_type == Geom::NT_float32) {
544 switch (num_values) {
546 vertex_element_array->add_tangent_vertex_element(array_index, start);
549 dxgsg9_cat.error() <<
"VE ERROR: invalid number of tangent coordinate elements " << num_values <<
"\n";
553 dxgsg9_cat.error() <<
"VE ERROR: invalid tangent type " << numeric_type <<
"\n";
556 dxgsg9_cat.error() <<
"Unsupported semantic " << semantic <<
" for parameter " << var_index <<
"\n";
563 dxgsg9_cat.error() <<
"Unable to setup vertex buffer for array " << array_index <<
"\n";
569 hr = device->SetStreamSource(array_index, dvbc->_vbuffer, 0, array_format->
get_stride());
571 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
575 _num_bound_streams = number_of_arrays;
577 if (apply_white_color) {
580 int array_index = number_of_arrays;
582 hr = device->SetStreamSource(array_index, vbuffer, 0, 0);
584 dxgsg9_cat.error() <<
"SetStreamSource failed" << D3DERRORSTRING(hr);
586 vertex_element_array->add_diffuse_color_vertex_element(array_index, 0);
587 ++_num_bound_streams;
590 if (_vertex_element_array !=
nullptr &&
591 _vertex_element_array->add_end_vertex_element()) {
592 if (dxgsg9_cat.is_debug()) {
597 if (cgD3D9ValidateVertexDeclaration(_cg_program,
598 _vertex_element_array->_vertex_element_array) == CG_TRUE) {
599 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration succeeded\n";
601 dxgsg9_cat.debug() <<
"cgD3D9ValidateVertexDeclaration failed\n";
606 if (_vertex_declaration !=
nullptr) {
607 _vertex_declaration->Release();
608 _vertex_declaration =
nullptr;
611 hr = device->CreateVertexDeclaration(_vertex_element_array->_vertex_element_array,
612 &_vertex_declaration);
614 dxgsg9_cat.error() <<
"CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
616 hr = device->SetVertexDeclaration(_vertex_declaration);
618 dxgsg9_cat.error() <<
"SetVertexDeclaration failed" << D3DERRORSTRING(hr);
622 dxgsg9_cat.error() <<
"VertexElementArray creation failed\n";
633 void DXShaderContext9::
634 disable_shader_texture_bindings(
GSG *gsg) {
637 for (
size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
638 CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
642 int texunit = cgGetParameterResourceIndex(p);
646 hr = gsg->_d3d_device->SetTexture(texunit,
nullptr);
649 <<
"SetTexture(" << texunit <<
", NULL) failed " 650 << D3DERRORSTRING(hr);
672 for (
size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
674 CGparameter p = _cg_parameter_map[spec._id._seqno];
679 int view = gsg->get_current_tex_view_offset();
682 PT(
Texture) tex = gsg->fetch_specified_texture(spec, sampler, view);
687 if (spec._suffix != 0) {
689 tex = tex->load_related(spec._suffix);
692 if (tex->get_texture_type() != spec._desired_type) {
696 TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
701 int texunit = cgGetParameterResourceIndex(p);
709 void assemble_shader_test(
char *file_path) {
712 LPD3DXINCLUDE include;
714 LPD3DXBUFFER error_messages;
722 D3DXAssembleShaderFromFile(file_path, defines, include, flags, &shader, &error_messages);
723 if (error_messages) {
726 error_message = (
char *)error_messages->GetBufferPointer();
728 dxgsg9_cat.error() << error_message;
731 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,...
LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer()
Returns a vertex buffer containing only a full-white color.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
DXShaderContext9(Shader *s, GSG *gsg)
xyz
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...
Filename get_filename(ShaderType type=ST_none) const
Return the Shader's filename for the given shader type.
void issue_parameters(GSG *gsg, int altered)
This function gets called whenever the RenderState or TransformState has changed, but the Shader itse...
void disable_shader_texture_bindings(GSG *gsg)
Disable all the texture bindings used by this shader.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
ShaderLanguage get_language() const
Returns the shader language in which this shader was written.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The ShaderContext is meant to contain the compiled version of a shader string.
void disable_shader_vertex_arrays(GSG *gsg)
Disable all the vertex arrays used by this shader.
This class gives the ability for a user-friendly way of creating a vertex declaration for DirectX 9.
Encodes a string name in a hash table, mapping it to a pointer.
Represents a set of settings that indicate how a texture is sampled.
bool update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force)
Disables all vertex arrays used by the previous shader, then enables all the vertex arrays needed by ...
get_basename
Return the name represented by just this particular InternalName object, ignoring its parents names.
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.
void update_shader_texture_bindings(DXShaderContext9 *prev, GSG *gsg)
Disables all texture bindings used by the previous shader, then enables all the texture bindings need...
get_texcoord_name
See set_texcoord_name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.