Panda3D
dxShaderContext9.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file dxShaderContext9.cxx
10 * @author jyelon
11 * @date 2005-09-01
12 */
13
15#include "dxShaderContext9.h"
17
18#include <io.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <fcntl.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24
25#ifdef HAVE_CG
26#include <Cg/cgD3D9.h>
27#endif
28
29#define DEBUG_SHADER 0
30
31TypeHandle DXShaderContext9::_type_handle;
32
33/**
34 * xyz
35 */
38 _vertex_element_array = nullptr;
39 _vertex_declaration = nullptr;
40
41 _num_bound_streams = 0;
42
43 _name = s->get_filename();
44
45#ifdef HAVE_CG
46 CGcontext context = DCAST(DXGraphicsStateGuardian9, gsg)->_cg_context;
47
48 if (s->get_language() == Shader::SL_Cg) {
49 // Ask the shader to compile itself for us and to give us the resulting Cg
50 // program objects.
51 if (!s->cg_compile_for(gsg->_shader_caps, context,
52 _cg_program, _cg_parameter_map)) {
53 return;
54 }
55
56 // Load the program.
57 DWORD assembly_flags = 0;
58#if DEBUG_SHADER
59 assembly_flags |= D3DXSHADER_DEBUG;
60#endif
61
62 HRESULT hr;
63 bool success = true;
64 hr = cgD3D9LoadProgram(_cg_program, FALSE, assembly_flags);
65 if (FAILED(hr)) {
66 dxgsg9_cat.error()
67 << "cgD3D9LoadProgram failed " << D3DERRORSTRING(hr);
68
69 CGerror error = cgGetError();
70 if (error != CG_NO_ERROR) {
71 dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
72 }
73 release_resources();
74 }
75 }
76#endif
77}
78
79/**
80 * xyz
81 */
84 release_resources();
85
86 if (_vertex_declaration != nullptr) {
87 _vertex_declaration->Release();
88 _vertex_declaration = nullptr;
89 }
90
91 if (_vertex_element_array != nullptr) {
92 delete _vertex_element_array;
93 _vertex_element_array = nullptr;
94 }
95}
96
97/**
98 * Should deallocate all system resources (such as vertex program handles or
99 * Cg contexts).
100 */
101void DXShaderContext9::
102release_resources() {
103#ifdef HAVE_CG
104 if (_cg_program) {
105 cgDestroyProgram(_cg_program);
106 _cg_program = 0;
107 _cg_parameter_map.clear();
108 }
109#endif
110
111 // I think we need to call SetStreamSource for _num_bound_streams --
112 // basically the logic from disable_shader_vertex_arrays -- but to do that
113 // we need to introduce logic like the GL code has to manage _last_gsg, so
114 // we can get at the device. Sigh.
115}
116
117/**
118 * This function is to be called to enable a new shader. It also initializes
119 * all of the shader's input parameters.
120 */
121bool DXShaderContext9::
122bind(GSG *gsg) {
123 bool bind_state = false;
124
125#ifdef HAVE_CG
126 if (_cg_program) {
127 // clear the last cached FVF to make sure the next SetFVF call goes
128 // through
129
130 gsg->_last_fvf = 0;
131
132 // Pass in k-parameters and transform-parameters
133 issue_parameters(gsg, Shader::SSD_general);
134
135 HRESULT hr;
136
137 // Bind the shaders.
138 bind_state = true;
139 hr = cgD3D9BindProgram(_cg_program);
140 if (FAILED(hr)) {
141 dxgsg9_cat.error() << "cgD3D9BindProgram failed " << D3DERRORSTRING(hr);
142
143 CGerror error = cgGetError();
144 if (error != CG_NO_ERROR) {
145 dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
146 }
147
148 bind_state = false;
149 }
150 }
151#endif
152
153 return bind_state;
154}
155
156/**
157 * This function disables a currently-bound shader.
158 */
159void DXShaderContext9::
160unbind(GSG *gsg) {
161#ifdef HAVE_CG
162 if (_cg_program) {
163 HRESULT hr;
164 hr = cgD3D9UnbindProgram(_cg_program);
165 if (FAILED(hr)) {
166 dxgsg9_cat.error()
167 << "cgD3D9UnbindProgram failed " << D3DERRORSTRING(hr);
168 }
169 }
170#endif
171}
172
173/**
174 * This function gets called whenever the RenderState or TransformState has
175 * changed, but the Shader itself has not changed. It loads new values into
176 * the shader's parameters.
177 *
178 * If "altered" is false, that means you promise that the parameters for this
179 * shader context have already been issued once, and that since the last time
180 * the parameters were issued, no part of the render state has changed except
181 * the external and internal transforms.
182 */
183
184#if DEBUG_SHADER
185PN_stdfloat *global_data = 0;
186ShaderContext::ShaderMatSpec *global_shader_mat_spec = 0;
187InternalName *global_internal_name_0 = 0;
188InternalName *global_internal_name_1 = 0;
189#endif
190
192issue_parameters(GSG *gsg, int altered) {
193#ifdef HAVE_CG
194 if (_cg_program) {
195
196 // Iterate through _ptr parameters
197 for (size_t i = 0; i < _shader->_ptr_spec.size(); ++i) {
198 const Shader::ShaderPtrSpec &spec = _shader->_ptr_spec[i];
199
200 if (altered & (spec._dep[0] | spec._dep[1])) {
201 const Shader::ShaderPtrData *ptr_data = gsg->fetch_ptr_parameter(spec);
202
203 if (ptr_data == nullptr) { //the input is not contained in ShaderPtrData
204 release_resources();
205 return;
206 }
207
208 // Calculate how many elements to transfer; no more than it expects,
209 // but certainly no more than we have.
210 int input_size = std::min(abs(spec._dim[0] * spec._dim[1] * spec._dim[2]), (int)ptr_data->_size);
211
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);
216 break;
217
218 case Shader::SPT_double:
219 cgSetParameterValuedc(p, input_size, (double *)ptr_data->_ptr);
220 break;
221
222 case Shader::SPT_float:
223 cgSetParameterValuefc(p, input_size, (float *)ptr_data->_ptr);
224 break;
225
226 default:
227 dxgsg9_cat.error()
228 << spec._id._name << ": unrecognized parameter type\n";
229 release_resources();
230 return;
231 }
232 }
233 }
234
235 for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
236 Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
237
238 if (altered & (spec._dep[0] | spec._dep[1])) {
239 CGparameter p = _cg_parameter_map[spec._id._seqno];
240 if (p == nullptr) {
241 continue;
242 }
243 const LMatrix4 *val = gsg->fetch_specified_value(spec, altered);
244 if (val) {
245 HRESULT hr;
246 PN_stdfloat v [4];
247 LMatrix4f temp_matrix = LCAST(float, *val);
248
249 hr = D3D_OK;
250
251 const float *data;
252 data = temp_matrix.get_data();
253
254#if DEBUG_SHADER
255 // DEBUG
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];
260#endif
261
262 switch (spec._piece) {
263 case Shader::SMP_whole:
264 // TRANSPOSE REQUIRED
265 temp_matrix.transpose_in_place();
266 data = temp_matrix.get_data();
267
268 hr = cgD3D9SetUniform(p, data);
269 break;
270
271 case Shader::SMP_transpose:
272 // NO TRANSPOSE REQUIRED
273 hr = cgD3D9SetUniform(p, data);
274 break;
275
276 case Shader::SMP_row0:
277 hr = cgD3D9SetUniform(p, data + 0);
278 break;
279 case Shader::SMP_row1:
280 hr = cgD3D9SetUniform(p, data + 4);
281 break;
282 case Shader::SMP_row2:
283 hr = cgD3D9SetUniform(p, data + 8);
284 break;
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);
290 break;
291
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);
295 break;
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);
299 break;
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);
303 break;
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);
307 break;
308
309 default:
310 dxgsg9_cat.error()
311 << "issue_parameters () SMP parameter type not implemented " << spec._piece << "\n";
312 break;
313 }
314
315 if (FAILED(hr)) {
316 std::string name = "unnamed";
317
318 if (spec._arg[0]) {
319 name = spec._arg[0]->get_basename();
320 }
321
322 dxgsg9_cat.error()
323 << "NAME " << name << "\n" << "MAT TYPE " << spec._piece
324 << " cgD3D9SetUniform failed " << D3DERRORSTRING(hr);
325
326 CGerror error = cgGetError();
327 if (error != CG_NO_ERROR) {
328 dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
329 }
330 }
331 }
332 }
333 }
334 }
335#endif
336}
337
338/**
339 * Disable all the vertex arrays used by this shader.
340 */
341void DXShaderContext9::
342disable_shader_vertex_arrays(GSG *gsg) {
343 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
344
345 for (int array_index = 0; array_index < _num_bound_streams; ++array_index) {
346 device->SetStreamSource(array_index, nullptr, 0, 0);
347 }
348 _num_bound_streams = 0;
349}
350
351/**
352 * Disables all vertex arrays used by the previous shader, then enables all
353 * the vertex arrays needed by this shader. Extracts the relevant vertex
354 * array data from the gsg. The current implementation is inefficient,
355 * because it may unnecessarily disable arrays then immediately reenable them.
356 * We may optimize this someday.
357 */
359update_shader_vertex_arrays(DXShaderContext9 *prev, GSG *gsg, bool force) {
360 if (prev) prev->disable_shader_vertex_arrays(gsg);
361#ifdef HAVE_CG
362 if (!_cg_program) {
363 return true;
364 }
365
366#ifdef SUPPORT_IMMEDIATE_MODE
367/*
368 if (gsg->_use_sender) {
369 dxgsg9_cat.error() << "immediate mode shaders not implemented yet\n";
370 } else
371*/
372#endif // SUPPORT_IMMEDIATE_MODE
373 {
374 int nvarying = _shader->_var_spec.size();
375 LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
376 HRESULT hr;
377
378 // Discard and recreate the VertexElementArray. This thrashes pretty
379 // bad....
380 if (_vertex_element_array != nullptr) {
381 delete _vertex_element_array;
382 }
383 _vertex_element_array = new VertexElementArray(nvarying + 2);
384 VertexElementArray* vertex_element_array = _vertex_element_array;
385
386 // Experimentally determined that DX doesn't like us crossing the streams!
387 // It seems to be okay with out-of-order offsets in both source and
388 // destination, but it wants all stream X entries grouped together, then
389 // all stream Y entries, etc. To accomplish this out outer loop processes
390 // arrays ("streams"), and we repeatedly iterate the parameters to pull
391 // out only those for a single stream.
392
393 bool apply_white_color = false;
394
395 int number_of_arrays = gsg->_data_reader->get_num_arrays();
396 for (int array_index = 0; array_index < number_of_arrays; ++array_index) {
397 const GeomVertexArrayDataHandle* array_reader =
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";
401 continue;
402 }
403
404 for (int var_index = 0; var_index < nvarying; ++var_index) {
405 CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno];
406 if (p == nullptr) {
407 dxgsg9_cat.info() <<
408 "No parameter in map for parameter " << var_index <<
409 " (probably optimized away)\n";
410 continue;
411 }
412
413 InternalName *name = _shader->_var_spec[var_index]._name;
414
415 // This is copied from the GL version of this function, and I've yet
416 // to 100% convince myself that it works properly....
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);
420 InternalName *texname = stage->get_texcoord_name();
421 if (name == InternalName::get_texcoord()) {
422 name = texname;
423 } else if (texname != InternalName::get_texcoord()) {
424 name = name->append(texname->get_basename());
425 }
426 }
427
428 if (name == InternalName::get_color() && !gsg->_vertex_colors_enabled) {
429 apply_white_color = true;
430 continue;
431 }
432
433 const GeomVertexArrayDataHandle *param_array_reader;
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,
438 start, stride)) {
439 // This is apparently not an error (actually I think it is, just not
440 // a fatal one). The GL implementation fails silently in this case,
441 // but the net result is that we end up not supplying input for a
442 // shader parameter, which can cause Bad Things to happen so I'd
443 // like to at least get a hint as to what's gone wrong.
444 dxgsg9_cat.info() << "Geometry contains no data for shader parameter " << *name << "\n";
445 if (name == InternalName::get_color()) {
446 apply_white_color = true;
447 }
448 continue;
449 }
450
451 // If not associated with the array we're working on, move on.
452 if (param_array_reader != array_reader) {
453 continue;
454 }
455
456 const char *semantic = cgGetParameterSemantic(p);
457 if (semantic == nullptr) {
458 dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n";
459 continue;
460 }
461
462 if (strncmp(semantic, "POSITION", strlen("POSITION")) == 0) {
463 if (numeric_type == Geom::NT_float32) {
464 switch (num_values) {
465 case 3:
466 vertex_element_array->add_position_xyz_vertex_element(array_index, start);
467 break;
468 case 4:
469 vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
470 break;
471 default:
472 dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
473 break;
474 }
475 } else {
476 dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n";
477 }
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) {
482 case 1:
483 vertex_element_array->add_u_vertex_element(array_index, start, slot);
484 break;
485 case 2:
486 vertex_element_array->add_uv_vertex_element(array_index, start, slot);
487 break;
488 case 3:
489 vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
490 break;
491 case 4:
492 vertex_element_array->add_xyzw_vertex_element(array_index, start, slot);
493 break;
494 default:
495 dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n";
496 break;
497 }
498 } else {
499 dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
500 }
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) {
506 case 4:
507 vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
508 break;
509 default:
510 dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n";
511 break;
512 }
513 } else {
514 dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n";
515 }
516 } else if (strncmp(semantic, "NORMAL", strlen("NORMAL")) == 0) {
517 if (numeric_type == Geom::NT_float32) {
518 switch (num_values) {
519 case 3:
520 vertex_element_array->add_normal_vertex_element(array_index, start);
521 break;
522 default:
523 dxgsg9_cat.error() << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n";
524 break;
525 }
526 } else {
527 dxgsg9_cat.error() << "VE ERROR: invalid normal type " << numeric_type << "\n";
528 }
529 } else if (strncmp(semantic, "BINORMAL", strlen("BINORMAL")) == 0) {
530 if (numeric_type == Geom::NT_float32) {
531 switch (num_values) {
532 case 3:
533 vertex_element_array->add_binormal_vertex_element(array_index, start);
534 break;
535 default:
536 dxgsg9_cat.error() << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n";
537 break;
538 }
539 } else {
540 dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n";
541 }
542 } else if (strncmp(semantic, "TANGENT", strlen("TANGENT")) == 0) {
543 if (numeric_type == Geom::NT_float32) {
544 switch (num_values) {
545 case 3:
546 vertex_element_array->add_tangent_vertex_element(array_index, start);
547 break;
548 default:
549 dxgsg9_cat.error() << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n";
550 break;
551 }
552 } else {
553 dxgsg9_cat.error() << "VE ERROR: invalid tangent type " << numeric_type << "\n";
554 }
555 } else {
556 dxgsg9_cat.error() << "Unsupported semantic " << semantic << " for parameter " << var_index << "\n";
557 }
558 }
559
560 // Get the vertex buffer for this array.
562 if (!gsg->setup_array_data(dvbc, array_reader, force)) {
563 dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
564 continue;
565 }
566
567 // Bind this array as the data source for the corresponding stream.
568 const GeomVertexArrayFormat *array_format = array_reader->get_array_format();
569 hr = device->SetStreamSource(array_index, dvbc->_vbuffer, 0, array_format->get_stride());
570 if (FAILED(hr)) {
571 dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
572 }
573 }
574
575 _num_bound_streams = number_of_arrays;
576
577 if (apply_white_color) {
578 // The shader needs a vertex color, but vertex colors are disabled.
579 // Bind a vertex buffer containing only one white colour.
580 int array_index = number_of_arrays;
581 LPDIRECT3DVERTEXBUFFER9 vbuffer = gsg->get_white_vbuffer();
582 hr = device->SetStreamSource(array_index, vbuffer, 0, 0);
583 if (FAILED(hr)) {
584 dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
585 }
586 vertex_element_array->add_diffuse_color_vertex_element(array_index, 0);
587 ++_num_bound_streams;
588 }
589
590 if (_vertex_element_array != nullptr &&
591 _vertex_element_array->add_end_vertex_element()) {
592 if (dxgsg9_cat.is_debug()) {
593 // Note that the currently generated vertex declaration works but
594 // never validates. My theory is that this is due to the shader
595 // programs always using float4 whereas the vertex declaration
596 // correctly sets the number of inputs (float2, float3, etc.).
597 if (cgD3D9ValidateVertexDeclaration(_cg_program,
598 _vertex_element_array->_vertex_element_array) == CG_TRUE) {
599 dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration succeeded\n";
600 } else {
601 dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration failed\n";
602 }
603 }
604
605 // Discard the old VertexDeclaration. This thrashes pretty bad....
606 if (_vertex_declaration != nullptr) {
607 _vertex_declaration->Release();
608 _vertex_declaration = nullptr;
609 }
610
611 hr = device->CreateVertexDeclaration(_vertex_element_array->_vertex_element_array,
612 &_vertex_declaration);
613 if (FAILED(hr)) {
614 dxgsg9_cat.error() << "CreateVertexDeclaration failed" << D3DERRORSTRING(hr);
615 } else {
616 hr = device->SetVertexDeclaration(_vertex_declaration);
617 if (FAILED(hr)) {
618 dxgsg9_cat.error() << "SetVertexDeclaration failed" << D3DERRORSTRING(hr);
619 }
620 }
621 } else {
622 dxgsg9_cat.error() << "VertexElementArray creation failed\n";
623 }
624 }
625#endif // HAVE_CG
626
627 return true;
628}
629
630/**
631 * Disable all the texture bindings used by this shader.
632 */
633void DXShaderContext9::
634disable_shader_texture_bindings(GSG *gsg) {
635#ifdef HAVE_CG
636 if (_cg_program) {
637 for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
638 CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
639 if (p == nullptr) {
640 continue;
641 }
642 int texunit = cgGetParameterResourceIndex(p);
643
644 HRESULT hr;
645
646 hr = gsg->_d3d_device->SetTexture(texunit, nullptr);
647 if (FAILED(hr)) {
648 dxgsg9_cat.error()
649 << "SetTexture(" << texunit << ", NULL) failed "
650 << D3DERRORSTRING(hr);
651 }
652 }
653 }
654#endif
655}
656
657/**
658 * Disables all texture bindings used by the previous shader, then enables all
659 * the texture bindings needed by this shader. Extracts the relevant vertex
660 * array data from the gsg. The current implementation is inefficient,
661 * because it may unnecessarily disable textures then immediately reenable
662 * them. We may optimize this someday.
663 */
666 if (prev) {
668 }
669
670#ifdef HAVE_CG
671 if (_cg_program) {
672 for (size_t i = 0; i < _shader->_tex_spec.size(); ++i) {
673 Shader::ShaderTexSpec &spec = _shader->_tex_spec[i];
674 CGparameter p = _cg_parameter_map[spec._id._seqno];
675 if (p == nullptr) {
676 continue;
677 }
678
679 int view = gsg->get_current_tex_view_offset();
680 SamplerState sampler;
681
682 PT(Texture) tex = gsg->fetch_specified_texture(spec, sampler, view);
683 if (tex.is_null()) {
684 continue;
685 }
686
687 if (spec._suffix != 0) {
688 // The suffix feature is inefficient. It is a temporary hack.
689 tex = tex->load_related(spec._suffix);
690 }
691
692 if (tex->get_texture_type() != spec._desired_type) {
693 continue;
694 }
695
696 TextureContext *tc = tex->prepare_now(view, gsg->_prepared_objects, gsg);
697 if (tc == nullptr) {
698 continue;
699 }
700
701 int texunit = cgGetParameterResourceIndex(p);
702 gsg->apply_texture(texunit, tc, sampler);
703 }
704 }
705#endif
706}
707
708// DEBUG CODE TO TEST ASM CODE GENERATED BY Cg
709void assemble_shader_test(char *file_path) {
710 int flags;
711 D3DXMACRO *defines;
712 LPD3DXINCLUDE include;
713 LPD3DXBUFFER shader;
714 LPD3DXBUFFER error_messages;
715
716 flags = 0;
717 defines = 0;
718 include = 0;
719 shader = 0;
720 error_messages = 0;
721
722 D3DXAssembleShaderFromFile(file_path, defines, include, flags, &shader, &error_messages);
723 if (error_messages) {
724 char *error_message;
725
726 error_message = (char *)error_messages->GetBufferPointer();
727 if (error_message) {
728 dxgsg9_cat.error() << error_message;
729 }
730
731 error_messages->Release();
732 }
733}
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,...
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler)
Makes the texture the currently available texture for rendering on the ith stage.
LPDIRECT3DVERTEXBUFFER9 get_white_vbuffer()
Returns a vertex buffer containing only a full-white color.
DXShaderContext9(Shader *s, GSG *gsg)
xyz
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 ...
void disable_shader_vertex_arrays(GSG *gsg)
Disable all the vertex arrays used by this shader.
void disable_shader_texture_bindings(GSG *gsg)
Disable all the texture bindings used by this shader.
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...
void issue_parameters(GSG *gsg, int altered)
This function gets called whenever the RenderState or TransformState has changed, but the Shader itse...
Caches a GeomVertexArrayData in the DirectX device as a vertex buffer.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
This describes the structure of a single array within a Geom data.
get_stride
Returns the total number of bytes reserved in the array for each vertex.
PT(Texture) fetch_specified_texture(Shader const Shader::ShaderPtrData * fetch_ptr_parameter(const Shader::ShaderPtrSpec &spec)
Return a pointer to struct ShaderPtrData.
const LMatrix4 * fetch_specified_value(Shader::ShaderMatSpec &spec, int altered)
The gsg contains a large number of useful matrices:
Encodes a string name in a hash table, mapping it to a pointer.
Definition: internalName.h:38
get_basename
Return the name represented by just this particular InternalName object, ignoring its parents names.
Definition: internalName.h:62
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
The ShaderContext is meant to contain the compiled version of a shader string.
Definition: shaderContext.h:31
Definition: shader.h:49
ShaderLanguage get_language() const
Returns the shader language in which this shader was written.
Definition: shader.I:132
Filename get_filename(ShaderType type=ST_none) const
Return the Shader's filename for the given shader type.
Definition: shader.I:20
This is a special class object that holds all the information returned by a particular GSG to indicat...
Defines the properties of a named stage of the multitexture pipeline.
Definition: textureStage.h:35
get_texcoord_name
See set_texcoord_name.
Definition: textureStage.h:194
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
This class gives the ability for a user-friendly way of creating a vertex declaration for DirectX 9.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.