diff --git a/panda/src/dxgsg9/Sources.pp b/panda/src/dxgsg9/Sources.pp index 396cad0d1e..7754eb0cac 100755 --- a/panda/src/dxgsg9/Sources.pp +++ b/panda/src/dxgsg9/Sources.pp @@ -7,7 +7,7 @@ #define WIN_SYS_LIBS \ d3d9.lib d3dx9.lib dxerr9.lib -#define USE_PACKAGES dx +#define USE_PACKAGES dx cg cgdx9 #begin lib_target #define TARGET dxgsg9 @@ -30,7 +30,7 @@ dxTextureContext9.h dxTextureContext9.I \ dxGeomMunger9.h dxGeomMunger9.I \ dxGraphicsDevice9.h \ - ../display/lru.h + ../display/lru.h \ #define INCLUDED_SOURCES \ config_dxgsg9.cxx \ @@ -42,6 +42,6 @@ wdxGraphicsPipe9.cxx \ wdxGraphicsWindow9.cxx \ wdxGraphicsBuffer9.cxx \ - + dxShaderContext9.cxx #end lib_target diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index d735f3c223..b7eb9151e1 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -4,7 +4,7 @@ //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license @@ -68,10 +68,6 @@ #define DEBUG_LRU false -#define DBG_S if (false) { -#define DBG_E } - - TypeHandle DXGraphicsStateGuardian9::_type_handle; D3DMATRIX DXGraphicsStateGuardian9::_d3d_ident_mat; @@ -134,6 +130,19 @@ DXGraphicsStateGuardian9(const FrameBufferProperties &properties) : _lru = 0; _last_fvf = 0; + + _vertex_shader_version_major = 0; + _vertex_shader_version_minor = 0; + _pixel_shader_version_major = 0; + _pixel_shader_version_minor = 0; + + _vertex_shader_maximum_constants = 0; + _supports_stream_offset = false; + +#ifdef HAVE_CGDX9 + _cg_context = 0; +#endif + } //////////////////////////////////////////////////////////////////// @@ -148,11 +157,19 @@ DXGraphicsStateGuardian9:: } free_nondx_resources(); - if (_lru) - { + if (_lru) { delete _lru; _lru = 0; } + +#ifdef HAVE_CGDX9 + if (_cg_context) { + cgD3D9SetDevice (NULL); + cgDestroyContext (_cg_context); + _cg_context = 0; + } +#endif + } //////////////////////////////////////////////////////////////////// @@ -217,13 +234,13 @@ apply_texture(int i, TextureContext *tc) { // error or oversight. if ((dirty & Texture::DF_image) == 0) { dxgsg9_cat.warning() - << "Texture " << *dtc->_texture << " has changed mipmap state.\n"; + << "Texture " << *dtc->_texture << " has changed mipmap state.\n"; } if (!dtc->create_texture(*_screen)) { // Oops, we can't re-create the texture for some reason. dxgsg9_cat.error() - << "Unable to re-create texture " << *dtc->_texture << endl; + << "Unable to re-create texture " << *dtc->_texture << endl; set_texture_stage_state(i, D3DTSS_COLOROP, D3DTOP_DISABLE); return; } @@ -313,6 +330,30 @@ release_texture(TextureContext *tc) { delete dtc; } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::prepare_shader +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +ShaderContext *CLP(GraphicsStateGuardian):: +prepare_shader(ShaderExpansion *se) { + CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this); + if (this -> _cg_context) return result; + delete result; + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::release_shader +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +release_shader(ShaderContext *sc) { + CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc); + delete gsc; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::prepare_vertex_buffer // Access: Public, Virtual @@ -328,7 +369,7 @@ release_texture(TextureContext *tc) { //////////////////////////////////////////////////////////////////// VertexBufferContext *DXGraphicsStateGuardian9:: prepare_vertex_buffer(GeomVertexArrayData *data) { - DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(data); + DXVertexBufferContext9 *dvbc = new DXVertexBufferContext9(data, *(this -> _screen)); return dvbc; } @@ -339,9 +380,20 @@ prepare_vertex_buffer(GeomVertexArrayData *data) { // makes it the current vertex buffer for rendering. //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -apply_vertex_buffer(VertexBufferContext *vbc) { +apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context) { DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc); + DBG_SH2 dxgsg9_cat.debug ( ) << "apply_vertex_buffer\n"; DBG_E + + bool set_stream_source; + HRESULT hr; + UINT stream; + UINT offset; + + set_stream_source = false; + stream = 0; + offset = 0; + if (_lru) { _lru -> access_page (dvbc -> _lru_page); @@ -360,11 +412,7 @@ apply_vertex_buffer(VertexBufferContext *vbc) { add_to_total_buffer_record(dvbc); dvbc->mark_loaded(); - _d3d_device->SetStreamSource - (0, dvbc->_vbuffer, 0, dvbc->get_data()->get_array_format()->get_stride()); - _active_vbuffer = dvbc; - _active_ibuffer = NULL; - add_to_vertex_buffer_record(dvbc); + set_stream_source = true; } else { _active_vbuffer = NULL; @@ -386,24 +434,134 @@ apply_vertex_buffer(VertexBufferContext *vbc) { } if (_active_vbuffer != dvbc) { - _d3d_device->SetStreamSource - (0, dvbc->_vbuffer, 0, dvbc->get_data()->get_array_format()->get_stride()); + set_stream_source = true; + } + } + + if (shader_context == 0) + { + // FVF MODE + if (set_stream_source) + { + hr = _d3d_device->SetStreamSource + (stream, dvbc->_vbuffer, offset, dvbc->get_data()->get_array_format()->get_stride()); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "SetStreamSource failed" << D3DERRORSTRING(hr); + } _active_vbuffer = dvbc; _active_ibuffer = NULL; add_to_vertex_buffer_record(dvbc); } - } - if (dvbc->_fvf != _last_fvf) { - HRESULT hr = _d3d_device->SetFVF(dvbc->_fvf); - #ifndef NDEBUG - if (FAILED(hr)) { - dxgsg9_cat.error() - << "SetVertexShader(0x" << (void*)dvbc->_fvf - << ") failed" << D3DERRORSTRING(hr); + 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 -> id != VS_END) + { + if (source_vertex_element_type -> id == vertex_element_type -> id) + { + offset = source_vertex_element_type -> offset; + break; + } + source_vertex_element_type++; + } + if (source_vertex_element_type -> id == VS_END) + { + dxgsg9_cat.error() + << "unable to find a mapping for vertex shader input type=" + << vertex_element_type -> id + << " 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); + } + + 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, dvbc->get_data()->get_array_format()->get_stride()); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "SetStreamSource failed" << D3DERRORSTRING(hr); + } + _active_vbuffer = dvbc; + _active_ibuffer = NULL; + add_to_vertex_buffer_record(dvbc); + } + + if (dvbc -> _direct_3d_vertex_declaration) { + + DBG_SH5 dxgsg9_cat.debug() << "SetVertexDeclaration ( ) \n"; DBG_E + + hr = _d3d_device -> SetVertexDeclaration (dvbc -> _direct_3d_vertex_declaration); + if (FAILED(hr)) { + dxgsg9_cat.error() + << "SetVertexDeclaration failed" << D3DERRORSTRING(hr); + } } - #endif - _last_fvf = dvbc->_fvf; } } @@ -547,7 +705,7 @@ do_clear(const RenderBuffer &buffer) { DWORD main_flags = 0; DWORD aux_flags = 0; -DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::do_clear\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::do_clear\n"; DBG_E //set appropriate flags if (buffer_type & RenderBuffer::T_back) { @@ -566,7 +724,7 @@ DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::do_clear\n"; DBG_E if ((main_flags | aux_flags) != 0) { -DBG_S dxgsg9_cat.error ( ) << "ccccc DXGraphicsStateGuardian9::really do_clear\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "ccccc DXGraphicsStateGuardian9::really do_clear\n"; DBG_E HRESULT hr = _d3d_device->Clear(0, NULL, main_flags | aux_flags, _d3dcolor_clear_value, _depth_clear_value, (DWORD)_stencil_clear_value); @@ -617,7 +775,7 @@ DBG_S dxgsg9_cat.error ( ) << "ccccc DXGraphicsStateGuardian9::really do_clear\n void DXGraphicsStateGuardian9:: prepare_display_region() { -// DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::PRE prepare_display_region\n"; DBG_E +// DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::PRE prepare_display_region\n"; DBG_E if (_current_display_region == (DisplayRegion*)0L) { dxgsg9_cat.error() @@ -626,12 +784,12 @@ prepare_display_region() { } else if (_current_display_region != _actual_display_region) { _actual_display_region = _current_display_region; -// DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::prepare_display_region\n"; DBG_E +// DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::prepare_display_region\n"; DBG_E int l, u, w, h; _actual_display_region->get_region_pixels_i(l, u, w, h); -DBG_S dxgsg9_cat.error ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E // Create the viewport D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f }; @@ -731,7 +889,7 @@ prepare_lens() { bool DXGraphicsStateGuardian9:: begin_frame() { -DBG_S dxgsg9_cat.error ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "^^^^^^^^^^^ begin_frame \n"; DBG_E GraphicsStateGuardian::begin_frame(); @@ -784,7 +942,7 @@ begin_scene() { return false; } -DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::begin_scene\n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::begin_scene\n"; DBG_E /* HRESULT hr = _d3d_device->BeginScene(); @@ -823,7 +981,7 @@ DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::begin_scene\n"; DBG_E void DXGraphicsStateGuardian9:: end_scene() { -DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::end_scene\n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "DXGraphicsStateGuardian9::end_scene\n"; DBG_E /* HRESULT hr = _d3d_device->EndScene(); @@ -857,7 +1015,7 @@ DBG_S dxgsg9_cat.error ( ) << "DXGraphicsStateGuardian9::end_scene\n"; DBG_E void DXGraphicsStateGuardian9:: end_frame() { -DBG_S dxgsg9_cat.error ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E HRESULT hr = _d3d_device->EndScene(); @@ -987,14 +1145,48 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger, } nassertr(_vertex_data != (GeomVertexData *)NULL, false); - const GeomVertexFormat *format = _vertex_data->get_format(); + DBG_SH5 dxgsg9_cat.debug ( ) << "begin_draw_primitives\n"; DBG_E - // The munger should have put the FVF data in the first array. - const GeomVertexArrayData *data = _vertex_data->get_array(0); + + +// 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_expansion = _current_shader_expansion; + _vertex_array_shader_context = _current_shader_context; + + +// const GeomVertexFormat *format = _vertex_data->get_format(); + + const GeomVertexArrayData *data; + + if (_current_shader_context && _vertex_data->get_num_arrays ( ) > 1) + { + data = _vertex_data->get_array(1); + } + else + { + // The munger should have put the FVF data in the first array. + data = _vertex_data->get_array(0); + } VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this); nassertr(vbc != (VertexBufferContext *)NULL, false); - apply_vertex_buffer(vbc); + apply_vertex_buffer(vbc, _current_shader_context); const GeomVertexAnimationSpec &animation = vertex_data->get_format()->get_animation(); @@ -1088,6 +1280,9 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger, //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: draw_triangles(const GeomTriangles *primitive) { + +// DBG_SH5 dxgsg9_cat.debug ( ) << "draw_triangles 1\n"; DBG_E + _vertices_tri_pcollector.add_level(primitive->get_num_vertices()); _primitive_batches_tri_pcollector.add_level(1); if (primitive->is_indexed()) { @@ -1100,14 +1295,18 @@ draw_triangles(const GeomTriangles *primitive) { nassertv(ibc != (IndexBufferContext *)NULL); apply_index_buffer(ibc); +//DBG_SH2 dxgsg9_cat.debug ( ) << "DrawIndexedPrimitive \n"; DBG_E + _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLELIST, - 0, + (D3DPT_TRIANGLELIST, 0, min_vertex, max_vertex - min_vertex + 1, 0, primitive->get_num_primitives()); } else { // Indexed, client arrays. + +//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_indexed_primitive_up \n"; DBG_E + D3DFORMAT index_type = get_index_type(primitive->get_index_type()); draw_indexed_primitive_up (D3DPT_TRIANGLELIST, @@ -1121,6 +1320,9 @@ draw_triangles(const GeomTriangles *primitive) { } else { if (_active_vbuffer != NULL) { // Nonindexed, vbuffers. + +//DBG_SH2 dxgsg9_cat.debug ( ) << "DrawPrimitive D3DPT_TRIANGLELIST \n"; DBG_E + _d3d_device->DrawPrimitive (D3DPT_TRIANGLELIST, primitive->get_first_vertex(), @@ -1129,6 +1331,8 @@ draw_triangles(const GeomTriangles *primitive) { } else { // Nonindexed, client arrays. +//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_primitive_up \n"; DBG_E + draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(), primitive->get_first_vertex(), primitive->get_num_vertices(), @@ -1136,6 +1340,8 @@ draw_triangles(const GeomTriangles *primitive) { _vertex_data->get_format()->get_array(0)->get_stride()); } } + +// DBG_SH5 dxgsg9_cat.debug ( ) << "end draw_triangles 1\n"; DBG_E } //////////////////////////////////////////////////////////////////// @@ -1145,6 +1351,9 @@ draw_triangles(const GeomTriangles *primitive) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: draw_tristrips(const GeomTristrips *primitive) { + + DBG_SH5 dxgsg9_cat.debug ( ) << "draw_tristrips\n"; DBG_E + if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) { // One long triangle strip, connected by the degenerate vertices // that have already been set up within the primitive. @@ -1160,13 +1369,17 @@ draw_tristrips(const GeomTristrips *primitive) { nassertv(ibc != (IndexBufferContext *)NULL); apply_index_buffer(ibc); +//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n"; + _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLESTRIP, - 0, + (D3DPT_TRIANGLESTRIP, 0, min_vertex, max_vertex - min_vertex + 1, 0, primitive->get_num_vertices() - 2); } else { + +//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n"; + // Indexed, client arrays, one long triangle strip. D3DFORMAT index_type = get_index_type(primitive->get_index_type()); draw_indexed_primitive_up @@ -1180,6 +1393,9 @@ draw_tristrips(const GeomTristrips *primitive) { } else { if (_active_vbuffer != NULL) { // Nonindexed, vbuffers, one long triangle strip. + +//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << primitive->get_first_vertex ( ) << " VERTICES: " << primitive->get_num_vertices ( ) << "\n"; + _d3d_device->DrawPrimitive (D3DPT_TRIANGLESTRIP, primitive->get_first_vertex(), @@ -1296,6 +1512,9 @@ draw_tristrips(const GeomTristrips *primitive) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: draw_trifans(const GeomTrifans *primitive) { + + DBG_SH5 dxgsg9_cat.debug ( ) << "draw_trifans\n"; DBG_E + CPTA_int ends = primitive->get_ends(); _primitive_batches_trifan_pcollector.add_level(ends.size()); @@ -1324,8 +1543,7 @@ draw_trifans(const GeomTrifans *primitive) { unsigned int min = mins.get_data1i(); unsigned int max = maxs.get_data1i(); _d3d_device->DrawIndexedPrimitive - (D3DPT_TRIANGLEFAN, - 0, + (D3DPT_TRIANGLEFAN, 0, min, max - min + 1, start, ends[i] - start - 2); @@ -2027,6 +2245,13 @@ reset() { D3DCAPS9 d3d_caps; _d3d_device->GetDeviceCaps(&d3d_caps); + _vertex_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.VertexShaderVersion); + _vertex_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.VertexShaderVersion); + _pixel_shader_version_major = D3DSHADER_VERSION_MAJOR (d3d_caps.PixelShaderVersion); + _pixel_shader_version_minor = D3DSHADER_VERSION_MINOR (d3d_caps.PixelShaderVersion); + _vertex_shader_maximum_constants = d3d_caps.MaxVertexShaderConst; + _supports_stream_offset = (d3d_caps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) != 0; + if (dxgsg9_cat.is_debug()) { dxgsg9_cat.debug() << "\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) @@ -2049,11 +2274,33 @@ reset() { << "\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0) << "\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0) << "\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0) + << "\nVertexShaderVersion = " << _vertex_shader_version_major << "." << _vertex_shader_version_minor + << "\nPixelShaderVersion = " << _pixel_shader_version_major << "." << _pixel_shader_version_minor + << "\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants + << "\nsupport stream offset = " << _supports_stream_offset << "\n"; } this -> reset_render_states ( ); + // minimum shader requirements + if (_vertex_shader_version_major >= 1 && + _pixel_shader_version_major >= 1) { + _supports_basic_shaders = true; + } + +#ifdef HAVE_CGDX9 + if (_cg_context) { + cgD3D9SetDevice (NULL); + cgDestroyContext (_cg_context); + _cg_context = 0; + } + if (_cg_context == 0) { + _cg_context = cgCreateContext ( ); + cgD3D9SetDevice (_d3d_device); + } +#endif + _max_vertices_per_array = d3d_caps.MaxVertexIndex; _max_vertices_per_primitive = d3d_caps.MaxPrimitiveCount; @@ -2312,6 +2559,13 @@ reset() { // must check (_screen->_d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon8500, no on TNT) set_render_state(D3DRS_BLENDOP, D3DBLENDOP_ADD); + _current_shader_expansion = (ShaderExpansion *)NULL; + _current_shader_context = (CLP(ShaderContext) *)NULL; + _vertex_array_shader_expansion = (ShaderExpansion *)NULL; + _vertex_array_shader_context = (CLP(ShaderContext) *)NULL; + _texture_binding_shader_expansion = (ShaderExpansion *)NULL; + _texture_binding_shader_context = (CLP(ShaderContext) *)NULL; + PRINT_REFCNT(dxgsg9, _d3d_device); } @@ -2375,8 +2629,31 @@ do_issue_transform() { const TransformState *transform = _internal_transform; DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1)); - const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data(); - _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat); + if (_current_shader_context) { + _current_shader_context->issue_transform(this); + +// ??? NO NEED TO SET THE D3D TRANSFORM VIA SetTransform SINCE THE TRANSFORM IS ONLY USED IN THE SHADER + const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data(); + _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat); + + } + else { + const D3DMATRIX *d3d_mat = (const D3DMATRIX *)transform->get_mat().get_data(); + _d3d_device->SetTransform(D3DTS_WORLD, d3d_mat); + +// DEBUG PRINT +/* + const float *data; + data = &d3d_mat -> _11; + dxgsg9_cat.debug ( ) << "do_issue_transform\n" << + data[ 0] << " " << data[ 1] << " " << data[ 2] << " " << data[ 3] << "\n" << + data[ 4] << " " << data[ 5] << " " << data[ 6] << " " << data[ 7] << "\n" << + data[ 8] << " " << data[ 9] << " " << data[10] << " " << data[11] << "\n" << + data[12] << " " << data[13] << " " << data[14] << " " << data[15] << "\n"; +*/ + + } + _transform_stale = false; if (_auto_rescale_normal) { @@ -2404,6 +2681,60 @@ do_issue_alpha_test() { } } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::do_issue_shader +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +do_issue_shader() { + + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: do_issue_shader\n"; DBG_E + + CLP(ShaderContext) *context = 0; + ShaderExpansion *expansion = _target_rs->get_shader_expansion(); + if (expansion == 0) { + if (_target._shader->get_shader() != 0) { + expansion = _target._shader->get_shader()->macroexpand(_target_rs); + // I am casting away the const-ness of this pointer, because + // the 'shader-expansion' field is just a cache. + ((RenderState *)((const RenderState*)_target_rs))-> + set_shader_expansion(expansion); + } + } + + if (expansion) { + context = (CLP(ShaderContext) *)(expansion->prepare_now(get_prepared_objects(), this)); + } + + if (context == 0) { + if (_current_shader_context != 0) { + _current_shader_context->unbind(this); + _current_shader_expansion = 0; + _current_shader_context = 0; + } + return; + } + + if (context != _current_shader_context) { + // Use a completely different shader than before. + // Unbind old shader, bind the new one. + if (_current_shader_context != 0) { + _current_shader_context->unbind(this); + _current_shader_context = 0; + _current_shader_expansion = 0; + } + if (context != 0) { + context->bind(this); + _current_shader_expansion = expansion; + _current_shader_context = context; + } + } else { + // Use the same shader as before, but with new input arguments. + context->issue_parameters(this); + } +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::do_issue_render_mode // Access: Protected @@ -2711,11 +3042,6 @@ set_state_and_transform(const RenderState *target, _state._shade_model = _target._shade_model; } - // Shaders not implemented under DX8 - if (_target._shader != _state._shader) { - _state._shader = _target._shader; - } - if (_target._tex_gen != _state._tex_gen) { _state._texture = 0; _state._tex_gen = _target._tex_gen; @@ -2734,6 +3060,12 @@ set_state_and_transform(const RenderState *target, _state._color_blend = _target._color_blend; } + if (_target._shader != _state._shader) { + do_issue_shader(); + _state._shader = _target._shader; + _state._texture = 0; + } + if (_target._texture != _state._texture) { do_issue_texture(); _state._texture = _target._texture; @@ -2985,11 +3317,67 @@ do_issue_material() { //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::do_issue_texture -// Access: Public, Virtual +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +do_issue_texture() { + DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); + + if (_texture_binding_shader_context==0) { + if (_current_shader_context==0) { + update_standard_texture_bindings(); + } else { + disable_standard_texture_bindings(); + _current_shader_context->update_shader_texture_bindings(NULL,this); + } + } else { + if (_current_shader_context==0) { + _texture_binding_shader_context->disable_shader_texture_bindings(this); + update_standard_texture_bindings(); + } else { + _current_shader_context-> + update_shader_texture_bindings(_texture_binding_shader_context,this); + } + } + _texture_binding_shader_expansion = _current_shader_expansion; + _texture_binding_shader_context = _current_shader_context; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::disable_standard_texture_bindings +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void CLP(GraphicsStateGuardian):: +disable_standard_texture_bindings() { + int num_old_stages = _max_texture_stages; + if (_state._texture != (TextureAttrib *)NULL) { + num_old_stages = _state._texture->get_num_on_stages(); + } + + // Disable the texture stages that are no longer used. + for (int i = 0; i < num_old_stages; i++) { + HRESULT hr; + + hr = _d3d_device -> SetTexture (i, NULL); + if (FAILED (hr)) { + dxgsg9_cat.error() + << "SetTexture (" + << i + << ", NULL) failed " + << D3DERRORSTRING(hr); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::update_standard_texture_bindings +// Access: Protected // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -do_issue_texture() { +update_standard_texture_bindings() { DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); int num_stages = _target._texture->get_num_on_stages(); @@ -4042,8 +4430,7 @@ show_frame() { return; } -DBG_S dxgsg9_cat.error ( ) << "- - - - - DXGraphicsStateGuardian9::show_frame\n"; DBG_E - +DBG_S dxgsg9_cat.debug ( ) << "- - - - - DXGraphicsStateGuardian9::show_frame\n"; DBG_E HRESULT hr; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index c29265cde0..cfe4404764 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -4,7 +4,7 @@ //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license @@ -35,6 +35,24 @@ #include "lru.h" +typedef D3DVERTEXELEMENT9 DIRECT_3D_VERTEX_ELEMENT; +typedef LPDIRECT3DDEVICE9 DIRECT_3D_DEVICE; +typedef LPDIRECT3DVERTEXDECLARATION9 DIRECT_3D_VERTEX_DECLARATION; + +#include "dxShaderContext9.h" + + +#define DEBUG_ENABLE !false +#define DBG_SH1 if (false && DEBUG_ENABLE) { +#define DBG_SH2 if (false && DEBUG_ENABLE) { +#define DBG_SH3 if (false && DEBUG_ENABLE) { +#define DBG_SH4 if (false && DEBUG_ENABLE) { +#define DBG_SH5 if (false && DEBUG_ENABLE) { +#define DBG_VEA if (false && DEBUG_ENABLE) { +#define DBG_S if (false && DEBUG_ENABLE) { +#define DBG_E } + + enum GsgPageType { GPT_Texture, @@ -63,8 +81,11 @@ public: void apply_texture(int i, TextureContext *tc); virtual void release_texture(TextureContext *tc); + ShaderContext *prepare_shader(ShaderExpansion *se); + void release_shader(ShaderContext *sc); + virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); - void apply_vertex_buffer(VertexBufferContext *vbc); + void apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context); virtual void release_vertex_buffer(VertexBufferContext *vbc); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data); @@ -128,6 +149,7 @@ public: protected: void do_issue_transform(); void do_issue_alpha_test(); + void do_issue_shader(); void do_issue_render_mode(); void do_issue_rescale_normal(); void do_issue_color_write(); @@ -159,6 +181,11 @@ protected: void do_auto_rescale_normal(); +// void disable_standard_vertex_arrays(); +// void update_standard_vertex_arrays(); + void disable_standard_texture_bindings(); + void update_standard_texture_bindings(); + protected: INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm); INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m); @@ -208,6 +235,11 @@ protected: public: DXScreenData *_screen; + +#ifdef HAVE_CGDX9 + CGcontext _cg_context; +#endif + protected: LPDIRECT3DDEVICE9 _d3d_device; // same as _screen->_d3d_device, cached for spd IDirect3DSwapChain9 *_swap_chain; @@ -243,6 +275,13 @@ protected: LMatrix4f _projection_mat; + PT(ShaderExpansion) _current_shader_expansion; + CLP(ShaderContext) *_current_shader_context; + PT(ShaderExpansion) _vertex_array_shader_expansion; + CLP(ShaderContext) *_vertex_array_shader_context; + PT(ShaderExpansion) _texture_binding_shader_expansion; + CLP(ShaderContext) *_texture_binding_shader_context; + CPT(DisplayRegion) _actual_display_region; const DXVertexBufferContext9 *_active_vbuffer; const DXIndexBufferContext9 *_active_ibuffer; @@ -292,6 +331,14 @@ protected: TextureStageStates _texture_stage_states_array [D3D_MAXTEXTURESTAGES]; TextureRenderStates _texture_render_states_array [MAXIMUM_TEXTURES]; + int _vertex_shader_version_major; + int _vertex_shader_version_minor; + int _pixel_shader_version_major; + int _pixel_shader_version_minor; + int _vertex_shader_maximum_constants; + + bool _supports_stream_offset; + public: virtual TypeHandle get_type() const { return get_class_type(); @@ -319,8 +366,68 @@ private: friend class wdxGraphicsBuffer9; friend class DXVertexBufferContext9; friend class DXIndexBufferContext9; + friend class CLP(ShaderContext); }; #include "dxGraphicsStateGuardian9.I" + +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 id; // this is VS_XXXXX + int index; + int stream; + int offset; +} +VERTEX_ELEMENT_TYPE; + +class VertexElementArray +{ +public: + + VertexElementArray (int maximum_vertex_elements); + ~VertexElementArray ( ); + + int set_vertex_element_offset (int vertex_element_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); + + int offset; + int total_elements; + int maximum_vertex_elements; + int vertex_element_type_counter_array [VS_TOTAL_TYPES]; + DIRECT_3D_VERTEX_ELEMENT *vertex_element_array; + VERTEX_ELEMENT_TYPE *vertex_element_type_array; +}; + #endif diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx index 1ffea912bb..2296c8130e 100644 --- a/panda/src/dxgsg9/dxShaderContext9.cxx +++ b/panda/src/dxgsg9/dxShaderContext9.cxx @@ -20,32 +20,6 @@ TypeHandle CLP(ShaderContext)::_type_handle; -class VertexElementArray -{ - -public: - - VertexElementArray (int maximum_vertex_elements); - ~VertexElementArray ( ); - - 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); - - int offset; - int total_elements; - int maximum_vertex_elements; - DIRECT_3D_VERTEX_ELEMENT *vertex_element_array; -}; - VertexElementArray::VertexElementArray (int maximum_vertex_elements) { @@ -53,22 +27,49 @@ VertexElementArray::VertexElementArray (int maximum_vertex_elements) this -> total_elements = 0; this -> maximum_vertex_elements = maximum_vertex_elements; this -> vertex_element_array = new DIRECT_3D_VERTEX_ELEMENT [maximum_vertex_elements]; + this -> vertex_element_type_array = new VERTEX_ELEMENT_TYPE [maximum_vertex_elements]; + + memset (this -> vertex_element_type_counter_array, 0, VS_TOTAL_TYPES * sizeof (int)); } VertexElementArray::~VertexElementArray ( ) { delete this -> vertex_element_array; + delete this -> vertex_element_type_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; + } + + return state; } 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_POSITION_XYZ; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT3; @@ -85,12 +86,20 @@ void VertexElementArray::add_position_xyz_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_POSITION_XYZW; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT4; @@ -107,12 +116,20 @@ void VertexElementArray::add_position_xyzw_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_NORMAL; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT3; @@ -129,12 +146,20 @@ void VertexElementArray::add_normal_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_BINORMAL; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT3; @@ -151,12 +176,20 @@ void VertexElementArray::add_binormal_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_TANGENT; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT3; @@ -173,12 +206,20 @@ void VertexElementArray::add_tangent_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_DIFFUSE; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_D3DCOLOR; @@ -195,12 +236,20 @@ void VertexElementArray::add_diffuse_color_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_SPECULAR; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_D3DCOLOR; @@ -217,12 +266,20 @@ void VertexElementArray::add_specular_color_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_TEXTURE_U; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT1; @@ -239,12 +296,20 @@ void VertexElementArray::add_u_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_TEXTURE_UV; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT2; @@ -261,12 +326,20 @@ void VertexElementArray::add_uv_vertex_element (int stream_index) 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]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_TEXTURE_UVW; + vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> id]; + vertex_element_type_counter_array [vertex_element_type -> id]++; + vertex_element -> Stream = stream_index; vertex_element -> Offset = this -> offset; vertex_element -> Type = D3DDECLTYPE_FLOAT3; @@ -284,6 +357,7 @@ 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) @@ -291,6 +365,11 @@ int VertexElementArray::add_end_vertex_element (void) vertex_element = &this -> vertex_element_array [this -> total_elements]; memset (vertex_element, 0, sizeof (DIRECT_3D_VERTEX_ELEMENT)); + vertex_element_type = &this -> vertex_element_type_array [this -> total_elements]; + memset (vertex_element_type, 0, sizeof (VERTEX_ELEMENT_TYPE)); + + vertex_element_type -> id = VS_END; + vertex_element -> Stream = 0xFF; vertex_element -> Type = D3DDECLTYPE_UNUSED; @@ -317,40 +396,37 @@ CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg) : ShaderContext(s) { _state = false; -// _cg_context = (CGcontext)0; _cg_profile[SHADER_type_vert] = CG_PROFILE_UNKNOWN; _cg_profile[SHADER_type_frag] = CG_PROFILE_UNKNOWN; _cg_program[SHADER_type_vert] = (CGprogram)0; _cg_program[SHADER_type_frag] = (CGprogram)0; _vertex_size = 0; - _direct_3d_vertex_declaration = 0; + _vertex_element_array = 0; if (header == "//Cg") { // CGcontext is created once during Reset ( ) - if (gsg -> _cg_context == 0) { release_resources(); cerr << "Cg not supported by this video card.\n"; return; } - -// IGNORE THIS FOR NOW, SEEMS TO BE LOADING IN GL SPECIFIC PROFILES -if (false) -{ - // Parse any directives in the source. - string directive; - while (!s->parse_eof()) { - s->parse_line(directive, true, true); - vector_string pieces; - tokenize(directive, pieces, " \t"); - if ((pieces.size()==4)&&(pieces[0]=="//Cg")&&(pieces[1]=="profile")) { - suggest_cg_profile(pieces[2], pieces[3]); + // IGNORE THIS FOR NOW, SEEMS TO BE LOADING IN GL SPECIFIC PROFILES + if (false) + { + // Parse any directives in the source. + string directive; + while (!s->parse_eof()) { + s->parse_line(directive, true, true); + vector_string pieces; + tokenize(directive, pieces, " \t"); + if ((pieces.size()==4)&&(pieces[0]=="//Cg")&&(pieces[1]=="profile")) { + suggest_cg_profile(pieces[2], pieces[3]); + } } } -} // Select a profile if no preferred profile specified in the source. if (_cg_profile[SHADER_type_vert] == CG_PROFILE_UNKNOWN) { @@ -379,6 +455,22 @@ if (false) cerr << s->get_name() << ": unrecognized shader language " << header << "\n"; } +//////////////////////////////////////////////////////////////////// +// Function: DXShaderContext9::Destructor +// Access: Public +// Description: xyz +//////////////////////////////////////////////////////////////////// +CLP(ShaderContext):: +~CLP(ShaderContext)() { + release_resources(); + + if (_vertex_element_array) + { + delete _vertex_element_array; + _vertex_element_array = 0; + } +} + //////////////////////////////////////////////////////////////////// // Function: DXShaderContext9::suggest_cg_profile // Access: Private @@ -588,21 +680,6 @@ try_cg_compile(ShaderExpansion *s, GSG *gsg) } #endif -//////////////////////////////////////////////////////////////////// -// Function: DXShaderContext9::Destructor -// Access: Public -// Description: xyz -//////////////////////////////////////////////////////////////////// -CLP(ShaderContext):: -~CLP(ShaderContext)() { - release_resources(); - - if (_direct_3d_vertex_declaration) { - _direct_3d_vertex_declaration -> Release ( ); - _direct_3d_vertex_declaration = 0; - } -} - //////////////////////////////////////////////////////////////////// // Function: DXShaderContext9::release_resources // Access: Public @@ -644,47 +721,51 @@ bind(GSG *gsg) { HRESULT hr; // Bind the shaders. -// ????? cgD3D9EnableProfile(_cg_profile[SHADER_type_vert]); hr = cgD3D9BindProgram(_cg_program[SHADER_type_vert]); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "cgD3D9BindProgram vertex shader failed\n"; + if (FAILED (hr)) + { + dxgsg9_cat.error() << "cgD3D9BindProgram vertex shader failed\n"; } -// ????? cgD3D9EnableProfile(_cg_profile[SHADER_type_frag]); hr = cgD3D9BindProgram(_cg_program[SHADER_type_frag]); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "cgD3D9BindProgram pixel shader failed\n"; + if (FAILED (hr)) + { + dxgsg9_cat.error() << "cgD3D9BindProgram pixel shader failed\n"; } + // DEBUG + DBG_SH1 - IDirect3DVertexShader9 *vertex_shader; - IDirect3DPixelShader9 *pixel_shader; + IDirect3DVertexShader9 *vertex_shader; + IDirect3DPixelShader9 *pixel_shader; - hr = gsg -> _d3d_device -> GetVertexShader (&vertex_shader); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "GetVertexShader ( ) failed " - << D3DERRORSTRING(hr); - } - hr = gsg -> _d3d_device -> GetPixelShader (&pixel_shader); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "GetPixelShader ( ) failed " - << D3DERRORSTRING(hr); - } + hr = gsg -> _d3d_device -> GetVertexShader (&vertex_shader); + if (FAILED (hr)) + { + dxgsg9_cat.error() + << "GetVertexShader ( ) failed " + << D3DERRORSTRING(hr); + } + hr = gsg -> _d3d_device -> GetPixelShader (&pixel_shader); + if (FAILED (hr)) + { + dxgsg9_cat.error() + << "GetPixelShader ( ) failed " + << D3DERRORSTRING(hr); + } + + DBG_SH5 dxgsg9_cat.debug ( ) + << this -> _name + << "\nSHADER: V " + << vertex_shader + << " P " + << pixel_shader + << " CG VS" + << _cg_program[SHADER_type_vert] + << " CG PS" + << _cg_program[SHADER_type_frag] + << "\n"; + DBG_E - DBG_SH5 dxgsg9_cat.debug ( ) - << this -> _name - << "\nSHADER: V " - << vertex_shader - << " P " - << pixel_shader - << " CG VS" - << _cg_program[SHADER_type_vert] - << " CG PS" - << _cg_program[SHADER_type_frag] - << "\n"; DBG_E } #endif @@ -700,25 +781,21 @@ unbind(GSG *gsg) { #ifdef HAVE_CGDX9 if (gsg -> _cg_context != 0) { -// ????? cgD3D9DisableProfile(_cg_profile[SHADER_type_vert]); -// ????? cgD3D9DisableProfile(_cg_profile[SHADER_type_frag]); + + DBG_SH5 dxgsg9_cat.debug ( ) << "SHADER: unbind \n"; DBG_E + HRESULT hr; hr = gsg -> _d3d_device -> SetVertexShader (NULL); if (FAILED (hr)) { dxgsg9_cat.error() - << "SetVertexShader (NULL) failed " - << D3DERRORSTRING(hr); + << "SetVertexShader (NULL) failed " << D3DERRORSTRING(hr); } hr = gsg -> _d3d_device -> SetPixelShader (NULL); if (FAILED (hr)) { dxgsg9_cat.error() - << "SetPixelShader (NULL) failed " - << D3DERRORSTRING(hr); + << "SetPixelShader (NULL) failed " << D3DERRORSTRING(hr); } - - DBG_SH5 dxgsg9_cat.debug ( ) << "SHADER: unbind \n"; DBG_E - } #endif } @@ -760,7 +837,8 @@ issue_cg_auto_bind(const ShaderAutoBind &bind, GSG *gsg) case SIC_tps_modelproj: case SIC_itp_modelproj: -// cgGLetStateMatrixParameter(p, (cgD3D9enum)((bind.value >> 2)+4), (cgD3D9enum)(bind.value & 3)); +// ORIGINAL OpenGL CODE +// cgGLetStateMatrixParameter(p, (cgD3D9enum)((bind.value >> 2)+4), (cgD3D9enum)(bind.value & 3)); const LMatrix4f *p_matrix; @@ -796,7 +874,7 @@ p_matrix = &(gsg -> _internal_transform -> get_mat ( )); tex_matrix_attrib = gsg->_state._tex_matrix; // SHADER ISSUE: using default ????? GL texture matrix = which DX texture matrix ????? -p_matrix = &(tex_matrix_attrib -> get_mat ( )); + p_matrix = &(tex_matrix_attrib -> get_mat ( )); // SHADER ISSUE: ***** DX_TRANSPOSE REQUIRED FOR COMPATIBILITY temp_matrix.transpose_from (*p_matrix); @@ -808,7 +886,7 @@ p_matrix = &(tex_matrix_attrib -> get_mat ( )); const LMatrix4f *model_matrix; const LMatrix4f *projection_matrix; -DBG_SH4 dxgsg9_cat.debug ( ) << "SHADER: issue_cg_auto_bind CG_GL_MODELVIEW_PROJECTION_MATRIX " << bind.value << "\n"; DBG_E + DBG_SH4 dxgsg9_cat.debug ( ) << "SHADER: issue_cg_auto_bind CG_GL_MODELVIEW_PROJECTION_MATRIX " << bind.value << "\n"; DBG_E projection_matrix = &gsg->_projection_mat; @@ -1000,17 +1078,33 @@ issue_parameters(GSG *gsg) { #ifdef HAVE_CGDX9 -DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters\n"; DBG_E + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters\n"; DBG_E if (gsg -> _cg_context != 0) { // Pass in k-float parameters. for (int i=0; i<(int)_cg_fbind.size(); i++) { + const float *data; InternalName *id = _cg_fbind[i].name; const ShaderInput *input = gsg->_target._shader->get_shader_input(id); -DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_fbind " << id -> get_name ( ) << "\n"; DBG_E + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_fbind " << id -> get_name ( ) << "\n"; DBG_E - cgD3D9SetUniform (_cg_fbind[i].parameter, input->get_vector().get_data()); + data = input->get_vector().get_data(); + + DBG_SH3 + char string [256]; + + sprintf (string, "%f %f %f %f \n", data [0], data [1], data [2], data [3]); + dxgsg9_cat.debug ( ) << string; + DBG_E + + HRESULT hr; + + hr = cgD3D9SetUniform (_cg_fbind[i].parameter, data); + if (FAILED (hr)) + { + dxgsg9_cat.error() << "cgD3D9SetUniform failed " << D3DERRORSTRING(hr); + } } // Pass in k-float4x4 parameters. @@ -1021,7 +1115,7 @@ DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_fbind " << id -> if (input->get_nodepath().is_empty()) { dat = LMatrix4f::ident_mat().get_data(); -DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind " << id -> get_name ( ) << "\n"; DBG_E + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind " << id -> get_name ( ) << "\n"; DBG_E cgD3D9SetUniform (_cg_npbind[i].parameter, dat); @@ -1047,7 +1141,7 @@ DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind " << id - matrix [14] = dat[11]; matrix [15] = dat[15]; -DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind 2 \n"; DBG_E + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind 2 \n"; DBG_E cgD3D9SetUniform (_cg_npbind[i].parameter, matrix); } @@ -1061,7 +1155,7 @@ DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_npbind 2 \n"; DB // Pass in trans,tpose,row,col,xvec,yvec,zvec,pos parameters for (int i=0; i<(int)_cg_parameter_bind.size(); i++) { -DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_parameter_bind \n"; DBG_E + DBG_SH3 dxgsg9_cat.debug ( ) << "SHADER: issue_parameters, _cg_parameter_bind \n"; DBG_E bind_cg_transform(_cg_parameter_bind[i], gsg); } @@ -1133,8 +1227,6 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) #ifdef HAVE_CGDX9 if (gsg -> _cg_context) { - HRESULT hr; - /* ????? #ifdef SUPPORT_IMMEDIATE_MODE if (gsg->_use_sender) { @@ -1143,18 +1235,19 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) #endif // SUPPORT_IMMEDIATE_MODE */ -// map the vertex shader inputs into a DirectX vertex declaration -// create and cache the vertex declaration -// this can be done here since a vertex shader has a fixed input - - if (_direct_3d_vertex_declaration == 0) { - + // Create and cache a VertexElementArray that does most of the + // mapping from the vertex shader inputs to a VertexElementArray. + // This can be done since a vertex shader has a well defined input. + // Later when the vertex buffer is applied the offsets will + // be properly mapped. + if (_vertex_element_array == 0) + { const GeomVertexArrayData *array_data; Geom::NumericType numeric_type; int start, stride, num_values; int nvarying = _cg_varying.size(); -DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: update_shader_vertex_arrays: nvarying " << nvarying << "\n"; DBG_E + DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: update_shader_vertex_arrays: nvarying = " << nvarying << "\n"; DBG_E int stream_index; VertexElementArray *vertex_element_array; @@ -1179,128 +1272,128 @@ DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: update_shader_vertex_arrays: nvarying } } } - if (gsg->_vertex_data->get_array_info(name, array_data, num_values, - numeric_type, start, stride)) { - -if (false) { - -} else if (name == 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; - default: - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid number of vertex coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid vertex type " << numeric_type << "\n"; - } - -} else if (name == 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 ( ) << "VERTEX ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid texture coordinate type " << numeric_type << "\n"; - } - -} else if (name == 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 ( ) << "VERTEX ERROR: invalid number of normal coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid normal type " << numeric_type << "\n"; - } - -} else if (name == 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 ( ) << "VERTEX ERROR: invalid number of binormal coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid binormal type " << numeric_type << "\n"; - } - -} else if (name == 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 ( ) << "VERTEX ERROR: invalid number of tangent coordinate elements " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid tangent type " << numeric_type << "\n"; - } - -} else if (name == InternalName::get_color ( )) { - - if (numeric_type == Geom::NT_packed_dcba || numeric_type == Geom::NT_packed_dabc) { - switch (num_values) - { - case 4: - vertex_element_array -> add_diffuse_color_vertex_element (stream_index); - break; - default: - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid color coordinates " << num_values << "\n"; - break; - } - } else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid color type " << numeric_type << "\n"; - } - -} else { - dxgsg9_cat.error ( ) << "VERTEX ERROR: unsupported vertex element " << name -> get_name ( ) << "\n"; -} - - -// ????? + if (gsg->_vertex_data->get_array_info(name, array_data, num_values, numeric_type, start, stride)) + { /* - -gsg->_vertex_data; - + // ORIGINAL OpenGL CODE const unsigned char *client_pointer = gsg->setup_array_data(array_data); - cgD3D9SetParameterPointer(_cg_varying[i].parameter, + cgGLSetParameterPointer(_cg_varying[i].parameter, num_values, gsg->get_numeric_type(numeric_type), stride, client_pointer + start); */ + if (false) { + + } else if (name == 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 == 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 == 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 == 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 == 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 == 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"; + } + DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: update_shader_vertex_arrays " << i << "\n"; DBG_E DBG_SH1 dxgsg9_cat.debug ( ) << "\n name " << name -> get_name ( ) @@ -1311,75 +1404,38 @@ gsg->_vertex_data; << "\n"; DBG_E } else { - + dxgsg9_cat.error ( ) << "get_array_info ( ) failed\n"; } } int state; state = vertex_element_array -> add_end_vertex_element ( ); - - if (vertex_element_array) { - HRESULT hr; - - if (state) { - - if (cgD3D9ValidateVertexDeclaration (_cg_program [SHADER_type_vert], vertex_element_array -> vertex_element_array) == CG_TRUE) - { - dxgsg9_cat.debug() << "||||| cgD3D9ValidateVertexDeclaration succeeded\n"; - } - else - { - dxgsg9_cat.error() << "********************************************\n"; - dxgsg9_cat.error() << "***cgD3D9ValidateVertexDeclaration failed***\n"; - dxgsg9_cat.error() << "********************************************\n"; - } - - hr = gsg -> _d3d_device ->CreateVertexDeclaration (vertex_element_array -> vertex_element_array, &_direct_3d_vertex_declaration); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "CreateVertexDeclaration failed" - << D3DERRORSTRING(hr); - } - - _vertex_size = vertex_element_array -> offset; - - DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: vertex size " << _vertex_size << "\n"; DBG_E + if (state) + { + if (cgD3D9ValidateVertexDeclaration (_cg_program [SHADER_type_vert], vertex_element_array -> vertex_element_array) == CG_TRUE) + { + dxgsg9_cat.debug() << "|||||cgD3D9ValidateVertexDeclaration succeeded\n"; + } + else + { + dxgsg9_cat.error() << "********************************************\n"; + dxgsg9_cat.error() << "***cgD3D9ValidateVertexDeclaration failed***\n"; + dxgsg9_cat.error() << "********************************************\n"; } + _vertex_size = vertex_element_array -> offset; + + DBG_SH1 dxgsg9_cat.debug ( ) << "SHADER: vertex size " << _vertex_size << "\n"; DBG_E + + _vertex_element_array = vertex_element_array; + } + else + { + dxgsg9_cat.error ( ) << "VertexElementArray creation failed\n"; delete vertex_element_array; } } - if (_direct_3d_vertex_declaration) - { - hr = gsg -> _d3d_device -> SetVertexDeclaration (_direct_3d_vertex_declaration); - if (FAILED(hr)) { - dxgsg9_cat.error() - << "SetVertexDeclaration failed" << D3DERRORSTRING(hr); - } else { - DBG_SH5 dxgsg9_cat.debug() << "Shader SetVertexDeclaration ( ) \n"; DBG_E - } - -/* - UINT stream_number; - IDirect3DVertexBuffer9 *vertex_buffer; - UINT offset; - UINT stride; - - stream_number = 0; -vertex_buffer = 0; - offset = 0; - stride = 0; - - hr = gsg -> _d3d_device -> SetStreamSource (stream_number, vertex_buffer, offset, stride); - if (FAILED (hr)) { - dxgsg9_cat.error() - << "SetStreamSource failed " - << D3DERRORSTRING(hr); - } -*/ - - } } #endif // HAVE_CGDX9 } diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h index c5de03f06b..cce7f4289e 100644 --- a/panda/src/dxgsg9/dxShaderContext9.h +++ b/panda/src/dxgsg9/dxShaderContext9.h @@ -37,8 +37,10 @@ #define CLASSPREFIX_QUOTED "DX" +class VertexElementArray; class CLP(GraphicsStateGuardian); + //////////////////////////////////////////////////////////////////// // Class : DXShaderContext9 // Description : xyz @@ -63,7 +65,7 @@ public: void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg); int _vertex_size; - DIRECT_3D_VERTEX_DECLARATION _direct_3d_vertex_declaration; + class VertexElementArray *_vertex_element_array; // FOR DEBUGGING string _name; diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.cxx b/panda/src/dxgsg9/dxVertexBufferContext9.cxx index 3317b72cae..77d6cdb244 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.cxx +++ b/panda/src/dxgsg9/dxVertexBufferContext9.cxx @@ -4,7 +4,7 @@ //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license @@ -35,7 +35,7 @@ TypeHandle DXVertexBufferContext9::_type_handle; // Description: //////////////////////////////////////////////////////////////////// DXVertexBufferContext9:: -DXVertexBufferContext9(GeomVertexArrayData *data) : +DXVertexBufferContext9(GeomVertexArrayData *data, DXScreenData &scrn) : VertexBufferContext(data), _vbuffer(NULL) { @@ -44,13 +44,103 @@ DXVertexBufferContext9(GeomVertexArrayData *data) : // We have to start with the vertex data, and work up from there in // order, since that's the way the FVF is defined. + int index; int n = 0; int num_columns = array_format->get_num_columns(); + int total_elements; + + 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)); + + // create a simple vertex type mapping from the vertex elements + 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 == InternalName::get_vertex ( )) { + + switch (num_values) + { + case 3: + _vertex_element_type_array [index].id = VS_POSITION_XYZ; + break; + case 4: + _vertex_element_type_array [index].id = VS_POSITION_XYZW; + break; + default: + dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid number of position coordinate elements " << num_values << "\n"; + break; + } + + } else if (name == InternalName::get_texcoord ( )) { + + switch (num_values) + { + case 1: + _vertex_element_type_array [index].id = VS_TEXTURE_U; + break; + case 2: + _vertex_element_type_array [index].id = VS_TEXTURE_UV; + break; + case 3: + _vertex_element_type_array [index].id = VS_TEXTURE_UVW; + break; + default: + dxgsg9_cat.error ( ) << "VERTEX ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; + break; + } + + } else if (name == InternalName::get_normal ( )) { + + _vertex_element_type_array [index].id = VS_NORMAL; + + } else if (name == InternalName::get_binormal ( )) { + + _vertex_element_type_array [index].id = VS_BINORMAL; + + } else if (name == InternalName::get_tangent ( )) { + + _vertex_element_type_array [index].id = VS_TANGENT; + + } else if (name == InternalName::get_color ( )) { + + _vertex_element_type_array [index].id = VS_DIFFUSE; + + } else { + + dxgsg9_cat.error ( ) << "VERTEX ERROR: unsupported vertex element " << name -> get_name ( ) << "\n"; + _vertex_element_type_array [index].id = VS_ERROR; + } + +// SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER ??? + _vertex_element_type_array [index].stream = 0; + _vertex_element_type_array [index].offset = array_format -> get_column(index) -> get_start ( ); + + DBG_VEA dxgsg9_cat.debug() << "INFO VertexElementArray " << index + << " " << name -> get_name ( ) + << " VS ID " << _vertex_element_type_array [index].id + << " offset " << _vertex_element_type_array [index].offset + << "\n"; + DBG_E + } + + DBG_VEA dxgsg9_cat.debug() << "INFO stride " << array_format -> get_stride ( ) << " total bytes " << array_format-> get_total_bytes ( ) << "\n"; DBG_E + _fvf = 0; _managed = -1; _lru_page = 0; + _direct_3d_vertex_declaration = 0; + _shader_context = 0; + if (n < num_columns && array_format->get_column(n)->get_name() == InternalName::get_vertex()) { ++n; @@ -175,10 +265,18 @@ DXVertexBufferContext9(GeomVertexArrayData *data) : 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 ( ); - if (_lru_page) - { + if (_lru_page) { _lru_page -> _m.lru -> remove_page (_lru_page); _lru_page -> _m.lru -> free_page (_lru_page); _lru_page = 0; diff --git a/panda/src/dxgsg9/dxVertexBufferContext9.h b/panda/src/dxgsg9/dxVertexBufferContext9.h index eb717dae7b..9e14d23e65 100755 --- a/panda/src/dxgsg9/dxVertexBufferContext9.h +++ b/panda/src/dxgsg9/dxVertexBufferContext9.h @@ -30,7 +30,7 @@ //////////////////////////////////////////////////////////////////// class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext { public: - DXVertexBufferContext9(GeomVertexArrayData *data); + DXVertexBufferContext9(GeomVertexArrayData *data, DXScreenData &scrn); virtual ~DXVertexBufferContext9(); void free_vbuffer(void); @@ -40,9 +40,14 @@ public: IDirect3DVertexBuffer9 *_vbuffer; int _fvf; + int _managed; LruPage *_lru_page; + 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/dxgsg9_composite1.cxx b/panda/src/dxgsg9/dxgsg9_composite1.cxx index f1b5623ee2..14d40da47f 100755 --- a/panda/src/dxgsg9/dxgsg9_composite1.cxx +++ b/panda/src/dxgsg9/dxgsg9_composite1.cxx @@ -1,5 +1,5 @@ #include "dxgsg9base.h" -#include "wdxGraphicsBuffer9.cxx" +#include "dxShaderContext9.cxx" #include "config_dxgsg9.cxx" #include "dxTextureContext9.cxx" #include "dxVertexBufferContext9.cxx" @@ -8,4 +8,5 @@ #include "wdxGraphicsPipe9.cxx" #include "wdxGraphicsWindow9.cxx" #include "dxGraphicsDevice9.cxx" +#include "wdxGraphicsBuffer9.cxx" diff --git a/panda/src/dxgsg9/dxgsg9base.h b/panda/src/dxgsg9/dxgsg9base.h index f21d067a29..c546564f09 100755 --- a/panda/src/dxgsg9/dxgsg9base.h +++ b/panda/src/dxgsg9/dxgsg9base.h @@ -93,7 +93,7 @@ typedef DWORD DXShaderHandle; // uncomment to add refcnt debug output -#define DEBUG_RELEASES +// #define DEBUG_RELEASES #ifdef DEBUG_RELEASES #define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero) { \ diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 843ab16559..9fe8093681 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -4,7 +4,7 @@ //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2005, Disney Enterprises, Inc. All rights reserved +// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license @@ -27,8 +27,6 @@ // support copy from texture to ram? // check D3DCAPS2_DYNAMICTEXTURES -#define DBG_S if (false) { -#define DBG_E } #define FL << "\n" << __FILE__ << " " << __LINE__ << "\n" TypeHandle wdxGraphicsBuffer9::_type_handle; @@ -84,7 +82,7 @@ begin_frame() { return false; } -DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_frame\n"; DBG_E DXGraphicsStateGuardian9 *dxgsg; DCAST_INTO_R(dxgsg, _gsg, false); @@ -116,7 +114,7 @@ begin_render_texture() { state = false; render_target_index = 0; -DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::begin_render_texture\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::begin_render_texture\n"; DBG_E if (dxgsg -> _d3d_device) { Texture *tex = get_texture(0); @@ -207,7 +205,7 @@ DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::begin_render_texture\n"; DBG_ void wdxGraphicsBuffer9:: end_render_texture() { -DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::end_render_texture\n"; DBG_E +DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::end_render_texture\n"; DBG_E if (_gsg != (GraphicsStateGuardian *)NULL) { @@ -315,7 +313,7 @@ select_cube_map(int cube_map_index) { } } -DBG_S dxgsg9_cat.error ( ) << "select_cube_map " << _cube_map_index << "\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "select_cube_map " << _cube_map_index << "\n"; DBG_E } else { dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; @@ -346,7 +344,7 @@ make_current() { DCAST_INTO_V(dxgsg, _gsg); // do nothing here -DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::make_current\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "wdxGraphicsBuffer9::make_current\n"; DBG_E } @@ -480,7 +478,7 @@ open_buffer() { width = tex -> get_x_size ( ); height = tex -> get_y_size ( ); -DBG_S dxgsg9_cat.error ( ) << "-------------RTT SIZE " << "t width " << width << " t height " << height FL; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "-------------RTT SIZE " << "t width " << width << " t height " << height FL; DBG_E if (surface_description.Width < width || surface_description.Height < height) { format = surface_description.Format; @@ -493,7 +491,7 @@ DBG_S dxgsg9_cat.error ( ) << "-------------RTT SIZE " << "t width " << width << discard, &this -> _new_z_stencil_surface, NULL); if (SUCCEEDED (hr)) { -DBG_S dxgsg9_cat.error ( ) << "-------------OK CreatedDepthStencilSurface " << D3DERRORSTRING(hr) FL; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "-------------OK CreatedDepthStencilSurface " << D3DERRORSTRING(hr) FL; DBG_E state = true;