Improve mapping from Panda vertex elements to vertex shader inputs.

Fix vertex element name issue.
Make alpha textures the default texture format for Render to Texture have a fallback to non-alpha texture in case it is not supported.
This commit is contained in:
aignacio_sf 2006-02-17 01:21:51 +00:00
parent 8fbc824aab
commit 4d63a51e9e
6 changed files with 256 additions and 131 deletions

View File

@ -388,7 +388,7 @@ void DXGraphicsStateGuardian9::
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
DBG_SH3 dxgsg9_cat.debug ( ) << "apply_vertex_buffer\n"; DBG_E
bool set_stream_source;
HRESULT hr;
@ -501,18 +501,18 @@ apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context
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) {
while (source_vertex_element_type -> vs_input_type != VS_END) {
if (source_vertex_element_type -> vs_input_type == vertex_element_type -> vs_input_type &&
source_vertex_element_type -> index == vertex_element_type -> index) {
offset = source_vertex_element_type -> offset;
break;
}
source_vertex_element_type++;
}
if (source_vertex_element_type -> id == VS_END) {
if (source_vertex_element_type -> vs_input_type == VS_END) {
dxgsg9_cat.error()
<< "unable to find a mapping for vertex shader input type="
<< vertex_element_type -> id
<< vertex_element_type -> vs_input_type
<< " from vertex elements\n";
}
@ -1142,8 +1142,6 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
DBG_SH5 dxgsg9_cat.debug ( ) << "begin_draw_primitives\n"; DBG_E
// SHADER
if (_vertex_array_shader_context==0) {
if (_current_shader_context==0) {
@ -1164,13 +1162,108 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
_vertex_array_shader_expansion = _current_shader_expansion;
_vertex_array_shader_context = _current_shader_context;
// const GeomVertexFormat *format = _vertex_data->get_format();
const GeomVertexFormat *format = _vertex_data->get_format ( );
const GeomVertexArrayData *data;
int number_of_arrays = _vertex_data -> get_num_arrays ( );
// use the original data if possible
if (_current_shader_context && _vertex_data->get_num_arrays ( ) > 1) {
data = _vertex_data->get_array(1);
if (_current_shader_context && number_of_arrays > 1) {
// find a matching vertex format for the vertex shader's input if possible
VertexElementArray *vertex_element_array;
vertex_element_array = _current_shader_context -> _vertex_element_array;
if (vertex_element_array)
{
bool match;
bool multiple_matches;
int index;
int first_index;
match = false;
multiple_matches = false;
first_index = -1;
// quick check for a match
// find the one array with the minimum number of elements if possible
{
for (index = 0; index < number_of_arrays; index++) {
data = _vertex_data -> get_array (index);
const GeomVertexArrayFormat *array_format = data->get_array_format();
int number_of_columns = array_format->get_num_columns();
DBG_VEA
dxgsg9_cat.debug ( )
<< " data index " << index
<< " number_of_columns " << number_of_columns
<< " vertex_element_array -> total_elements " << vertex_element_array -> total_elements
<< "\n";
DBG_E
if (number_of_columns >= vertex_element_array -> total_elements) {
if (first_index >= 0) {
multiple_matches = true;
}
else {
first_index = index;
}
}
}
}
if (multiple_matches)
{
// ugh slow, need to find which one
for (index = first_index; index < number_of_arrays; index++)
{
data = _vertex_data -> get_array (index);
const GeomVertexArrayFormat *array_format = data->get_array_format();
int number_of_columns = array_format->get_num_columns();
if (number_of_columns >= vertex_element_array -> total_elements)
{
// check not implemented yet
dxgsg9_cat.error ( ) << "vertex_element_type_array check not implemented yet\n";
// build a vertex_element_type_array from data
// compare both vertex_element_type_array for a match
vertex_element_array -> vertex_element_type_array;
}
}
// since the check is not implemented yet use first_index for now
data = _vertex_data -> get_array (first_index);
match = true;
}
else
{
if (first_index >= 0) {
data = _vertex_data -> get_array (first_index);
match = true;
}
}
if (match) {
}
else {
// ERROR
dxgsg9_cat.error ( ) << "could not find matching vertex element data for vertex shader\n";
// just use the 0 array
data = _vertex_data->get_array(0);
}
}
else {
// ERROR
dxgsg9_cat.error ( ) << "_current_shader_context -> _vertex_element_array == 0\n";
}
}
else {
// The munger should have put the FVF data in the first array.
@ -2412,20 +2505,37 @@ reset() {
_supports_render_texture = false;
// default render to texture format
_screen->_render_to_texture_d3d_format = D3DFMT_X8R8G8B8;
_screen->_render_to_texture_d3d_format = D3DFMT_A8R8G8B8;
#define TOTAL_RENDER_TO_TEXTURE_FORMATS 3
D3DFORMAT render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS] =
{
D3DFMT_A8R8G8B8, // check for this format first
D3DFMT_X8R8G8B8,
(D3DFORMAT) 0, // place holder for _screen->_display_mode.Format
};
render_to_texture_formats [TOTAL_RENDER_TO_TEXTURE_FORMATS - 1] = _screen->_display_mode.Format;
hr = _d3d_device->GetCreationParameters (&creation_parameters);
if (SUCCEEDED (hr)) {
hr = _screen->_d3d9->CheckDeviceFormat (
creation_parameters.AdapterOrdinal,
creation_parameters.DeviceType,
_screen->_display_mode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
_screen->_render_to_texture_d3d_format);
if (SUCCEEDED (hr)) {
// match the display mode format for render to texture
_screen->_render_to_texture_d3d_format = _screen->_display_mode.Format;
_supports_render_texture = true;
int index;
for (index = 0; index < TOTAL_RENDER_TO_TEXTURE_FORMATS; index++) {
hr = _screen->_d3d9->CheckDeviceFormat (
creation_parameters.AdapterOrdinal,
creation_parameters.DeviceType,
_screen->_display_mode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
render_to_texture_formats [index]);
if (SUCCEEDED (hr)) {
_screen->_render_to_texture_d3d_format = render_to_texture_formats [index];
_supports_render_texture = true;
}
if (_supports_render_texture) {
break;
}
}
}
if (dxgsg9_cat.is_debug()) {
@ -2706,7 +2816,7 @@ do_issue_shader() {
context = (CLP(ShaderContext) *)(expansion->prepare_now(get_prepared_objects(), this));
}
if (context == 0) {
if (context == 0 || (context && context -> valid (this) == false)) {
if (_current_shader_context != 0) {
_current_shader_context->unbind(this);
_current_shader_expansion = 0;

View File

@ -45,13 +45,13 @@ typedef LPDIRECT3DPIXELSHADER9 DIRECT_3D_PIXEL_SHADER;
#include "dxShaderContext9.h"
#define DEBUG_ENABLE !false
#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_HLSL if (!false && DEBUG_ENABLE) {
#define DBG_HLSL if (false && DEBUG_ENABLE) {
#define DBG_VEA if (false && DEBUG_ENABLE) {
#define DBG_S if (false && DEBUG_ENABLE) {
#define DBG_E }

View File

@ -392,11 +392,12 @@ CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg) : ShaderContext(s) {
s->parse_init();
s->parse_line(header, true, true);
_state = false;
#ifdef HAVE_CGDX9
DBG_SH2 dxgsg9_cat.debug ( ) << "SHADER: Create ShaderContext \n"; DBG_E
_state = false;
_cg_shader = false;
_cg_profile[SHADER_type_vert] = CG_PROFILE_UNKNOWN;
@ -626,7 +627,7 @@ CLP(ShaderContext)(ShaderExpansion *s, GSG *gsg) : ShaderContext(s) {
// SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER?
stream_index = 0;
vertex_element_array = new VertexElementArray (_direct_3d_vertex_shader.total_semantics + 16);
vertex_element_array = new VertexElementArray (_direct_3d_vertex_shader.total_semantics + 2);
for (index = 0; index < _direct_3d_vertex_shader.total_semantics; index++) {
D3DXSEMANTIC *semantic;
@ -1661,7 +1662,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
// SHADER ISSUE: STREAM INDEX ALWAYS 0 FOR VERTEX BUFFER?
stream_index = 0;
vertex_element_array = new VertexElementArray (nvarying + 16);
vertex_element_array = new VertexElementArray (nvarying + 2);
for (int i=0; i<nvarying; i++) {
InternalName *name = _cg_varying[i].name;

View File

@ -46,92 +46,119 @@ DXVertexBufferContext9(GeomVertexArrayData *data, DXScreenData &scrn) :
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));
_vertex_element_type_array = 0;
// create a simple vertex type mapping from the vertex elements
for (index = 0; index < num_columns; index++)
VERTEX_ELEMENT_TYPE *vertex_element_type_array;
// if (scrn._dxgsg9 -> _current_shader_context)
{
int num_values;
const InternalName *name;
int total_elements;
unsigned char vertex_element_type_counter_array [VS_TOTAL_TYPES];
VERTEX_ELEMENT_TYPE *vertex_element_type;
name = array_format -> get_column (index) -> get_name ( );
num_values = array_format -> get_column(index) -> get_num_values ( );
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));
if (false) {
// 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;
} else if (name == InternalName::get_vertex ( )) {
name = array_format -> get_column (index) -> get_name ( );
num_values = array_format -> get_column(index) -> get_num_values ( );
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.warning ( ) << "VERTEX ERROR: invalid number of position coordinate elements " << num_values << "\n";
break;
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;
}
} else if (name == InternalName::get_texcoord ( )) {
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]++;
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.warning ( ) << "VERTEX ERROR: invalid number of vertex texture coordinate elements " << num_values << "\n";
break;
}
// 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 ( );
} else if (name == InternalName::get_normal ( )) {
DBG_VEA dxgsg9_cat.debug()
<< "INFO VertexElementArray " << index
<< " " << name -> get_name ( )
<< " VS INPUT TYPE " << vertex_element_type -> vs_input_type
<< " index " << vertex_element_type -> index
<< " offset " << vertex_element_type -> offset
<< "\n";
DBG_E
_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.warning ( ) << "VERTEX ERROR: unsupported vertex element " << name -> get_name ( ) << "\n";
_vertex_element_type_array [index].id = VS_ERROR;
vertex_element_type++;
}
// 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
DBG_VEA dxgsg9_cat.debug()
<< "INFO stride " << array_format -> get_stride ( )
<< " total bytes " << array_format-> get_total_bytes ( )
<< "\n";
DBG_E
}
DBG_VEA dxgsg9_cat.debug() << "INFO stride " << array_format -> get_stride ( ) << " total bytes " << array_format-> get_total_bytes ( ) << "\n"; DBG_E
_vertex_element_type_array = vertex_element_type_array;
_fvf = 0;
_managed = -1;

View File

@ -50,6 +50,12 @@ int VertexElementArray::set_vertex_element_offset (int vertex_element_index, int
return state;
}
void VertexElementArray::set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type) {
vertex_element_type -> vs_input_type = vs_input_type;
vertex_element_type -> index = vertex_element_type_counter_array [vertex_element_type -> vs_input_type];
vertex_element_type_counter_array [vertex_element_type -> vs_input_type]++;
}
void VertexElementArray::add_position_xyz_vertex_element (int stream_index) {
DIRECT_3D_VERTEX_ELEMENT *vertex_element;
VERTEX_ELEMENT_TYPE *vertex_element_type;
@ -58,9 +64,7 @@ void VertexElementArray::add_position_xyz_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_POSITION_XYZ, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -83,9 +87,7 @@ void VertexElementArray::add_position_xyzw_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_POSITION_XYZW, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -108,9 +110,7 @@ void VertexElementArray::add_normal_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_NORMAL, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -133,9 +133,7 @@ void VertexElementArray::add_binormal_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_BINORMAL, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -158,9 +156,7 @@ void VertexElementArray::add_tangent_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_TANGENT, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -183,9 +179,7 @@ void VertexElementArray::add_diffuse_color_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_DIFFUSE, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -208,9 +202,7 @@ void VertexElementArray::add_specular_color_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_SPECULAR, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -233,9 +225,7 @@ void VertexElementArray::add_u_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_TEXTURE_U, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -258,9 +248,7 @@ void VertexElementArray::add_uv_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_TEXTURE_UV, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -283,9 +271,7 @@ void VertexElementArray::add_uvw_vertex_element (int stream_index) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
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]++;
set_vs_input_type (VS_TEXTURE_UVW, vertex_element_type);
vertex_element -> Stream = stream_index;
vertex_element -> Offset = this -> offset;
@ -310,7 +296,7 @@ int VertexElementArray::add_end_vertex_element (void) {
vertex_element = &this -> vertex_element_array [this -> total_elements];
vertex_element_type = &this -> vertex_element_type_array [this -> total_elements];
vertex_element_type -> id = VS_END;
vertex_element_type -> vs_input_type = VS_END;
vertex_element -> Stream = 0xFF;
vertex_element -> Type = D3DDECLTYPE_UNUSED;

View File

@ -42,7 +42,7 @@ enum
typedef struct
{
int id; // this is VS_XXXXX
int vs_input_type; // this is VS_XXXXX from the enum above
int index;
int stream;
int offset;
@ -72,6 +72,7 @@ public:
~VertexElementArray ( );
int set_vertex_element_offset (int vertex_element_index, int offset);
void set_vs_input_type (int vs_input_type, VERTEX_ELEMENT_TYPE *vertex_element_type);
void add_position_xyz_vertex_element (int stream_index);
void add_position_xyzw_vertex_element (int stream_index);