dx9 shader support from zhao

This commit is contained in:
David Rose 2011-09-28 18:42:58 +00:00
parent 6bed0cf394
commit cd79af53fe
16 changed files with 1111 additions and 1501 deletions

View File

@ -360,7 +360,11 @@ protected:
// This bitmask contains a 1 bit everywhere that _state_rs has a // This bitmask contains a 1 bit everywhere that _state_rs has a
// known value. If a bit is 0, the corresponding state must be // known value. If a bit is 0, the corresponding state must be
// re-sent. // 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 _state_mask;
RenderState::SlotMask _inv_state_mask;
// The current transform, as of the last call to // The current transform, as of the last call to
// set_state_and_transform(). // set_state_and_transform().

View File

@ -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 // Make sure the FVF-style array we just built up is first in the
// list. // list.
new_format->insert_array(0, new_array_format); 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 // Make sure the FVF-style array we just built up is first in the
// list. // list.
new_format->insert_array(0, new_array_format); new_format->insert_array(0, new_array_format);

File diff suppressed because it is too large Load Diff

View File

@ -33,12 +33,6 @@
#include "lru.h" #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 "vertexElementArray.h"
#include "dxShaderContext9.h" #include "dxShaderContext9.h"
@ -83,10 +77,15 @@ public:
void release_shader(ShaderContext *sc); void release_shader(ShaderContext *sc);
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data); virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
bool apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context, bool apply_vertex_buffer(VertexBufferContext *vbc,
const GeomVertexArrayDataHandle *reader, bool force, string name); const GeomVertexArrayDataHandle *reader,
bool force);
virtual void release_vertex_buffer(VertexBufferContext *vbc); 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); virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
bool apply_index_buffer(IndexBufferContext *ibc, bool apply_index_buffer(IndexBufferContext *ibc,
const GeomPrimitivePipelineReader *reader, bool force); const GeomPrimitivePipelineReader *reader, bool force);
@ -206,8 +205,8 @@ protected:
void do_auto_rescale_normal(); void do_auto_rescale_normal();
// void disable_standard_vertex_arrays(); void disable_standard_vertex_arrays();
// void update_standard_vertex_arrays(); bool update_standard_vertex_arrays(bool force);
void disable_standard_texture_bindings(); void disable_standard_texture_bindings();
void update_standard_texture_bindings(); void update_standard_texture_bindings();
@ -301,7 +300,6 @@ protected:
PT(Shader) _texture_binding_shader; PT(Shader) _texture_binding_shader;
CLP(ShaderContext) *_texture_binding_shader_context; CLP(ShaderContext) *_texture_binding_shader_context;
const DXVertexBufferContext9 *_active_vbuffer;
const DXIndexBufferContext9 *_active_ibuffer; const DXIndexBufferContext9 *_active_ibuffer;
bool _overlay_windows_supported; bool _overlay_windows_supported;
@ -320,6 +318,7 @@ protected:
UINT _available_texture_memory; UINT _available_texture_memory;
DWORD _last_fvf; DWORD _last_fvf;
int _num_bound_streams;
// Cache the data necessary to bind each particular light each // Cache the data necessary to bind each particular light each
// frame, so if we bind a given light multiple times, we only have // frame, so if we bind a given light multiple times, we only have

View File

@ -14,6 +14,7 @@
#include "dxGraphicsStateGuardian9.h" #include "dxGraphicsStateGuardian9.h"
#include "dxShaderContext9.h" #include "dxShaderContext9.h"
#include "dxVertexBufferContext9.h"
#include <io.h> #include <io.h>
#include <stdio.h> #include <stdio.h>
@ -37,8 +38,11 @@ TypeHandle CLP(ShaderContext)::_type_handle;
CLP(ShaderContext):: CLP(ShaderContext)::
CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
_vertex_size = 0; _vertex_element_array = NULL;
_vertex_element_array = 0; _vertex_declaration = NULL;
_num_bound_streams = 0;
_name = s->get_filename ( ); _name = s->get_filename ( );
#ifdef HAVE_CG #ifdef HAVE_CG
@ -131,9 +135,14 @@ CLP(ShaderContext)::
~CLP(ShaderContext)() { ~CLP(ShaderContext)() {
release_resources(); 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; delete _vertex_element_array;
_vertex_element_array = 0; _vertex_element_array = NULL;
} }
} }
@ -203,6 +212,10 @@ release_resources() {
_cg_parameter_map.clear(); _cg_parameter_map.clear();
} }
#endif #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. // Description: Disable all the vertex arrays used by this shader.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CLP(ShaderContext):: void CLP(ShaderContext)::
disable_shader_vertex_arrays(GSG *gsg) disable_shader_vertex_arrays(GSG *gsg) {
{ LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
#ifdef HAVE_CG
if (_cg_context) { for ( int array_index = 0; array_index < _num_bound_streams; ++array_index )
// DO NOTHING, CURRENTLY USING ONLY ONE STREAM SOURCE {
device->SetStreamSource( array_index, NULL, 0, 0 );
} }
#endif _num_bound_streams = 0;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -493,54 +507,62 @@ disable_shader_vertex_arrays(GSG *gsg)
// it may unnecessarily disable arrays then immediately // it may unnecessarily disable arrays then immediately
// reenable them. We may optimize this someday. // reenable them. We may optimize this someday.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CLP(ShaderContext)::
// DEBUG update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
#if DEBUG_SHADER
VertexElementArray *global_vertex_element_array = 0;
#endif
void CLP(ShaderContext)::
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
{
if (prev) prev->disable_shader_vertex_arrays(gsg); if (prev) prev->disable_shader_vertex_arrays(gsg);
#ifdef HAVE_CG #ifdef HAVE_CG
if (_cg_context) { if (!_cg_context) {
return true;
}
#ifdef SUPPORT_IMMEDIATE_MODE #ifdef SUPPORT_IMMEDIATE_MODE
/* /*
if (gsg->_use_sender) { if (gsg->_use_sender) {
dxgsg9_cat.error() << "immediate mode shaders not implemented yet\n"; dxgsg9_cat.error() << "immediate mode shaders not implemented yet\n";
} else } else
*/ */
#endif // SUPPORT_IMMEDIATE_MODE #endif // SUPPORT_IMMEDIATE_MODE
{ {
if (_vertex_element_array == 0) {
bool error;
const GeomVertexArrayDataHandle *array_reader;
Geom::NumericType numeric_type;
int start, stride, num_values;
int nvarying = _shader->_var_spec.size(); int nvarying = _shader->_var_spec.size();
LPDIRECT3DDEVICE9 device = gsg->_screen->_d3d_device;
HRESULT hr;
int stream_index; // Discard and recreate the VertexElementArray. This thrashes pretty bad....
VertexElementArray *vertex_element_array; if ( _vertex_element_array != NULL ) {
delete _vertex_element_array;
}
_vertex_element_array = new VertexElementArray(nvarying + 2);
VertexElementArray* vertex_element_array = _vertex_element_array;
error = false; // Experimentally determined that DX doesn't like us crossing the streams!
// SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER? // It seems to be okay with out-of-order offsets in both source and destination,
stream_index = 0; // but it wants all stream X entries grouped together, then all stream Y entries, etc.
vertex_element_array = new VertexElementArray (nvarying + 2); // To accomplish this out outer loop processes arrays ("streams"), and we repeatedly
// iterate the parameters to pull out only those for a single stream.
#if DEBUG_SHADER int number_of_arrays = gsg->_data_reader->get_num_arrays();
// DEBUG for ( int array_index = 0; array_index < number_of_arrays; ++array_index ) {
global_vertex_element_array = vertex_element_array; const GeomVertexArrayDataHandle* array_reader =
#endif gsg->_data_reader->get_array_reader( array_index );
if ( array_reader == NULL ) {
for (int i=0; i<nvarying; i++) { dxgsg9_cat.error() << "Unable to get reader for array " << array_index << "\n";
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
if (p == NULL) {
continue; continue;
} }
InternalName *name = _shader->_var_spec[i]._name;
int texslot = _shader->_var_spec[i]._append_uv; 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()) { if (texslot >= 0 && texslot < gsg->_state_texture->get_num_on_stages()) {
TextureStage *stage = gsg->_state_texture->get_on_stage(texslot); TextureStage *stage = gsg->_state_texture->get_on_stage(texslot);
InternalName *texname = stage->get_texcoord_name(); InternalName *texname = stage->get_texcoord_name();
@ -550,164 +572,184 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
name = name->append(texname->get_basename()); name = name->append(texname->get_basename());
} }
} }
if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) {
if (false) { const GeomVertexArrayDataHandle* param_array_reader;
Geom::NumericType numeric_type;
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;
}
} else if (name -> get_top ( ) == InternalName::get_vertex ( )) { // If not associated with the array we're working on, move on.
if ( param_array_reader != array_reader ) {
continue;
}
const char* semantic = cgGetParameterSemantic( p );
if ( semantic == NULL ) {
dxgsg9_cat.error() << "Unable to retrieve semantic for parameter " << var_index << "\n";
continue;
}
if ( strncmp( semantic, "POSITION", strlen( "POSITION" ) ) == 0 ) {
if (numeric_type == Geom::NT_float32) { if (numeric_type == Geom::NT_float32) {
switch (num_values) { switch (num_values) {
case 3: case 3:
vertex_element_array -> add_position_xyz_vertex_element (stream_index); vertex_element_array->add_position_xyz_vertex_element(array_index, start);
break; break;
case 4: case 4:
vertex_element_array -> add_position_xyzw_vertex_element (stream_index); vertex_element_array->add_position_xyzw_vertex_element(array_index, start);
break; break;
default: default:
dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid number of vertex coordinate elements " << num_values << "\n";
break; break;
} }
} else { } else {
dxgsg9_cat.error ( ) << "VE ERROR: invalid vertex type " << numeric_type << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid vertex type " << numeric_type << "\n";
} }
} else if ( strncmp( semantic, "TEXCOORD", strlen( "TEXCOORD" ) ) == 0 ) {
} else if (name -> get_top ( ) == InternalName::get_texcoord ( )) { int slot = atoi( semantic + strlen( "TEXCOORD" ) );
if (numeric_type == Geom::NT_float32) { if (numeric_type == Geom::NT_float32) {
switch (num_values) switch (num_values) {
{
case 1: case 1:
vertex_element_array -> add_u_vertex_element (stream_index); vertex_element_array->add_u_vertex_element(array_index, start, slot);
break; break;
case 2: case 2:
vertex_element_array -> add_uv_vertex_element (stream_index); vertex_element_array->add_uv_vertex_element(array_index, start, slot);
break; break;
case 3: case 3:
vertex_element_array -> add_uvw_vertex_element (stream_index); vertex_element_array->add_uvw_vertex_element(array_index, start, slot);
break; break;
default: default:
dxgsg9_cat.error ( ) << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n";
break; break;
} }
} else { } else {
dxgsg9_cat.error ( ) << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid texture coordinate type " << numeric_type << "\n";
} }
} else if ( strncmp( semantic, "COLOR", strlen( "COLOR" ) ) == 0 ) {
} 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 || if (numeric_type == Geom::NT_packed_dcba ||
numeric_type == Geom::NT_packed_dabc || numeric_type == Geom::NT_packed_dabc ||
numeric_type == Geom::NT_uint8) { numeric_type == Geom::NT_uint8) {
switch (num_values) switch (num_values) {
{
case 4: case 4:
vertex_element_array -> add_diffuse_color_vertex_element (stream_index); vertex_element_array->add_diffuse_color_vertex_element(array_index, start);
break; break;
default: default:
dxgsg9_cat.error ( ) << "VE ERROR: invalid color coordinates " << num_values << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid color coordinates " << num_values << "\n";
break; break;
} }
} else { } else {
dxgsg9_cat.error ( ) << "VE ERROR: invalid color type " << numeric_type << "\n"; dxgsg9_cat.error() << "VE ERROR: invalid color type " << numeric_type << "\n";
}
} 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 { } else {
dxgsg9_cat.error ( ) << "VE ERROR: unsupported vertex element " << name -> get_name ( ) << "\n"; 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 { } else {
dxgsg9_cat.error ( ) dxgsg9_cat.error() << "VE ERROR: invalid binormal type " << numeric_type << "\n";
<< "get_array_info ( ) failed for shader " }
<< _name } else if ( strncmp( semantic, "TANGENT", strlen( "TANGENT" ) ) == 0 ) {
<< "\n" if (numeric_type == Geom::NT_float32) {
<< " vertex element name = " switch (num_values) {
<< name -> get_name ( ) case 3:
<< "\n"; vertex_element_array->add_tangent_vertex_element(array_index, start);
error = true; 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";
} }
} }
if (error) { // Get the vertex buffer for this array.
delete vertex_element_array; CLP(VertexBufferContext)* dvbc;
} if (!gsg->setup_array_data(dvbc, array_reader, force)) {
else { dxgsg9_cat.error() << "Unable to setup vertex buffer for array " << array_index << "\n";
int state; continue;
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 {
} }
_vertex_size = vertex_element_array -> offset; // Bind this array as the data source for the corresponding stream.
_vertex_element_array = vertex_element_array; const GeomVertexArrayFormat* array_format = array_reader->get_array_format();
} hr = device->SetStreamSource( array_index, dvbc->_vbuffer, 0, array_format->get_stride() );
else { if (FAILED(hr)) {
dxgsg9_cat.error ( ) << "VertexElementArray creation failed\n"; dxgsg9_cat.error() << "SetStreamSource failed" << D3DERRORSTRING(hr);
delete vertex_element_array;
} }
} }
_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 #endif // HAVE_CG
return true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -76,14 +76,17 @@ public:
void issue_parameters(GSG *gsg, int altered); void issue_parameters(GSG *gsg, int altered);
void issue_transform(GSG *gsg); void issue_transform(GSG *gsg);
void disable_shader_vertex_arrays(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 disable_shader_texture_bindings(GSG *gsg);
void update_shader_texture_bindings(CLP(ShaderContext) *prev, 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 // FOR DEBUGGING
int _vertex_size;
string _name; string _name;
private: private:

View File

@ -29,8 +29,10 @@ TypeHandle DXVertexBufferContext9::_type_handle;
// Access: Public // Access: Public
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
DXVertexBufferContext9:: CLP(VertexBufferContext)::
DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn) : CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
PreparedGraphicsObjects *pgo,
GeomVertexArrayData *data) :
VertexBufferContext(pgo, data), VertexBufferContext(pgo, data),
_vbuffer(NULL) _vbuffer(NULL)
{ {
@ -43,112 +45,11 @@ DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data,
int n = 0; int n = 0;
int num_columns = array_format->get_num_columns(); 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; _fvf = 0;
_managed = -1;
_direct_3d_vertex_declaration = 0;
_shader_context = 0;
if (n < num_columns && if (n < num_columns &&
array_format->get_column(n)->get_name() == InternalName::get_vertex()) { array_format->get_column(n)->get_name() == InternalName::get_vertex()) {
Geom::Contents contents = array_format->get_column(n)->get_contents();
++n; ++n;
int num_blend_values = 0; 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 // Function: DXVertexBufferContext9::evict_lru
// Access: Public, Virtual // Access: Public, Virtual
@ -298,162 +179,16 @@ DXVertexBufferContext9::
// case the eviction will be requested again much // case the eviction will be requested again much
// later). // later).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXVertexBufferContext9:: void CLP(VertexBufferContext)::
evict_lru() { evict_lru() {
dequeue_lru(); dequeue_lru();
free_vbuffer();
if ( _vbuffer != NULL ) {
_vbuffer->Release();
_vbuffer = NULL;
}
update_data_size_bytes(0); update_data_size_bytes(0);
mark_unloaded(); 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;
}

View File

@ -18,33 +18,27 @@
#include "pandabase.h" #include "pandabase.h"
#include "dxgsg9base.h" #include "dxgsg9base.h"
#include "vertexBufferContext.h" #include "vertexBufferContext.h"
#include "deletedChain.h"
class CLP(GraphicsStateGuardian);
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : DXVertexBufferContext9 // Class : DXVertexBufferContext9
// Description : Caches a GeomVertexArrayData in the DirectX device as // Description : Caches a GeomVertexArrayData in the DirectX device as
// a vertex buffer. // a vertex buffer.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext { class EXPCL_PANDADX CLP(VertexBufferContext) : public VertexBufferContext {
public: public:
DXVertexBufferContext9(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data, DXScreenData &scrn); CLP(VertexBufferContext)(CLP(GraphicsStateGuardian) *dxgsg,
virtual ~DXVertexBufferContext9(); PreparedGraphicsObjects *pgo,
GeomVertexArrayData *data);
ALLOC_DELETED_CHAIN(CLP(VertexBufferContext));
virtual void evict_lru(); virtual void evict_lru();
void free_vbuffer(); LPDIRECT3DVERTEXBUFFER9 _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;
int _fvf; int _fvf;
int _managed;
VERTEX_ELEMENT_TYPE *_vertex_element_type_array;
DIRECT_3D_VERTEX_DECLARATION _direct_3d_vertex_declaration;
CLP(ShaderContext) *_shader_context;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -16,294 +16,213 @@
#include "vertexElementArray.h" #include "vertexElementArray.h"
VertexElementArray::VertexElementArray (int maximum_vertex_elements) { VertexElementArray::VertexElementArray(int maximum_vertex_elements) {
this -> offset = 0; _total_elements = 0;
this -> total_elements = 0; _maximum_vertex_elements = maximum_vertex_elements;
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);
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 ( ) { VertexElementArray::~VertexElementArray() {
delete this -> vertex_element_array; delete _vertex_element_array;
delete this -> vertex_element_type_array;
} }
int VertexElementArray::set_vertex_element_offset (int vertex_element_index, int offset) { void VertexElementArray::add_position_xyz_vertex_element(int stream_index, int offset) {
int state; if (_total_elements >= _maximum_vertex_elements) {
DIRECT_3D_VERTEX_ELEMENT *vertex_element; return;
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; 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) { void VertexElementArray::add_position_xyzw_vertex_element(int stream_index, int offset) {
vertex_element_type -> vs_input_type = vs_input_type; if (_total_elements >= _maximum_vertex_elements) {
vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type]; return;
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;
} }
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;
} }

View File

@ -15,36 +15,6 @@
#ifndef VERTEX_ELEMENT_ARRAY_H #ifndef VERTEX_ELEMENT_ARRAY_H
#define 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 // Class : VertexElementArray
// Description : This class gives the ability for a user-friendly way // Description : This class gives the ability for a user-friendly way
@ -67,28 +37,26 @@ public:
VertexElementArray (int maximum_vertex_elements); VertexElementArray (int maximum_vertex_elements);
~VertexElementArray ( ); ~VertexElementArray ( );
int set_vertex_element_offset (int vertex_element_index, int offset); void add_position_xyz_vertex_element (int stream_index, int offset);
void set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type); void add_position_xyzw_vertex_element (int stream_index, int offset);
void add_position_xyz_vertex_element (int stream_index); void add_normal_vertex_element (int stream_index, int offset);
void add_position_xyzw_vertex_element (int stream_index); void add_binormal_vertex_element (int stream_index, int offset);
void add_normal_vertex_element (int stream_index); void add_tangent_vertex_element (int stream_index, int offset);
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; void add_diffuse_color_vertex_element (int stream_index, int offset);
int total_elements; void add_specular_color_vertex_element (int stream_index, int offset);
int maximum_vertex_elements;
int total_texture_coordinate_elements; void add_u_vertex_element (int stream_index, int offset, int texture_stage);
int vertex_element_type_counter_array [VS_TOTAL_TYPES]; void add_uv_vertex_element (int stream_index, int offset, int texture_stage);
DIRECT_3D_VERTEX_ELEMENT *vertex_element_array; void add_uvw_vertex_element (int stream_index, int offset, int texture_stage);
VERTEX_ELEMENT_TYPE *vertex_element_type_array;
bool add_end_vertex_element (void);
int _total_elements;
int _maximum_vertex_elements;
LPD3DVERTEXELEMENT9 _vertex_element_array;
}; };
#endif #endif

View File

@ -341,7 +341,7 @@ reset() {
// Build _inv_state_mask as a mask of 1's where we don't care, and // 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. // 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(ShaderAttrib::get_class_slot());
_inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot()); _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
_inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot()); _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());

View File

@ -652,7 +652,7 @@ public:
DeletedDisplayLists _deleted_display_lists; DeletedDisplayLists _deleted_display_lists;
DeletedDisplayLists _deleted_queries; DeletedDisplayLists _deleted_queries;
RenderState::SlotMask _inv_state_mask; //RenderState::SlotMask _inv_state_mask;
bool _track_errors; bool _track_errors;
bool _allow_flush; bool _allow_flush;

View File

@ -476,7 +476,7 @@ output(ostream &out) const {
for (ci = _columns.begin(); ci != _columns.end(); ++ci) { for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
const GeomVertexColumn *column = (*ci); const GeomVertexColumn *column = (*ci);
if (column->get_start() > last_pos) { if (column->get_start() > last_pos) {
out << " ..." << (column->get_start() - last_pos) << "..."; out << " (..." << (column->get_start() - last_pos) << "...)";
} }
out << " " << *column; out << " " << *column;
last_pos = column->get_start() + column->get_total_bytes(); last_pos = column->get_start() + column->get_total_bytes();

View File

@ -622,7 +622,10 @@ synthesize_shader(const RenderState *rs) {
analyze_renderstate(rs); analyze_renderstate(rs);
reset_register_allocator(); 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. // These variables will hold the results of register allocation.
@ -998,7 +1001,7 @@ synthesize_shader(const RenderState *rs) {
if (_lighting) { if (_lighting) {
text << "\t // Begin view-space light calculations\n"; text << "\t // Begin view-space light calculations\n";
text << "\t float ldist,lattenv,langle;\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) { if (_shadows && _auto_shadow_on) {
text << "\t float lshad;\n"; text << "\t float lshad;\n";
} }

View File

@ -95,7 +95,6 @@ reset() {
// Build _inv_state_mask as a mask of 1's where we don't care, and // 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. // 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(ColorAttrib::get_class_slot());
_inv_state_mask.clear_bit(ColorScaleAttrib::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(CullFaceAttrib::get_class_slot());

View File

@ -170,7 +170,6 @@ private:
bool _texture_replace; bool _texture_replace;
bool _filled_flat; bool _filled_flat;
bool _auto_rescale_normal; bool _auto_rescale_normal;
RenderState::SlotMask _inv_state_mask;
CPT(TransformState) _scissor_mat; CPT(TransformState) _scissor_mat;