From cd79af53fe991893c867f4f466143bc2cc9b2db5 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 28 Sep 2011 18:42:58 +0000 Subject: [PATCH] dx9 shader support from zhao --- panda/src/display/graphicsStateGuardian.h | 4 + panda/src/dxgsg9/dxGeomMunger9.cxx | 30 + panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 1231 ++++++++--------- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 21 +- panda/src/dxgsg9/dxShaderContext9.cxx | 446 +++--- panda/src/dxgsg9/dxShaderContext9.h | 9 +- panda/src/dxgsg9/dxVertexBufferContext9.cxx | 289 +--- panda/src/dxgsg9/dxVertexBufferContext9.h | 24 +- panda/src/dxgsg9/vertexElementArray.cxx | 475 +++---- panda/src/dxgsg9/vertexElementArray.h | 68 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 2 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 2 +- panda/src/gobj/geomVertexArrayFormat.cxx | 2 +- panda/src/pgraphnodes/shaderGenerator.cxx | 7 +- .../tinydisplay/tinyGraphicsStateGuardian.cxx | 1 - .../tinydisplay/tinyGraphicsStateGuardian.h | 1 - 16 files changed, 1111 insertions(+), 1501 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 60940f7fcc..918b4c6664 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -360,7 +360,11 @@ protected: // This bitmask contains a 1 bit everywhere that _state_rs has a // known value. If a bit is 0, the corresponding state must be // re-sent. + // + // Derived GSGs should initialize _inv_state_mask in reset() as a mask of + // 1's where they don't care, and 0's where they do care, about the state. RenderState::SlotMask _state_mask; + RenderState::SlotMask _inv_state_mask; // The current transform, as of the last call to // set_state_and_transform(). diff --git a/panda/src/dxgsg9/dxGeomMunger9.cxx b/panda/src/dxgsg9/dxGeomMunger9.cxx index 80f51536a0..886ffd2af5 100755 --- a/panda/src/dxgsg9/dxGeomMunger9.cxx +++ b/panda/src/dxgsg9/dxGeomMunger9.cxx @@ -174,6 +174,21 @@ munge_format_impl(const GeomVertexFormat *orig, } } + // Now go through the remaining arrays and make sure they are + // tightly packed. If not, repack them. + for (int i = 0; i < new_format->get_num_arrays(); ++i) { + CPT(GeomVertexArrayFormat) orig_a = new_format->get_array(i); + if (orig_a->count_unused_space() != 0) { + PT(GeomVertexArrayFormat) new_a = new GeomVertexArrayFormat; + for (int j = 0; j < orig_a->get_num_columns(); ++j) { + const GeomVertexColumn *column = orig_a->get_column(j); + new_a->add_column(column->get_name(), column->get_num_components(), + column->get_numeric_type(), column->get_contents()); + } + new_format->set_array(i, new_a); + } + } + // Make sure the FVF-style array we just built up is first in the // list. new_format->insert_array(0, new_array_format); @@ -268,6 +283,21 @@ premunge_format_impl(const GeomVertexFormat *orig) { } } + // Now go through the remaining arrays and make sure they are + // tightly packed. If not, repack them. + for (int i = 0; i < new_format->get_num_arrays(); ++i) { + CPT(GeomVertexArrayFormat) orig_a = new_format->get_array(i); + if (orig_a->count_unused_space() != 0) { + PT(GeomVertexArrayFormat) new_a = new GeomVertexArrayFormat; + for (int j = 0; j < orig_a->get_num_columns(); ++j) { + const GeomVertexColumn *column = orig_a->get_column(j); + new_a->add_column(column->get_name(), column->get_num_components(), + column->get_numeric_type(), column->get_contents()); + } + new_format->set_array(i, new_a); + } + } + // Make sure the FVF-style array we just built up is first in the // list. new_format->insert_array(0, new_array_format); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 60d5318a98..6525b6685f 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -116,7 +116,6 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) : _overlay_windows_supported = false; _tex_stats_retrieval_impossible = false; - _active_vbuffer = NULL; _active_ibuffer = NULL; // This is a static member, but we initialize it here in the @@ -131,21 +130,12 @@ DXGraphicsStateGuardian9(GraphicsEngine *engine, GraphicsPipe *pipe) : // they copy framebuffer-to-texture. Ok. _copy_texture_inverted = true; - // D3DRS_POINTSPRITEENABLE doesn't seem to support remapping the - // texture coordinates via a texture matrix, so we don't advertise - // GR_point_sprite_tex_matrix. - _supported_geom_rendering = - Geom::GR_point | Geom::GR_point_uniform_size | - Geom::GR_point_perspective | Geom::GR_point_sprite | - Geom::GR_indexed_other | - Geom::GR_triangle_strip | Geom::GR_triangle_fan | - Geom::GR_flat_first_vertex; - _gsg_managed_textures = dx_management | dx_texture_management; _gsg_managed_vertex_buffers = dx_management; _gsg_managed_index_buffers = dx_management; _last_fvf = 0; + _num_bound_streams = 0; _vertex_shader_version_major = 0; _vertex_shader_version_minor = 0; @@ -464,10 +454,52 @@ release_shader(ShaderContext *sc) { // This function should not be called directly to // prepare a buffer. Instead, call Geom::prepare(). //////////////////////////////////////////////////////////////////// -VertexBufferContext *DXGraphicsStateGuardian9:: +VertexBufferContext *CLP(GraphicsStateGuardian):: prepare_vertex_buffer(GeomVertexArrayData *data) { - DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(_prepared_objects, data, *(this -> _screen)); - return dvbc; + CLP(VertexBufferContext) *dvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data); + + DWORD usage; + D3DPOOL pool; + if (_screen->_managed_vertex_buffers) { + pool = D3DPOOL_MANAGED; + usage = D3DUSAGE_WRITEONLY; + } else { + pool = D3DPOOL_DEFAULT; + usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC; + } + + int num_bytes = data->get_data_size_bytes(); + + PStatTimer timer(_create_vertex_buffer_pcollector, Thread::get_current_thread()); + + HRESULT hr; + int attempts = 0; + do + { + hr = _screen->_d3d_device->CreateVertexBuffer(num_bytes, usage, dvbc->_fvf, pool, &dvbc->_vbuffer, NULL); + attempts++; + } + while (check_dx_allocation(hr, num_bytes, attempts)); + + if (!FAILED(hr)) { + #if 0 + if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) { + dxgsg9_cat.debug() + << "creating vertex buffer " << dvbc->_vbuffer << ": " + << data->get_num_rows() << " vertices " + << *data->get_array_format() << "\n"; + } + #endif + + return dvbc; + } else { + dxgsg9_cat.error() + << "CreateVertexBuffer failed" << D3DERRORSTRING(hr); + + dvbc->_vbuffer = NULL; + } + + return NULL; } //////////////////////////////////////////////////////////////////// @@ -476,194 +508,62 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // Description: Updates the vertex buffer with the current data, and // makes it the current vertex buffer for rendering. //////////////////////////////////////////////////////////////////// -bool DXGraphicsStateGuardian9:: +bool CLP(GraphicsStateGuardian):: apply_vertex_buffer(VertexBufferContext *vbc, - CLP(ShaderContext) *shader_context, - const GeomVertexArrayDataHandle *reader, - bool force, - string name) { - DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc); + const GeomVertexArrayDataHandle *reader, bool force ) { - bool set_stream_source; - HRESULT hr; - UINT stream; - UINT offset; + CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc); - set_stream_source = false; - stream = 0; - offset = 0; - - if (dvbc->_vbuffer == NULL) { - // Attempt to create a new vertex buffer. - if (vertex_buffers && - reader->get_usage_hint() != Geom::UH_client) { - dvbc->create_vbuffer(*_screen, reader, name); + if (dvbc->was_modified(reader)) { + int num_bytes = reader->get_data_size_bytes(); + #if 0 + if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) { + dxgsg9_cat.debug() + << "copying " << num_bytes + << " bytes into vertex buffer " << dvbc->_vbuffer << "\n"; } + #endif - if (dvbc->_vbuffer != NULL) { - if (!dvbc->upload_data(reader, force)) { + if ( num_bytes != 0 ) { + const unsigned char *client_pointer = reader->get_read_pointer(force); + if (client_pointer == NULL) { return false; } - dvbc->mark_loaded(reader); + PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread()); - set_stream_source = true; - - } else { - _active_vbuffer = NULL; - } - - } else { - if (dvbc->was_modified(reader)) { + #if 0 if (dvbc->changed_size(reader)) { // We have to destroy the old vertex buffer and create a new // one. - dvbc->create_vbuffer(*_screen, reader, name); + dvbc->create_vbuffer(*_screen, reader); } + #endif - if (!dvbc->upload_data(reader, force)) { + HRESULT hr; + BYTE *local_pointer; + if (_screen->_managed_vertex_buffers) { + hr = dvbc->_vbuffer->Lock(0, num_bytes, (void **) &local_pointer, 0); + } else { + hr = dvbc->_vbuffer->Lock(0, num_bytes, (void **) &local_pointer, D3DLOCK_DISCARD); + } + if (FAILED(hr)) { + dxgsg9_cat.error() + << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr); return false; } - dvbc->mark_loaded(reader); - _active_vbuffer = NULL; + memcpy(local_pointer, client_pointer, num_bytes); + + dvbc->_vbuffer->Unlock(); + + _data_transferred_pcollector.add_level(num_bytes); } - if (_active_vbuffer != dvbc) { - set_stream_source = true; - } + dvbc->mark_loaded(reader); } dvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru); - if (shader_context == 0) { - // FVF MODE - if (set_stream_source) { - hr = _d3d_device->SetStreamSource - (stream, dvbc->_vbuffer, offset, reader->get_array_format()->get_stride()); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "SetStreamSource failed" << D3DERRORSTRING(hr); - } - _active_vbuffer = dvbc; - _active_ibuffer = NULL; - dvbc->set_active(true); - } - - if ((dvbc->_fvf != _last_fvf)) { - hr = _d3d_device->SetFVF(dvbc->_fvf); - if (FAILED(hr)) { - dxgsg9_cat.error() << "SetFVF failed" << D3DERRORSTRING(hr); - } - - _last_fvf = dvbc->_fvf; - } - } - else { - // SHADER MODE - if (set_stream_source) { - if (dvbc -> _direct_3d_vertex_declaration) { - if (dvbc -> _shader_context == shader_context) { - // same shader as before, no need to remap a new vertex declaration - } - else { - // need to make a new vertex declaration since the new shader may - // have a different mapping - dvbc -> _direct_3d_vertex_declaration -> Release ( ); - dvbc -> _direct_3d_vertex_declaration = 0; - dvbc -> _shader_context = 0; - } - } - - if (dvbc -> _direct_3d_vertex_declaration == 0 && - dvbc -> _vertex_element_type_array) { - VertexElementArray *vertex_element_array; - - vertex_element_array = shader_context -> _vertex_element_array; - if (vertex_element_array) { - int index; - - for (index = 0; index < vertex_element_array->total_elements; index++) { - VERTEX_ELEMENT_TYPE *vertex_element_type; - VERTEX_ELEMENT_TYPE *source_vertex_element_type; - - vertex_element_type = - &vertex_element_array -> vertex_element_type_array [index]; - - // MAP VERTEX ELEMENTS to VERTEX SHADER INPUTS - // get offsets from vertex data for certain types of vertex elements - - offset = 0; - source_vertex_element_type = dvbc -> _vertex_element_type_array; - while (source_vertex_element_type -> vs_input_type != VS_END) { - if (source_vertex_element_type -> vs_input_type == vertex_element_type -> vs_input_type && - source_vertex_element_type -> index == vertex_element_type -> index) { - offset = source_vertex_element_type -> offset; - break; - } - source_vertex_element_type++; - } - if (source_vertex_element_type -> vs_input_type == VS_END) { - dxgsg9_cat.error() - << "unable to find a mapping for vertex shader input type=" - << vertex_element_type -> vs_input_type - << " from vertex elements\n"; - } - - vertex_element_array -> set_vertex_element_offset (index, offset); - } - - hr = _d3d_device -> CreateVertexDeclaration ( - vertex_element_array -> vertex_element_array, - &dvbc -> _direct_3d_vertex_declaration); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "CreateVertexDeclaration failed" - << D3DERRORSTRING(hr); - - if (0) { - // DEBUG - printf ("TOTAL ELEMENTS: %d \n", vertex_element_array -> total_elements); - for (index = 0; index < vertex_element_array -> total_elements; index++) - { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - vertex_element = &vertex_element_array -> vertex_element_array [index]; - vertex_element_type = &vertex_element_array -> vertex_element_type_array [index]; - - printf (" index %d Stream %d Offset %d Type %d Method %d Usage %d UsageIndex %d \n", index, vertex_element -> Stream, vertex_element -> Offset, vertex_element -> Type, vertex_element -> Method, vertex_element -> Usage, vertex_element -> UsageIndex); - } - } - } - - dvbc -> _shader_context = shader_context; - } - else { - dxgsg9_cat.error() << "apply_vertex_buffer ( ): shader_context vertex_element_array == 0\n"; - } - } - - offset = 0; - hr = _d3d_device->SetStreamSource - (stream, dvbc->_vbuffer, offset, reader->get_array_format()->get_stride()); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "SetStreamSource failed" << D3DERRORSTRING(hr); - } - _active_vbuffer = dvbc; - _active_ibuffer = NULL; - dvbc->set_active(true); - } - - if (dvbc -> _direct_3d_vertex_declaration) { - hr = _d3d_device -> SetVertexDeclaration (dvbc -> _direct_3d_vertex_declaration); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "SetVertexDeclaration failed" << D3DERRORSTRING(hr); - } - } - } - return true; } @@ -675,12 +575,58 @@ apply_vertex_buffer(VertexBufferContext *vbc, // directly; instead, call Data::release() (or simply // let the Data destruct). //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: +void CLP(GraphicsStateGuardian):: release_vertex_buffer(VertexBufferContext *vbc) { - DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc); + + CLP(VertexBufferContext) *dvbc = DCAST(CLP(VertexBufferContext), vbc); + + #if 0 + if (dxgsg9_cat.is_debug() && CLP(debug_buffers)) { + dxgsg9_cat.debug() + << "deleting vertex buffer " << dvbc->_vbuffer << "\n"; + } + #endif + + dvbc->_vbuffer->Release(); + dvbc->_vbuffer = NULL; + delete dvbc; } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::setup_array_data +// Access: Public +// Description: 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. +// +// If the buffer object is bound, this function sets +// client_pointer to NULL (representing the start of the +// buffer object in server memory); if the buffer object +// is not bound, this function sets client_pointer the +// pointer to the data array in client memory, that is, +// the data array passed in. +// +// If force is not true, the function may return false +// indicating the data is not currently available. +//////////////////////////////////////////////////////////////////// +bool CLP(GraphicsStateGuardian):: +setup_array_data(CLP(VertexBufferContext)*& dvbc, + const GeomVertexArrayDataHandle* array_reader, + bool force) { + + // Prepare the buffer object and bind it. + VertexBufferContext* vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this); + nassertr(vbc != (VertexBufferContext *)NULL, false); + if (!apply_vertex_buffer(vbc, array_reader, force)) { + return false; + } + + dvbc = (CLP(VertexBufferContext)*)vbc; + return true; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::prepare_index_buffer // Access: Public, Virtual @@ -865,6 +811,14 @@ clear(DrawableRegion *clearable) { DWORD main_flags = 0; DWORD aux_flags = 0; + if ((!clearable->get_clear_color_active())&& + (!clearable->get_clear_depth_active())&& + (!clearable->get_clear_stencil_active())) { + return; + } + + set_state_and_transform(RenderState::make_empty(), _internal_transform); + D3DCOLOR color_clear_value = Colorf_to_D3DCOLOR(clearable->get_clear_color()); float depth_clear_value = clearable->get_clear_depth(); DWORD stencil_clear_value = (DWORD)(clearable->get_clear_stencil()); @@ -1252,148 +1206,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, } nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false); - string name; - const Geom *geom; - - name = ""; - geom = geom_reader -> get_object ( ); - if (geom) - { - CPT(GeomVertexData) geom_vertex_data; - geom_vertex_data = geom -> get_vertex_data(); - - name = geom_vertex_data -> get_name(); - -// cout << name << "\n"; - } - - -// SHADER - if (_vertex_array_shader_context==0) { - if (_current_shader_context==0) { -// ????? update_standard_vertex_arrays(); - } else { -// ????? disable_standard_vertex_arrays(); - _current_shader_context->update_shader_vertex_arrays(NULL,this); - } - } else { - if (_current_shader_context==0) { - _vertex_array_shader_context->disable_shader_vertex_arrays(this); -// ????? update_standard_vertex_arrays(); - } else { - _current_shader_context-> - update_shader_vertex_arrays(_vertex_array_shader_context,this); - } - } - _vertex_array_shader = _current_shader; - _vertex_array_shader_context = _current_shader_context; - - const GeomVertexFormat *format = _data_reader->get_format ( ); - const GeomVertexArrayDataHandle *data = NULL; - int number_of_arrays = _data_reader -> get_num_arrays ( ); - - if (_current_shader_context && number_of_arrays > 1) { - - // find a matching vertex format for the vertex shader's input if possible - VertexElementArray *vertex_element_array; - - vertex_element_array = _current_shader_context -> _vertex_element_array; - if (vertex_element_array) - { - bool match; - bool multiple_matches; - int index; - int first_index; - - match = false; - multiple_matches = false; - first_index = -1; - - // quick check for a match - // find the one array with the minimum number of elements if possible - { - for (index = 0; index < number_of_arrays; index++) { - data = _data_reader -> get_array_reader (index); - - const GeomVertexArrayFormat *array_format = data->get_array_format(); - int number_of_columns = array_format->get_num_columns(); - - if (number_of_columns >= vertex_element_array -> total_elements) { - if (first_index >= 0) { - multiple_matches = true; - } - else { - first_index = index; - } - } - } - } - - if (multiple_matches) - { - // ugh slow, need to find which one - for (index = first_index; index < number_of_arrays; index++) - { - data = _data_reader -> get_array_reader (index); - - const GeomVertexArrayFormat *array_format = data->get_array_format(); - int number_of_columns = array_format->get_num_columns(); - - if (number_of_columns >= vertex_element_array -> total_elements) - { - - // check not implemented yet - dxgsg9_cat.error ( ) << "vertex_element_type_array check not implemented yet\n"; - - // build a vertex_element_type_array from data - - // compare both vertex_element_type_array for a match - vertex_element_array -> vertex_element_type_array; - } - } - - // since the check is not implemented yet use first_index for now - data = _data_reader -> get_array_reader (first_index); - - match = true; - } - else - { - if (first_index >= 0) { - data = _data_reader -> get_array_reader (first_index); - match = true; - } - } - - if (match) { - - } - else { - // ERROR - dxgsg9_cat.error ( ) << "could not find matching vertex element data for vertex shader\n"; - - // just use the 0 array - data = _data_reader->get_array_reader(0); - } - } - else { - // ERROR - dxgsg9_cat.error ( ) << "_current_shader_context -> _vertex_element_array == 0\n"; - } - } - else { - // The munger should have put the FVF data in the first array. - data = _data_reader->get_array_reader(0); - } - - nassertr(data != (GeomVertexArrayDataHandle *)NULL, false); - GeomVertexArrayData *data_obj = (GeomVertexArrayData *)data->get_object(); - nassertr(data_obj != (GeomVertexArrayData *)NULL, false); - VertexBufferContext *vbc = data_obj->prepare_now(get_prepared_objects(), this); - nassertr(vbc != (VertexBufferContext *)NULL, false); - if (!apply_vertex_buffer(vbc, _current_shader_context, data, force, name)) { - return false; - } + const GeomVertexFormat *format = _data_reader->get_format(); const GeomVertexAnimationSpec &animation = data_reader->get_format()->get_animation(); @@ -1477,9 +1290,104 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, _d3d_device->SetTransform(D3DTS_PROJECTION, (const D3DMATRIX *)rescale_mat.get_data()); } + if (_current_shader_context == 0 /*|| !_current_shader_context->uses_custom_vertex_arrays()*/) { + // No shader, or a non-Cg shader. + if (_vertex_array_shader_context != 0) { + _vertex_array_shader_context->disable_shader_vertex_arrays(this); + } + if (!update_standard_vertex_arrays(force)) { + return false; + } + } else { + // Cg shader. + if (_vertex_array_shader_context == 0) { + disable_standard_vertex_arrays(); + if (!_current_shader_context->update_shader_vertex_arrays(NULL, this, force)) { + return false; + } + } else { + if (!_current_shader_context-> + update_shader_vertex_arrays(_vertex_array_shader_context, this, force)) { + return false; + } + } + } + + _vertex_array_shader = _current_shader; + _vertex_array_shader_context = _current_shader_context; + return true; } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::update_standard_vertex_arrays +// Access: Protected +// Description: Binds vertex buffers as stream sources and sets the +// correct FVF format for fixed-function rendering. +// Used only when the standard (non-shader) pipeline +// is about to be used - dxShaderContexts are responsible +// for setting up their own vertex arrays. +//////////////////////////////////////////////////////////////////// +bool CLP(GraphicsStateGuardian):: +update_standard_vertex_arrays(bool force) { + + int fvf = 0; + HRESULT hr; + + int number_of_arrays = _data_reader->get_num_arrays(); + for ( int array_index = 0; array_index < number_of_arrays; ++array_index ) { + const GeomVertexArrayDataHandle* array_reader = _data_reader->get_array_reader( array_index ); + if ( array_reader == NULL ) { + dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n"; + return false; + } + + // Get the vertex buffer for this array. + CLP(VertexBufferContext)* dvbc; + if (!setup_array_data(dvbc, array_reader, force)) { + dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n"; + return false; + } + + // Bind this array as the data source for the corresponding stream. + const GeomVertexArrayFormat* array_format = array_reader->get_array_format(); + hr = _d3d_device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() ); + if (FAILED(hr)) { + dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr); + return false; + } + + // Update our combined set of FVF flags + fvf |= dvbc->_fvf; + } + + hr = _d3d_device->SetFVF( fvf ); + if (FAILED(hr)) { + dxgsg9_cat.error() << "SetFVF failed" << D3DERRORSTRING(hr); + return false; + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::disable_standard_vertex_arrays +// Access: Protected +// Description: Unbinds all of the streams that are currently enabled. +// dxShaderContexts are responsible for setting up their +// own streams, but before they can do so, the standard +// streams need to be disabled to get them "out of the +// way." Called only from begin_draw_primitives. +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +disable_standard_vertex_arrays() { + for ( int array_index = 0; array_index < _num_bound_streams; ++array_index ) + { + _d3d_device->SetStreamSource( array_index, NULL, 0, 0 ); + } + _num_bound_streams = 0; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::draw_triangles // Access: Public, Virtual @@ -1491,65 +1399,59 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { _vertices_tri_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_tri_pcollector.add_level(1); + if (reader->is_indexed()) { int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex(); int max_vertex = reader->get_max_vertex(); - if (_active_vbuffer != NULL) { - // Indexed, vbuffers. - IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, false); - if (!apply_index_buffer(ibc, reader, force)) { - return false; - } - - _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLELIST, 0, - min_vertex, max_vertex - min_vertex + 1, - 0, reader->get_num_primitives()); - - } else { - // Indexed, client arrays. - - const unsigned char *index_pointer = reader->get_read_pointer(force); - if (index_pointer == NULL) { - return false; - } - D3DFORMAT index_type = get_index_type(reader->get_index_type()); - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - draw_indexed_primitive_up - (D3DPT_TRIANGLELIST, - min_vertex, max_vertex, - reader->get_num_primitives(), - index_pointer, index_type, vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + // Indexed, vbuffers. + IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; } + + _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, + 0, + min_vertex, max_vertex - min_vertex + 1, + 0, reader->get_num_primitives() ); + + #if 0 + // Indexed, client arrays. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } + D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + + draw_indexed_primitive_up( D3DPT_TRIANGLELIST, + min_vertex, max_vertex, + reader->get_num_primitives(), + index_pointer, index_type, vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride() ); + #endif } else { - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers. + // Nonindexed, vbuffers. + _d3d_device->DrawPrimitive( D3DPT_TRIANGLELIST, + reader->get_first_vertex(), + reader->get_num_primitives() ); - _d3d_device->DrawPrimitive - (D3DPT_TRIANGLELIST, - reader->get_first_vertex(), - reader->get_num_primitives()); - - } else { - // Nonindexed, client arrays. - - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(), - reader->get_first_vertex(), - reader->get_num_vertices(), vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + #if 0 + // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; } + + draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(), + reader->get_first_vertex(), + reader->get_num_vertices(), vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif } return true; @@ -1569,75 +1471,64 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { // that have already been set up within the primitive. _vertices_tristrip_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_tristrip_pcollector.add_level(1); + if (reader->is_indexed()) { int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex(); int max_vertex = reader->get_max_vertex(); - if (_active_vbuffer != NULL) { - // Indexed, vbuffers, one line triangle strip. - IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, false); - if (!apply_index_buffer(ibc, reader, force)) { - return false; - } - -//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n"; - - _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLESTRIP, 0, - min_vertex, max_vertex - min_vertex + 1, - 0, reader->get_num_vertices() - 2); - - } else { - -//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n"; - - // Indexed, client arrays, one long triangle strip. - const unsigned char *index_pointer = reader->get_read_pointer(force); - if (index_pointer == NULL) { - return false; - } - D3DFORMAT index_type = get_index_type(reader->get_index_type()); - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - draw_indexed_primitive_up - (D3DPT_TRIANGLESTRIP, - min_vertex, max_vertex, - reader->get_num_vertices() - 2, - index_pointer, index_type, vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + // Indexed, vbuffers, one long triangle strip. + IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; } + + _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, + 0, + min_vertex, max_vertex - min_vertex + 1, + 0, reader->get_num_vertices() - 2 ); + + #if 0 + // Indexed, client arrays, one long triangle strip. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } + D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + + draw_indexed_primitive_up + (D3DPT_TRIANGLESTRIP, + min_vertex, max_vertex, + reader->get_num_vertices() - 2, + index_pointer, index_type, vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif } else { - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers, one long triangle strip. + // Nonindexed, vbuffers, one long triangle strip. + _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP, + reader->get_first_vertex(), + reader->get_num_vertices() - 2 ); -//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << reader->get_first_vertex ( ) << " VERTICES: " << reader->get_num_vertices ( ) << "\n"; - - _d3d_device->DrawPrimitive - (D3DPT_TRIANGLESTRIP, - reader->get_first_vertex(), - reader->get_num_vertices() - 2); - - } else { - // Indexed, client arrays, one long triangle strip. - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - draw_primitive_up(D3DPT_TRIANGLESTRIP, - reader->get_num_vertices() - 2, - reader->get_first_vertex(), - reader->get_num_vertices(), vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + #if 0 + // Indexed, client arrays, one long triangle strip. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; } + draw_primitive_up(D3DPT_TRIANGLESTRIP, + reader->get_num_vertices() - 2, + reader->get_first_vertex(), + reader->get_num_vertices(), vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif } } else { - // Send the individual triangle strips, stepping over the - // degenerate vertices. + // Send the individual triangle strips, stepping over the degenerate vertices. CPTA_int ends = reader->get_ends(); _primitive_batches_tristrip_pcollector.add_level(ends.size()); @@ -1651,90 +1542,85 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) { nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && reader->get_maxs()->get_num_rows() == (int)ends.size(), false); - if (_active_vbuffer != NULL) { - // Indexed, vbuffers, individual triangle strips. - IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, false); - if (!apply_index_buffer(ibc, reader, force)) { - return false; - } - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_tristrip_pcollector.add_level(ends[i] - start); - unsigned int min = mins.get_data1i(); - unsigned int max = maxs.get_data1i(); - _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLESTRIP, - 0, - min, max - min + 1, - start, ends[i] - start - 2); - - start = ends[i] + 2; - } - - } else { - // Indexed, client arrays, individual triangle strips. - int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *index_pointer = reader->get_read_pointer(force); - if (index_pointer == NULL) { - return false; - } - D3DFORMAT index_type = get_index_type(reader->get_index_type()); - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_tristrip_pcollector.add_level(ends[i] - start); - unsigned int min = mins.get_data1i(); - unsigned int max = maxs.get_data1i(); - draw_indexed_primitive_up - (D3DPT_TRIANGLESTRIP, - min, max, - ends[i] - start - 2, - index_pointer + start * index_stride, index_type, - vertex_pointer, stride); - - start = ends[i] + 2; - } + // Indexed, vbuffers, individual triangle strips. + IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; } + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_tristrip_pcollector.add_level(ends[i] - start); + unsigned int min = mins.get_data1i(); + unsigned int max = maxs.get_data1i(); + _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, + 0, + min, max - min + 1, + start, ends[i] - start - 2 ); + start = ends[i] + 2; + } + + #if 0 + // Indexed, client arrays, individual triangle strips. + int stride = _data_reader->get_format()->get_array(0)->get_stride(); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } + D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_tristrip_pcollector.add_level(ends[i] - start); + unsigned int min = mins.get_data1i(); + unsigned int max = maxs.get_data1i(); + draw_indexed_primitive_up + (D3DPT_TRIANGLESTRIP, + min, max, + ends[i] - start - 2, + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); + + start = ends[i] + 2; + } + #endif } else { unsigned int first_vertex = reader->get_first_vertex(); - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers, individual triangle strips. - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_tristrip_pcollector.add_level(ends[i] - start); - _d3d_device->DrawPrimitive - (D3DPT_TRIANGLESTRIP, - first_vertex + start, ends[i] - start - 2); - - start = ends[i] + 2; - } - - } else { - // Nonindexed, client arrays, individual triangle strips. - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - int stride = _data_reader->get_format()->get_array(0)->get_stride(); - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_tristrip_pcollector.add_level(ends[i] - start); - draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2, - first_vertex + start, - ends[i] - start, - vertex_pointer, stride); - - start = ends[i] + 2; - } + // Nonindexed, vbuffers, individual triangle strips. + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_tristrip_pcollector.add_level(ends[i] - start); + _d3d_device->DrawPrimitive( D3DPT_TRIANGLESTRIP, + first_vertex + start, + ends[i] - start - 2 ); + start = ends[i] + 2; } + + #if 0 + // Nonindexed, client arrays, individual triangle strips. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + int stride = _data_reader->get_format()->get_array(0)->get_stride(); + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_tristrip_pcollector.add_level(ends[i] - start); + draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2, + first_vertex + start, + ends[i] - start, + vertex_pointer, stride); + + start = ends[i] + 2; + } + #endif } } return true; @@ -1765,89 +1651,85 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() && reader->get_maxs()->get_num_rows() == (int)ends.size(), false); - if (_active_vbuffer != NULL) { - // Indexed, vbuffers. - IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, false); - if (!apply_index_buffer(ibc, reader, force)) { - return false; - } - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_trifan_pcollector.add_level(ends[i] - start); - unsigned int min = mins.get_data1i(); - unsigned int max = maxs.get_data1i(); - _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLEFAN, 0, - min, max - min + 1, - start, ends[i] - start - 2); - - start = ends[i]; - } - - } else { - // Indexed, client arrays. - int stride = _data_reader->get_format()->get_array(0)->get_stride(); - const unsigned char *index_pointer = reader->get_read_pointer(force); - if (index_pointer == NULL) { - return false; - } - D3DFORMAT index_type = get_index_type(reader->get_index_type()); - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_trifan_pcollector.add_level(ends[i] - start); - unsigned int min = mins.get_data1i(); - unsigned int max = maxs.get_data1i(); - draw_indexed_primitive_up - (D3DPT_TRIANGLEFAN, - min, max, - ends[i] - start - 2, - index_pointer + start * index_stride, index_type, - vertex_pointer, stride); - - start = ends[i]; - } + // Indexed, vbuffers. + IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; } + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_trifan_pcollector.add_level(ends[i] - start); + unsigned int min = mins.get_data1i(); + unsigned int max = maxs.get_data1i(); + _d3d_device->DrawIndexedPrimitive( D3DPT_TRIANGLEFAN, + 0, + min, max - min + 1, + start, ends[i] - start - 2 ); + start = ends[i]; + } + + #if 0 + // Indexed, client arrays. + int stride = _data_reader->get_format()->get_array(0)->get_stride(); + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } + D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_trifan_pcollector.add_level(ends[i] - start); + unsigned int min = mins.get_data1i(); + unsigned int max = maxs.get_data1i(); + draw_indexed_primitive_up + (D3DPT_TRIANGLEFAN, + min, max, + ends[i] - start - 2, + index_pointer + start * index_stride, index_type, + vertex_pointer, stride); + + start = ends[i]; + } + #endif } else { unsigned int first_vertex = reader->get_first_vertex(); - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers. - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_trifan_pcollector.add_level(ends[i] - start); - _d3d_device->DrawPrimitive - (D3DPT_TRIANGLEFAN, - first_vertex + start, ends[i] - start - 2); - - start = ends[i]; - } - - } else { - // Nonindexed, client arrays. - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - int stride = _data_reader->get_format()->get_array(0)->get_stride(); - - unsigned int start = 0; - for (size_t i = 0; i < ends.size(); i++) { - _vertices_trifan_pcollector.add_level(ends[i] - start); - draw_primitive_up(D3DPT_TRIANGLEFAN, - ends[i] - start - 2, - first_vertex, - ends[i] - start, - vertex_pointer, stride); - start = ends[i]; - } + // Nonindexed, vbuffers. + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_trifan_pcollector.add_level(ends[i] - start); + _d3d_device->DrawPrimitive( D3DPT_TRIANGLEFAN, + first_vertex + start, + ends[i] - start - 2 ); + start = ends[i]; } + + #if 0 + // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + int stride = _data_reader->get_format()->get_array(0)->get_stride(); + + unsigned int start = 0; + for (size_t i = 0; i < ends.size(); i++) { + _vertices_trifan_pcollector.add_level(ends[i] - start); + draw_primitive_up(D3DPT_TRIANGLEFAN, + ends[i] - start - 2, + first_vertex, + ends[i] - start, + vertex_pointer, stride); + start = ends[i]; + } + #endif } return true; } @@ -1860,6 +1742,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) { bool DXGraphicsStateGuardian9:: draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { //PStatTimer timer(_draw_primitive_pcollector); + _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1867,58 +1750,54 @@ draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex(); int max_vertex = reader->get_max_vertex(); - if (_active_vbuffer != NULL) { - // Indexed, vbuffers. - IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); - nassertr(ibc != (IndexBufferContext *)NULL, false); - if (!apply_index_buffer(ibc, reader, force)) { - return false; - } - - _d3d_device->DrawIndexedPrimitive - (D3DPT_LINELIST, - 0, - min_vertex, max_vertex - min_vertex + 1, - 0, reader->get_num_primitives()); - - } else { - // Indexed, client arrays. - const unsigned char *index_pointer = reader->get_read_pointer(force); - if (index_pointer == NULL) { - return false; - } - D3DFORMAT index_type = get_index_type(reader->get_index_type()); - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - - draw_indexed_primitive_up - (D3DPT_LINELIST, - min_vertex, max_vertex, - reader->get_num_primitives(), - index_pointer, index_type, vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + // Indexed, vbuffers. + IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this); + nassertr(ibc != (IndexBufferContext *)NULL, false); + if (!apply_index_buffer(ibc, reader, force)) { + return false; } + + _d3d_device->DrawIndexedPrimitive( D3DPT_LINELIST, + 0, + min_vertex, max_vertex - min_vertex + 1, + 0, reader->get_num_primitives() ); + + #if 0 + // Indexed, client arrays. + const unsigned char *index_pointer = reader->get_read_pointer(force); + if (index_pointer == NULL) { + return false; + } + D3DFORMAT index_type = get_index_type(reader->get_index_type()); + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; + } + + draw_indexed_primitive_up + (D3DPT_LINELIST, + min_vertex, max_vertex, + reader->get_num_primitives(), + index_pointer, index_type, vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif } else { - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers. - _d3d_device->DrawPrimitive - (D3DPT_LINELIST, - reader->get_first_vertex(), - reader->get_num_primitives()); + // Nonindexed, vbuffers. + _d3d_device->DrawPrimitive( D3DPT_LINELIST, + reader->get_first_vertex(), + reader->get_num_primitives() ); - } else { - // Nonindexed, client arrays. - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(), - reader->get_first_vertex(), - reader->get_num_vertices(), vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + #if 0 + // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; } + draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(), + reader->get_first_vertex(), + reader->get_num_vertices(), vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif } return true; } @@ -1941,6 +1820,7 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) { bool DXGraphicsStateGuardian9:: draw_points(const GeomPrimitivePipelineReader *reader, bool force) { //PStatTimer timer(_draw_primitive_pcollector); + _vertices_other_pcollector.add_level(reader->get_num_vertices()); _primitive_batches_other_pcollector.add_level(1); @@ -1948,24 +1828,23 @@ draw_points(const GeomPrimitivePipelineReader *reader, bool force) { // doesn't support them. nassertr(!reader->is_indexed(), false); - if (_active_vbuffer != NULL) { - // Nonindexed, vbuffers. - _d3d_device->DrawPrimitive - (D3DPT_POINTLIST, - reader->get_first_vertex(), - reader->get_num_primitives()); + // Nonindexed, vbuffers. + _d3d_device->DrawPrimitive( D3DPT_POINTLIST, + reader->get_first_vertex(), + reader->get_num_primitives() ); - } else { - // Nonindexed, client arrays. - const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); - if (vertex_pointer == NULL) { - return false; - } - draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(), - reader->get_first_vertex(), - reader->get_num_vertices(), vertex_pointer, - _data_reader->get_format()->get_array(0)->get_stride()); + #if 0 + // Nonindexed, client arrays. + const unsigned char *vertex_pointer = _data_reader->get_array_reader(0)->get_read_pointer(force); + if (vertex_pointer == NULL) { + return false; } + draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(), + reader->get_first_vertex(), + reader->get_num_vertices(), vertex_pointer, + _data_reader->get_format()->get_array(0)->get_stride()); + #endif + return true; } @@ -2385,6 +2264,42 @@ void DXGraphicsStateGuardian9:: reset() { GraphicsStateGuardian::reset(); + // Build _inv_state_mask as a mask of 1's where we don't care, and + // 0's where we do care, about the state. + _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot()); + _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ColorAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot()); + _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot()); + _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot()); + _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot()); + _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot()); + _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot()); + _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot()); + _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot()); + _inv_state_mask.clear_bit(TextureAttrib::get_class_slot()); + _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot()); + _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot()); + _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot()); + _inv_state_mask.clear_bit(LightAttrib::get_class_slot()); + _inv_state_mask.clear_bit(StencilAttrib::get_class_slot()); + _inv_state_mask.clear_bit(FogAttrib::get_class_slot()); + _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot()); + + // D3DRS_POINTSPRITEENABLE doesn't seem to support remapping the + // texture coordinates via a texture matrix, so we don't advertise + // GR_point_sprite_tex_matrix. + _supported_geom_rendering = + Geom::GR_point | Geom::GR_point_uniform_size | + Geom::GR_point_perspective | Geom::GR_point_sprite | + Geom::GR_indexed_other | + Geom::GR_triangle_strip | Geom::GR_triangle_fan | + Geom::GR_flat_first_vertex; + _auto_rescale_normal = false; // overwrite gsg defaults with these values @@ -3254,7 +3169,7 @@ set_state_and_transform(const RenderState *target, do_issue_transform(); } - if (target == _state_rs) { + if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) { return; } _target_rs = target; @@ -4224,7 +4139,7 @@ free_nondx_resources() { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: free_d3d_device() { - // don't want a full reset of gsg, just a state clear + // dont want a full reset of gsg, just a state clear _state_rs = RenderState::make_empty(); _state_mask.clear(); @@ -4247,7 +4162,7 @@ free_d3d_device() { free_nondx_resources(); - // obviously we don't release ID3D9, just ID3DDevice9 + // obviously we dont release ID3D9, just ID3DDevice9 } //////////////////////////////////////////////////////////////////// @@ -5738,7 +5653,7 @@ get_supports_cg_profile(const string &name) const { #else CGprofile profile = cgGetProfile(name.c_str()); - if (profile ==CG_PROFILE_UNKNOWN) { + if (profile == CG_PROFILE_UNKNOWN) { dxgsg9_cat.error() << name <<", unknown Cg-profile\n"; return false; } diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 17ffa8695b..0286938a0a 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -33,12 +33,6 @@ #include "lru.h" -typedef LPDIRECT3DDEVICE9 DIRECT_3D_DEVICE; -typedef D3DVERTEXELEMENT9 DIRECT_3D_VERTEX_ELEMENT; -typedef LPDIRECT3DVERTEXDECLARATION9 DIRECT_3D_VERTEX_DECLARATION; -typedef LPDIRECT3DVERTEXSHADER9 DIRECT_3D_VERTEX_SHADER; -typedef LPDIRECT3DPIXELSHADER9 DIRECT_3D_PIXEL_SHADER; - #include "vertexElementArray.h" #include "dxShaderContext9.h" @@ -83,10 +77,15 @@ public: void release_shader(ShaderContext *sc); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - bool apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context, - const GeomVertexArrayDataHandle *reader, bool force, string name); + bool apply_vertex_buffer(VertexBufferContext *vbc, + const GeomVertexArrayDataHandle *reader, + bool force); virtual void release_vertex_buffer(VertexBufferContext *vbc); + bool setup_array_data(CLP(VertexBufferContext)*& vbc, + const GeomVertexArrayDataHandle* data, + bool force); + virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); bool apply_index_buffer(IndexBufferContext *ibc, const GeomPrimitivePipelineReader *reader, bool force); @@ -206,8 +205,8 @@ protected: void do_auto_rescale_normal(); -// void disable_standard_vertex_arrays(); -// void update_standard_vertex_arrays(); + void disable_standard_vertex_arrays(); + bool update_standard_vertex_arrays(bool force); void disable_standard_texture_bindings(); void update_standard_texture_bindings(); @@ -301,7 +300,6 @@ protected: PT(Shader) _texture_binding_shader; CLP(ShaderContext) *_texture_binding_shader_context; - const DXVertexBufferContext9 *_active_vbuffer; const DXIndexBufferContext9 *_active_ibuffer; bool _overlay_windows_supported; @@ -320,6 +318,7 @@ protected: UINT _available_texture_memory; DWORD _last_fvf; + int _num_bound_streams; // Cache the data necessary to bind each particular light each // frame, so if we bind a given light multiple times, we only have diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index a883910872..1140589fc4 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -14,6 +14,7 @@ #include "dxGraphicsStateGuardian9.h" #include "dxShaderContext9.h" +#include "dxVertexBufferContext9.h" #include #include @@ -37,8 +38,11 @@ TypeHandle CLP(ShaderContext)::_type_handle; CLP(ShaderContext):: CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { - _vertex_size = 0; - _vertex_element_array = 0; + _vertex_element_array = NULL; + _vertex_declaration = NULL; + + _num_bound_streams = 0; + _name = s->get_filename ( ); #ifdef HAVE_CG @@ -131,9 +135,14 @@ CLP(ShaderContext):: ~CLP(ShaderContext)() { release_resources(); - if (_vertex_element_array) { + if ( _vertex_declaration != NULL ) { + _vertex_declaration->Release(); + _vertex_declaration = NULL; + } + + if ( _vertex_element_array != NULL ) { delete _vertex_element_array; - _vertex_element_array = 0; + _vertex_element_array = NULL; } } @@ -203,6 +212,10 @@ release_resources() { _cg_parameter_map.clear(); } #endif + + // I think we need to call SetStreamSource for _num_bound_streams -- basically the logic from + // disable_shader_vertex_arrays -- but to do that we need to introduce logic like the GL code + // has to manage _last_gsg, so we can get at the device. Sigh. } //////////////////////////////////////////////////////////////////// @@ -473,13 +486,14 @@ issue_parameters(GSG *gsg, int altered) // Description: Disable all the vertex arrays used by this shader. //////////////////////////////////////////////////////////////////// void CLP(ShaderContext):: -disable_shader_vertex_arrays(GSG *gsg) -{ -#ifdef HAVE_CG - if (_cg_context) { - // DO NOTHING, CURRENTLY USING ONLY ONE STREAM SOURCE +disable_shader_vertex_arrays(GSG *gsg) { + LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device; + + for ( int array_index = 0; array_index < _num_bound_streams; ++array_index ) + { + device->SetStreamSource( array_index, NULL, 0, 0 ); } -#endif + _num_bound_streams = 0; } //////////////////////////////////////////////////////////////////// @@ -493,221 +507,249 @@ disable_shader_vertex_arrays(GSG *gsg) // it may unnecessarily disable arrays then immediately // reenable them. We may optimize this someday. //////////////////////////////////////////////////////////////////// - -// DEBUG -#if DEBUG_SHADER -VertexElementArray *global_vertex_element_array = 0; -#endif - -void CLP(ShaderContext):: -update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) -{ +bool CLP(ShaderContext):: +update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) { if (prev) prev->disable_shader_vertex_arrays(gsg); #ifdef HAVE_CG - if (_cg_context) { + if (!_cg_context) { + return true; + } - #ifdef SUPPORT_IMMEDIATE_MODE +#ifdef SUPPORT_IMMEDIATE_MODE /* if (gsg->_use_sender) { dxgsg9_cat.error() << "immediate mode shaders not implemented yet\n"; } else */ - #endif // SUPPORT_IMMEDIATE_MODE - { - if (_vertex_element_array == 0) { - bool error; - const GeomVertexArrayDataHandle *array_reader; +#endif // SUPPORT_IMMEDIATE_MODE + { + int nvarying = _shader->_var_spec.size(); + LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device; + HRESULT hr; + + // Discard and recreate the VertexElementArray. This thrashes pretty bad.... + if ( _vertex_element_array != NULL ) { + delete _vertex_element_array; + } + _vertex_element_array = new VertexElementArray(nvarying + 2); + VertexElementArray* vertex_element_array = _vertex_element_array; + + // Experimentally determined that DX doesn't like us crossing the streams! + // It seems to be okay with out-of-order offsets in both source and destination, + // but it wants all stream X entries grouped together, then all stream Y entries, etc. + // To accomplish this out outer loop processes arrays ("streams"), and we repeatedly + // iterate the parameters to pull out only those for a single stream. + + int number_of_arrays = gsg->_data_reader->get_num_arrays(); + for ( int array_index = 0; array_index < number_of_arrays; ++array_index ) { + const GeomVertexArrayDataHandle* array_reader = + gsg->_data_reader->get_array_reader( array_index ); + if ( array_reader == NULL ) { + dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n"; + continue; + } + + for ( int var_index = 0; var_index < nvarying; ++var_index ) { + CGparameter p = _cg_parameter_map[_shader->_var_spec[var_index]._id._seqno]; + if ( p == NULL ) { + dxgsg9_cat.info() << + "No parameter in map for parameter " << var_index << + " (probably optimized away)\n"; + continue; + } + + InternalName *name = _shader->_var_spec[var_index]._name; + + // This is copied from the GL version of this function, and I've yet to 100% convince + // myself that it works properly.... + int texslot = _shader->_var_spec[var_index]._append_uv; + if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) { + TextureStage *stage = gsg->_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()); + } + } + + const GeomVertexArrayDataHandle* param_array_reader; Geom::NumericType numeric_type; - int start, stride, num_values; - int nvarying = _shader->_var_spec.size(); + int num_values; + int start; + int stride; + if ( gsg->_data_reader->get_array_info( name, + param_array_reader, num_values, numeric_type, + start, stride ) == false ) { + // This is apparently not an error (actually I think it is, just not a fatal one). + // + // The GL implementation fails silently in this case, but the net result is that we + // end up not supplying input for a shader parameter, which can cause Bad Things to + // happen so I'd like to at least get a hint as to what's gone wrong. + dxgsg9_cat.info() << "Geometry contains no data for shader parameter " << *name << "\n"; + continue; + } + + // If not associated with the array we're working on, move on. + if ( param_array_reader != array_reader ) { + continue; + } - int stream_index; - VertexElementArray *vertex_element_array; + const char* semantic = cgGetParameterSemantic( p ); + if ( semantic == NULL ) { + dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n"; + continue; + } - error = false; - // SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER? - stream_index = 0; - vertex_element_array = new VertexElementArray (nvarying + 2); - - #if DEBUG_SHADER - // DEBUG - global_vertex_element_array = vertex_element_array; - #endif - - for (int i=0; i_var_spec[i]._id._seqno]; - if (p == NULL) { - continue; - } - InternalName *name = _shader->_var_spec[i]._name; - int texslot = _shader->_var_spec[i]._append_uv; - if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) { - TextureStage *stage = gsg->_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 ( strncmp( semantic, "POSITION", strlen( "POSITION" ) ) == 0 ) { + if (numeric_type == Geom::NT_float32) { + switch (num_values) { + case 3: + vertex_element_array->add_position_xyz_vertex_element(array_index, start); + break; + case 4: + vertex_element_array->add_position_xyzw_vertex_element(array_index, start); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n"; + break; } - } - if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) { - - if (false) { - - } else if (name -> get_top ( ) == InternalName::get_vertex ( )) { - - if (numeric_type == Geom::NT_float32) { - switch (num_values) { - case 3: - vertex_element_array -> add_position_xyz_vertex_element (stream_index); - break; - case 4: - vertex_element_array -> add_position_xyzw_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid vertex type " << numeric_type << "\n"; - } - - } else if (name -> get_top ( ) == InternalName::get_texcoord ( )) { - - if (numeric_type == Geom::NT_float32) { - switch (num_values) - { - case 1: - vertex_element_array -> add_u_vertex_element (stream_index); - break; - case 2: - vertex_element_array -> add_uv_vertex_element (stream_index); - break; - case 3: - vertex_element_array -> add_uvw_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n"; - } - - } else if (name -> get_top ( ) == InternalName::get_normal ( )) { - - if (numeric_type == Geom::NT_float32) { - switch (num_values) - { - case 3: - vertex_element_array -> add_normal_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid normal type " << numeric_type << "\n"; - } - - } else if (name -> get_top ( ) == InternalName::get_binormal ( )) { - - if (numeric_type == Geom::NT_float32) { - switch (num_values) - { - case 3: - vertex_element_array -> add_binormal_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid binormal type " << numeric_type << "\n"; - } - - } else if (name -> get_top ( ) == InternalName::get_tangent ( )) { - - if (numeric_type == Geom::NT_float32) { - switch (num_values) - { - case 3: - vertex_element_array -> add_tangent_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid tangent type " << numeric_type << "\n"; - } - - } else if (name -> get_top ( ) == InternalName::get_color ( )) { - - if (numeric_type == Geom::NT_packed_dcba || - numeric_type == Geom::NT_packed_dabc || - numeric_type == Geom::NT_uint8) { - switch (num_values) - { - case 4: - vertex_element_array -> add_diffuse_color_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VE ERROR: invalid color coordinates " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VE ERROR: invalid color type " << numeric_type << "\n"; - } - - } else { - dxgsg9_cat.error ( ) << "VE ERROR: unsupported vertex element " << name -> get_name ( ) << "\n"; - } - } else { - dxgsg9_cat.error ( ) - << "get_array_info ( ) failed for shader " - << _name - << "\n" - << " vertex element name = " - << name -> get_name ( ) - << "\n"; - error = true; + dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n"; } - } - - if (error) { - delete vertex_element_array; - } - else { - int state; - - state = vertex_element_array -> add_end_vertex_element ( ); - if (state) { - if (_cg_context) { - if (cgD3D9ValidateVertexDeclaration (_cg_vprogram, - vertex_element_array -> vertex_element_array) == CG_TRUE) { - dxgsg9_cat.debug() << "|||||cgD3D9ValidateVertexDeclaration succeeded\n"; - } - else { - } + } else if ( strncmp( semantic, "TEXCOORD", strlen( "TEXCOORD" ) ) == 0 ) { + int slot = atoi( semantic + strlen( "TEXCOORD" ) ); + if (numeric_type == Geom::NT_float32) { + switch (num_values) { + case 1: + vertex_element_array->add_u_vertex_element(array_index, start, slot); + break; + case 2: + vertex_element_array->add_uv_vertex_element(array_index, start, slot); + break; + case 3: + vertex_element_array->add_uvw_vertex_element(array_index, start, slot); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; + break; } - else { - + } else { + dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n"; + } + } else if ( strncmp( semantic, "COLOR", strlen( "COLOR" ) ) == 0 ) { + if (numeric_type == Geom::NT_packed_dcba || + numeric_type == Geom::NT_packed_dabc || + numeric_type == Geom::NT_uint8) { + switch (num_values) { + case 4: + vertex_element_array->add_diffuse_color_vertex_element(array_index, start); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n"; + break; } - - _vertex_size = vertex_element_array -> offset; - _vertex_element_array = vertex_element_array; + } else { + dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n"; } - else { - dxgsg9_cat.error ( ) << "VertexElementArray creation failed\n"; - delete vertex_element_array; + } else if ( strncmp( semantic, "NORMAL", strlen( "NORMAL" ) ) == 0 ) { + if (numeric_type == Geom::NT_float32) { + switch (num_values) { + case 3: + vertex_element_array->add_normal_vertex_element(array_index, start); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid number of normal coordinate elements " << num_values << "\n"; + break; + } + } else { + dxgsg9_cat.error() << "VE ERROR: invalid normal type " << numeric_type << "\n"; } + } else if ( strncmp( semantic, "BINORMAL", strlen( "BINORMAL" ) ) == 0 ) { + if (numeric_type == Geom::NT_float32) { + switch (num_values) { + case 3: + vertex_element_array->add_binormal_vertex_element(array_index, start); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid number of binormal coordinate elements " << num_values << "\n"; + break; + } + } else { + dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n"; + } + } else if ( strncmp( semantic, "TANGENT", strlen( "TANGENT" ) ) == 0 ) { + if (numeric_type == Geom::NT_float32) { + switch (num_values) { + case 3: + vertex_element_array->add_tangent_vertex_element(array_index, start); + break; + default: + dxgsg9_cat.error() << "VE ERROR: invalid number of tangent coordinate elements " << num_values << "\n"; + break; + } + } else { + dxgsg9_cat.error() << "VE ERROR: invalid tangent type " << numeric_type << "\n"; + } + } else { + dxgsg9_cat.error() << "Unsupported semantic " << semantic << " for parameter " << var_index << "\n"; } } + + // Get the vertex buffer for this array. + CLP(VertexBufferContext)* dvbc; + if (!gsg->setup_array_data(dvbc, array_reader, force)) { + dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n"; + continue; + } + + // Bind this array as the data source for the corresponding stream. + const GeomVertexArrayFormat* array_format = array_reader->get_array_format(); + hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() ); + if (FAILED(hr)) { + dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr); + } + } + + _num_bound_streams = number_of_arrays; + + if (( _vertex_element_array != NULL ) && + ( _vertex_element_array->add_end_vertex_element() != false )) { + if ( dxgsg9_cat.is_debug() ) { + // Note that the currently generated vertex declaration works but never validates. + // My theory is that this is due to the shader programs always using float4 whereas + // the vertex declaration correctly sets the number of inputs (float2, float3, etc.). + if (cgD3D9ValidateVertexDeclaration(_cg_vprogram, + _vertex_element_array->_vertex_element_array) == CG_TRUE) { + dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration succeeded\n"; + } else { + dxgsg9_cat.debug() << "cgD3D9ValidateVertexDeclaration failed\n"; + } + } + + // Discard the old VertexDeclaration. This thrashes pretty bad.... + if ( _vertex_declaration != NULL ) { + _vertex_declaration->Release(); + _vertex_declaration = NULL; + } + + hr = device->CreateVertexDeclaration( _vertex_element_array->_vertex_element_array, + &_vertex_declaration ); + if (FAILED (hr)) { + dxgsg9_cat.error() << "CreateVertexDeclaration failed" << D3DERRORSTRING(hr); + } else { + hr = device->SetVertexDeclaration( _vertex_declaration ); + if (FAILED(hr)) { + dxgsg9_cat.error() << "SetVertexDeclaration failed" << D3DERRORSTRING(hr); + } + } + } else { + dxgsg9_cat.error() << "VertexElementArray creation failed\n"; } } #endif // HAVE_CG + + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h index 0042f2cd1c..41424f38db 100644 --- a/panda/src/dxgsg9/dxShaderContext9.h +++ b/panda/src/dxgsg9/dxShaderContext9.h @@ -76,14 +76,17 @@ public: void issue_parameters(GSG *gsg, int altered); void issue_transform(GSG *gsg); void disable_shader_vertex_arrays(GSG *gsg); - void update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg); + bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, + bool force); void disable_shader_texture_bindings(GSG *gsg); void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg); - class VertexElementArray *_vertex_element_array; + class VertexElementArray* _vertex_element_array; + LPDIRECT3DVERTEXDECLARATION9 _vertex_declaration; + + int _num_bound_streams; // FOR DEBUGGING - int _vertex_size; string _name; private: diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.cxx b/panda/src/dxgsg9/dxVertexBufferContext9.cxx index 18f47efe7d..59e5e71341 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.cxx +++ b/panda/src/dxgsg9/dxVertexBufferContext9.cxx @@ -29,8 +29,10 @@ TypeHandle DXVertexBufferContext9::_type_handle; // Access: Public // Description: //////////////////////////////////////////////////////////////////// -DXVertexBufferContext9:: -DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn) : +CLP(VertexBufferContext):: +CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg, + PreparedGraphicsObjects *pgo, + GeomVertexArrayData *data) : VertexBufferContext(pgo, data), _vbuffer(NULL) { @@ -43,112 +45,11 @@ DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, int n = 0; int num_columns = array_format->get_num_columns(); - _vertex_element_type_array = 0; - - VERTEX_ELEMENT_TYPE *vertex_element_type_array; - -// if (scrn._dxgsg9 -> _current_shader_context) - { - int total_elements; - unsigned char vertex_element_type_counter_array [VS_TOTAL_TYPES]; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - total_elements = num_columns + 2; - vertex_element_type_array = new VERTEX_ELEMENT_TYPE [total_elements]; - memset (vertex_element_type_array, 0, total_elements * sizeof (VERTEX_ELEMENT_TYPE)); - memset (vertex_element_type_counter_array, 0, sizeof (vertex_element_type_counter_array)); - - // create a simple vertex type mapping from the vertex elements - vertex_element_type = vertex_element_type_array; - for (index = 0; index < num_columns; index++) - { - int num_values; - const InternalName *name; - - name = array_format -> get_column (index) -> get_name ( ); - num_values = array_format -> get_column(index) -> get_num_values ( ); - - if (false) { - - } else if (name -> get_top ( ) == InternalName::get_vertex ( )) { - - switch (num_values) - { - case 3: - vertex_element_type -> vs_input_type = VS_POSITION_XYZ; - break; - case 4: - vertex_element_type -> vs_input_type = VS_POSITION_XYZW; - break; - default: - dxgsg9_cat.warning ( ) << "VERTEX ERROR: invalid number of position coordinate elements " << num_values << "\n"; - break; - } - - } else if (name -> get_top ( ) == InternalName::get_texcoord ( )) { - - switch (num_values) - { - case 1: - vertex_element_type -> vs_input_type = VS_TEXTURE_U; - break; - case 2: - vertex_element_type -> vs_input_type = VS_TEXTURE_UV; - break; - case 3: - vertex_element_type -> vs_input_type = VS_TEXTURE_UVW; - break; - default: - dxgsg9_cat.warning ( ) << "VERTEX ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; - break; - } - - } else if (name -> get_top ( ) == InternalName::get_normal ( )) { - - vertex_element_type -> vs_input_type = VS_NORMAL; - - } else if (name -> get_top ( ) == InternalName::get_binormal ( )) { - - vertex_element_type -> vs_input_type = VS_BINORMAL; - - } else if (name -> get_top ( ) == InternalName::get_tangent ( )) { - - vertex_element_type -> vs_input_type = VS_TANGENT; - - } else if (name -> get_top ( ) == InternalName::get_color ( )) { - - vertex_element_type -> vs_input_type = VS_DIFFUSE; - - } else { - - dxgsg9_cat.error ( ) - << "VERTEX ERROR: unsupported vertex element " << name -> get_name ( ) - << "\n"; - - vertex_element_type -> vs_input_type = VS_ERROR; - } - - vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type]; - vertex_element_type_counter_array [vertex_element_type -> vs_input_type]++; - - // SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER ??? - vertex_element_type -> stream = 0; - vertex_element_type -> offset = array_format -> get_column(index) -> get_start ( ); - - vertex_element_type++; - } - } - - _vertex_element_type_array = vertex_element_type_array; - _fvf = 0; - _managed = -1; - - _direct_3d_vertex_declaration = 0; - _shader_context = 0; if (n < num_columns && array_format->get_column(n)->get_name() == InternalName::get_vertex()) { + Geom::Contents contents = array_format->get_column(n)->get_contents(); ++n; int num_blend_values = 0; @@ -263,26 +164,6 @@ DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, } } -//////////////////////////////////////////////////////////////////// -// Function: DXVertexBufferContext9::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -DXVertexBufferContext9:: -~DXVertexBufferContext9() { - - if (_vertex_element_type_array) { - delete _vertex_element_type_array; - _vertex_element_type_array = 0; - } - if (_direct_3d_vertex_declaration) { - _direct_3d_vertex_declaration -> Release ( ); - _direct_3d_vertex_declaration = 0; - } - - free_vbuffer ( ); -} - //////////////////////////////////////////////////////////////////// // Function: DXVertexBufferContext9::evict_lru // Access: Public, Virtual @@ -298,162 +179,16 @@ DXVertexBufferContext9:: // case the eviction will be requested again much // later). //////////////////////////////////////////////////////////////////// -void DXVertexBufferContext9:: +void CLP(VertexBufferContext):: evict_lru() { dequeue_lru(); - free_vbuffer(); + + if ( _vbuffer != NULL ) { + _vbuffer->Release(); + _vbuffer = NULL; + } + update_data_size_bytes(0); mark_unloaded(); } -//////////////////////////////////////////////////////////////////// -// Function: DXVertexBufferContext9::free_vbuffer -// Access: Public -// Description: Frees vertex buffer memory. -//////////////////////////////////////////////////////////////////// -void DXVertexBufferContext9:: -free_vbuffer(void) { - - if (_vbuffer != NULL) { - if (DEBUG_VERTEX_BUFFER && dxgsg9_cat.is_debug()) { - dxgsg9_cat.debug() - << "deleting vertex buffer " << _vbuffer << "\n"; - } - - if (DEBUG_VERTEX_BUFFER) { - RELEASE(_vbuffer, dxgsg9, "vertex buffer", RELEASE_ONCE); - } - else { - _vbuffer -> Release ( ); - } - - _vbuffer = NULL; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DXVertexBufferContext9::allocate_vbuffer -// Access: Public -// Description: Allocates vertex buffer memory. -//////////////////////////////////////////////////////////////////// -void DXVertexBufferContext9:: -allocate_vbuffer(DXScreenData &scrn, - const GeomVertexArrayDataHandle *reader) { - - int data_size; - HRESULT hr; - DWORD usage; - D3DPOOL pool; - - data_size = reader->get_data_size_bytes(); - - _managed = scrn._managed_vertex_buffers; - if (_managed) { - pool = D3DPOOL_MANAGED; - usage = D3DUSAGE_WRITEONLY; - } - else { - pool = D3DPOOL_DEFAULT; - usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC; - } - - int attempts; - - attempts = 0; - do - { - hr = scrn._d3d_device->CreateVertexBuffer - (data_size, usage, _fvf, pool, &_vbuffer, NULL); - attempts++; - } - while (scrn._dxgsg9 -> check_dx_allocation (hr, data_size, attempts)); - - if (FAILED(hr)) { - dxgsg9_cat.warning() - << "CreateVertexBuffer failed" << D3DERRORSTRING(hr); - - printf ("data_size %d \n", data_size); - - _vbuffer = NULL; - } else { - if (DEBUG_VERTEX_BUFFER && dxgsg9_cat.is_debug()) { - dxgsg9_cat.debug() - << "created vertex buffer " << _vbuffer << ": " - << reader->get_num_rows() << " vertices " - << *reader->get_array_format() << "\n"; - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: DXVertexBufferContext9::create_vbuffer -// Access: Public -// Description: Creates a new vertex buffer (but does not upload data -// to it). -//////////////////////////////////////////////////////////////////// -void DXVertexBufferContext9:: -create_vbuffer(DXScreenData &scrn, - const GeomVertexArrayDataHandle *reader, - string name) { - nassertv(reader->get_object() == get_data()); - Thread *current_thread = reader->get_current_thread(); - - free_vbuffer ( ); - - PStatTimer timer(GraphicsStateGuardian::_create_vertex_buffer_pcollector, - current_thread); - - int data_size; - - data_size = reader->get_data_size_bytes(); - - this -> allocate_vbuffer(scrn, reader); -} - -//////////////////////////////////////////////////////////////////// -// Function: DXVertexBufferContext9::upload_data -// Access: Public -// Description: Copies the latest data from the client store to -// DirectX. -//////////////////////////////////////////////////////////////////// -bool DXVertexBufferContext9:: -upload_data(const GeomVertexArrayDataHandle *reader, bool force) { - nassertr(reader->get_object() == get_data(), false); - nassertr(_vbuffer != NULL, false); - Thread *current_thread = reader->get_current_thread(); - - const unsigned char *data_pointer = reader->get_read_pointer(force); - if (data_pointer == NULL) { - return false; - } - int data_size = reader->get_data_size_bytes(); - - if (dxgsg9_cat.is_spam()) { - dxgsg9_cat.spam() - << "copying " << data_size - << " bytes into vertex buffer " << _vbuffer << "\n"; - } - PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector, - current_thread); - - HRESULT hr; - BYTE *local_pointer; - - if (_managed) { - hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, 0); - } - else { - hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD); - } - if (FAILED(hr)) { - dxgsg9_cat.error() - << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr); - return false; - } - - GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size); - memcpy(local_pointer, data_pointer, data_size); - - _vbuffer->Unlock(); - return true; -} diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.h b/panda/src/dxgsg9/dxVertexBufferContext9.h index 46f69e840e..a7799fc0a6 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.h +++ b/panda/src/dxgsg9/dxVertexBufferContext9.h @@ -18,33 +18,27 @@ #include "pandabase.h" #include "dxgsg9base.h" #include "vertexBufferContext.h" +#include "deletedChain.h" + +class CLP(GraphicsStateGuardian); //////////////////////////////////////////////////////////////////// // Class : DXVertexBufferContext9 // Description : Caches a GeomVertexArrayData in the DirectX device as // a vertex buffer. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext { +class EXPCL_PANDADX CLP(VertexBufferContext) : public VertexBufferContext { public: - DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn); - virtual ~DXVertexBufferContext9(); + CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg, + PreparedGraphicsObjects *pgo, + GeomVertexArrayData *data); + ALLOC_DELETED_CHAIN(CLP(VertexBufferContext)); virtual void evict_lru(); - void free_vbuffer(); - void allocate_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader); - void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader, string name); - bool upload_data(const GeomVertexArrayDataHandle *reader, bool force); - - IDirect3DVertexBuffer9 *_vbuffer; + LPDIRECT3DVERTEXBUFFER9 _vbuffer; int _fvf; - int _managed; - - VERTEX_ELEMENT_TYPE *_vertex_element_type_array; - DIRECT_3D_VERTEX_DECLARATION _direct_3d_vertex_declaration; - CLP(ShaderContext) *_shader_context; - public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/dxgsg9/vertexElementArray.cxx b/panda/src/dxgsg9/vertexElementArray.cxx index f25f2f0a18..075b8bff42 100644 --- a/panda/src/dxgsg9/vertexElementArray.cxx +++ b/panda/src/dxgsg9/vertexElementArray.cxx @@ -16,294 +16,213 @@ #include "vertexElementArray.h" -VertexElementArray::VertexElementArray (int maximum_vertex_elements) { - this -> offset = 0; - this -> total_elements = 0; - this -> maximum_vertex_elements = maximum_vertex_elements; - this -> total_texture_coordinate_elements = 0; - this -> vertex_element_array = new DIRECT_3D_VERTEX_ELEMENT [maximum_vertex_elements]; - memset (this -> vertex_element_array, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT) * maximum_vertex_elements); - this -> vertex_element_type_array = new VERTEX_ELEMENT_TYPE [maximum_vertex_elements]; - memset (this -> vertex_element_type_array, 0, sizeof (VERTEX_ELEMENT_TYPE) * maximum_vertex_elements); +VertexElementArray::VertexElementArray(int maximum_vertex_elements) { + _total_elements = 0; + _maximum_vertex_elements = maximum_vertex_elements; - memset (this -> vertex_element_type_counter_array, 0, VS_TOTAL_TYPES * sizeof (int)); + _vertex_element_array = new D3DVERTEXELEMENT9[maximum_vertex_elements]; + memset(_vertex_element_array, 0, sizeof(D3DVERTEXELEMENT9) * maximum_vertex_elements); } -VertexElementArray::~VertexElementArray ( ) { - delete this -> vertex_element_array; - delete this -> vertex_element_type_array; +VertexElementArray::~VertexElementArray() { + delete _vertex_element_array; } -int VertexElementArray::set_vertex_element_offset (int vertex_element_index, int offset) { - int state; - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - - if (vertex_element_index >= 0 && vertex_element_index < this -> total_elements) { - vertex_element = &this -> vertex_element_array [vertex_element_index]; - vertex_element -> Offset = offset; - state = true; +void VertexElementArray::add_position_xyz_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; } - return state; + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT3; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_POSITION; + vertex_element->UsageIndex = 0; + + _total_elements++; } -void VertexElementArray::set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type) { - vertex_element_type -> vs_input_type = vs_input_type; - vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type]; - vertex_element_type_counter_array [vertex_element_type -> vs_input_type]++; -} - -void VertexElementArray::add_position_xyz_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_POSITION_XYZ, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT3; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_POSITION; - vertex_element -> UsageIndex = 0; - - this -> offset += 12; - this -> total_elements++; - } -} - -void VertexElementArray::add_position_xyzw_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_POSITION_XYZW, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT4; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_POSITION; - vertex_element -> UsageIndex = 0; - - this -> offset += 16; - this -> total_elements++; - } -} - -void VertexElementArray::add_normal_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_NORMAL, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT3; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_NORMAL; - vertex_element -> UsageIndex = 0; - - this -> offset += 12; - this -> total_elements++; - } -} - -void VertexElementArray::add_binormal_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_BINORMAL, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT3; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_BINORMAL; - vertex_element -> UsageIndex = 0; - - this -> offset += 12; - this -> total_elements++; - } -} - -void VertexElementArray::add_tangent_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_TANGENT, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT3; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_TANGENT; - vertex_element -> UsageIndex = 0; - - this -> offset += 12; - this -> total_elements++; - } -} - -void VertexElementArray::add_diffuse_color_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_DIFFUSE, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_D3DCOLOR; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_COLOR; - vertex_element -> UsageIndex = 0; - - this -> offset += 4; - this -> total_elements++; - } -} - -void VertexElementArray::add_specular_color_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_SPECULAR, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_D3DCOLOR; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_COLOR; - vertex_element -> UsageIndex = 1; - - this -> offset += 4; - this -> total_elements++; - } -} - -void VertexElementArray::add_u_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_TEXTURE_U, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT1; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD; - vertex_element -> UsageIndex = this -> total_texture_coordinate_elements; - this -> total_texture_coordinate_elements++; - - this -> offset += 4; - this -> total_elements++; - } -} - -void VertexElementArray::add_uv_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_TEXTURE_UV, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT2; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD; - vertex_element -> UsageIndex = this -> total_texture_coordinate_elements; - this -> total_texture_coordinate_elements++; - - this -> offset += 8; - this -> total_elements++; - } -} - -void VertexElementArray::add_uvw_vertex_element (int stream_index) { - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - set_vs_input_type (VS_TEXTURE_UVW, vertex_element_type); - - vertex_element -> Stream = stream_index; - vertex_element -> Offset = this -> offset; - vertex_element -> Type = D3DDECLTYPE_FLOAT3; - vertex_element -> Method = D3DDECLMETHOD_DEFAULT; - - vertex_element -> Usage = D3DDECLUSAGE_TEXCOORD; - vertex_element -> UsageIndex = this -> total_texture_coordinate_elements; - this -> total_texture_coordinate_elements++; - - this -> offset += 12; - this -> total_elements++; - } -} - -int VertexElementArray::add_end_vertex_element (void) { - int add; - DIRECT_3D_VERTEX_ELEMENT *vertex_element; - VERTEX_ELEMENT_TYPE *vertex_element_type; - - add = FALSE; - if (this -> total_elements < this -> maximum_vertex_elements) { - vertex_element = &this -> vertex_element_array [this -> total_elements]; - vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; - - vertex_element_type -> vs_input_type = VS_END; - - vertex_element -> Stream = 0xFF; - vertex_element -> Type = D3DDECLTYPE_UNUSED; - - add = TRUE; +void VertexElementArray::add_position_xyzw_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; } - return add; + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT4; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_POSITION; + vertex_element->UsageIndex = 0; + + _total_elements++; +} + +void VertexElementArray::add_normal_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT3; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_NORMAL; + vertex_element->UsageIndex = 0; + + _total_elements++; +} + +void VertexElementArray::add_binormal_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT3; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_BINORMAL; + vertex_element->UsageIndex = 0; + + _total_elements++; +} + +void VertexElementArray::add_tangent_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT3; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_TANGENT; + vertex_element->UsageIndex = 0; + + _total_elements++; +} + +void VertexElementArray::add_diffuse_color_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_D3DCOLOR; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_COLOR; + vertex_element->UsageIndex = 0; + + _total_elements++; +} + +void VertexElementArray::add_specular_color_vertex_element(int stream_index, int offset) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_D3DCOLOR; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_COLOR; + vertex_element->UsageIndex = 1; + + _total_elements++; +} + +void VertexElementArray::add_u_vertex_element(int stream_index, int offset, int texture_stage) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT1; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_TEXCOORD; + vertex_element->UsageIndex = texture_stage; + + _total_elements++; +} + +void VertexElementArray::add_uv_vertex_element(int stream_index, int offset, int texture_stage) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT2; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_TEXCOORD; + vertex_element->UsageIndex = texture_stage; + + _total_elements++; +} + +void VertexElementArray::add_uvw_vertex_element(int stream_index, int offset, int texture_stage) { + if (_total_elements >= _maximum_vertex_elements) { + return; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = stream_index; + vertex_element->Offset = offset; + vertex_element->Type = D3DDECLTYPE_FLOAT3; + vertex_element->Method = D3DDECLMETHOD_DEFAULT; + + vertex_element->Usage = D3DDECLUSAGE_TEXCOORD; + vertex_element->UsageIndex = texture_stage; + + _total_elements++; +} + +bool VertexElementArray::add_end_vertex_element(void) { + if (_total_elements >= _maximum_vertex_elements) { + return false; + } + + LPD3DVERTEXELEMENT9 vertex_element = &_vertex_element_array[_total_elements]; + + vertex_element->Stream = 0xFF; + vertex_element->Offset = 0; + vertex_element->Type = D3DDECLTYPE_UNUSED; + vertex_element->Method = 0; + + vertex_element->Usage = 0; + vertex_element->UsageIndex = 0; + + return true; } diff --git a/panda/src/dxgsg9/vertexElementArray.h b/panda/src/dxgsg9/vertexElementArray.h index 4e7865dcfd..0507cd11e9 100644 --- a/panda/src/dxgsg9/vertexElementArray.h +++ b/panda/src/dxgsg9/vertexElementArray.h @@ -15,36 +15,6 @@ #ifndef VERTEX_ELEMENT_ARRAY_H #define VERTEX_ELEMENT_ARRAY_H - -enum -{ - VS_END = 0, - - VS_POSITION_XYZ, - VS_POSITION_XYZW, - VS_NORMAL, - VS_DIFFUSE, - VS_SPECULAR, - VS_TEXTURE_U, - VS_TEXTURE_UV, - VS_TEXTURE_UVW, - VS_TANGENT, - VS_BINORMAL, - - VS_ERROR, - - VS_TOTAL_TYPES -}; - -typedef struct -{ - int vs_input_type; // this is VS_XXXXX from the enum above - int index; - int stream; - int offset; -} -VERTEX_ELEMENT_TYPE; - //////////////////////////////////////////////////////////////////// // Class : VertexElementArray // Description : This class gives the ability for a user-friendly way @@ -67,28 +37,26 @@ public: VertexElementArray (int maximum_vertex_elements); ~VertexElementArray ( ); - int set_vertex_element_offset (int vertex_element_index, int offset); - void set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type); + void add_position_xyz_vertex_element (int stream_index, int offset); + void add_position_xyzw_vertex_element (int stream_index, int offset); - void add_position_xyz_vertex_element (int stream_index); - void add_position_xyzw_vertex_element (int stream_index); - void add_normal_vertex_element (int stream_index); - void add_binormal_vertex_element (int stream_index); - void add_tangent_vertex_element (int stream_index); - void add_diffuse_color_vertex_element (int stream_index); - void add_specular_color_vertex_element (int stream_index); - void add_u_vertex_element (int stream_index); - void add_uv_vertex_element (int stream_index); - void add_uvw_vertex_element (int stream_index); - int add_end_vertex_element (void); + void add_normal_vertex_element (int stream_index, int offset); + void add_binormal_vertex_element (int stream_index, int offset); + void add_tangent_vertex_element (int stream_index, int offset); - int offset; - int total_elements; - int maximum_vertex_elements; - int total_texture_coordinate_elements; - int vertex_element_type_counter_array [VS_TOTAL_TYPES]; - DIRECT_3D_VERTEX_ELEMENT *vertex_element_array; - VERTEX_ELEMENT_TYPE *vertex_element_type_array; + void add_diffuse_color_vertex_element (int stream_index, int offset); + void add_specular_color_vertex_element (int stream_index, int offset); + + void add_u_vertex_element (int stream_index, int offset, int texture_stage); + void add_uv_vertex_element (int stream_index, int offset, int texture_stage); + void add_uvw_vertex_element (int stream_index, int offset, int texture_stage); + + bool add_end_vertex_element (void); + + int _total_elements; + int _maximum_vertex_elements; + + LPD3DVERTEXELEMENT9 _vertex_element_array; }; #endif diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 704542095d..192156b264 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -341,7 +341,7 @@ reset() { // Build _inv_state_mask as a mask of 1's where we don't care, and // 0's where we do care, about the state. - _inv_state_mask = RenderState::SlotMask::all_on(); + //_inv_state_mask = RenderState::SlotMask::all_on(); _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot()); _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot()); _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot()); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index f5e8952d0d..e95e49ee64 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -652,7 +652,7 @@ public: DeletedDisplayLists _deleted_display_lists; DeletedDisplayLists _deleted_queries; - RenderState::SlotMask _inv_state_mask; + //RenderState::SlotMask _inv_state_mask; bool _track_errors; bool _allow_flush; diff --git a/panda/src/gobj/geomVertexArrayFormat.cxx b/panda/src/gobj/geomVertexArrayFormat.cxx index 4ab4965661..25b4aa80f1 100644 --- a/panda/src/gobj/geomVertexArrayFormat.cxx +++ b/panda/src/gobj/geomVertexArrayFormat.cxx @@ -476,7 +476,7 @@ output(ostream &out) const { for (ci = _columns.begin(); ci != _columns.end(); ++ci) { const GeomVertexColumn *column = (*ci); if (column->get_start() > last_pos) { - out << " ..." << (column->get_start() - last_pos) << "..."; + out << " (..." << (column->get_start() - last_pos) << "...)"; } out << " " << *column; last_pos = column->get_start() + column->get_total_bytes(); diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 1830714068..148f1f0820 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -622,7 +622,10 @@ synthesize_shader(const RenderState *rs) { analyze_renderstate(rs); reset_register_allocator(); - pgraph_cat.info() << "Generating shader for render state " << rs << "\n"; + if (pgraph_cat.is_debug()) { + pgraph_cat.debug() + << "Generating shader for render state " << *rs << "\n"; + } // These variables will hold the results of register allocation. @@ -998,7 +1001,7 @@ synthesize_shader(const RenderState *rs) { if (_lighting) { text << "\t // Begin view-space light calculations\n"; text << "\t float ldist,lattenv,langle;\n"; - text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;"; + text << "\t float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;\n"; if (_shadows && _auto_shadow_on) { text << "\t float lshad;\n"; } diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index be0ea2fbb5..bf6576bbb9 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -95,7 +95,6 @@ reset() { // Build _inv_state_mask as a mask of 1's where we don't care, and // 0's where we do care, about the state. - _inv_state_mask = RenderState::SlotMask::all_on(); _inv_state_mask.clear_bit(ColorAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot()); _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot()); diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h index 45ce15902b..df1f3b465e 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h @@ -170,7 +170,6 @@ private: bool _texture_replace; bool _filled_flat; bool _auto_rescale_normal; - RenderState::SlotMask _inv_state_mask; CPT(TransformState) _scissor_mat;