00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "dxVertexBufferContext8.h"
00016 #include "geomVertexArrayData.h"
00017 #include "geomVertexArrayFormat.h"
00018 #include "graphicsStateGuardian.h"
00019 #include "pStatTimer.h"
00020 #include "internalName.h"
00021 #include "config_dxgsg8.h"
00022 #include "dxgsg8base.h"
00023
00024 TypeHandle DXVertexBufferContext8::_type_handle;
00025
00026
00027
00028
00029
00030
00031 DXVertexBufferContext8::
00032 DXVertexBufferContext8(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
00033 VertexBufferContext(pgo, data),
00034 _vbuffer(NULL)
00035 {
00036
00037 const GeomVertexArrayFormat *array_format = data->get_array_format();
00038
00039
00040
00041 int n = 0;
00042 int num_columns = array_format->get_num_columns();
00043
00044 _fvf = 0;
00045
00046 if (n < num_columns &&
00047 array_format->get_column(n)->get_name() == InternalName::get_vertex()) {
00048 ++n;
00049
00050 int num_blend_values = 0;
00051
00052 if (n < num_columns &&
00053 array_format->get_column(n)->get_name() == InternalName::get_transform_weight()) {
00054
00055 num_blend_values = array_format->get_column(n)->get_num_values();
00056 ++n;
00057 }
00058
00059 if (n < num_columns &&
00060 array_format->get_column(n)->get_name() == InternalName::get_transform_index()) {
00061
00062 _fvf |= D3DFVF_LASTBETA_UBYTE4;
00063 ++num_blend_values;
00064 ++n;
00065 }
00066
00067 switch (num_blend_values) {
00068 case 0:
00069 _fvf |= D3DFVF_XYZ;
00070 break;
00071
00072 case 1:
00073 _fvf |= D3DFVF_XYZB1;
00074 break;
00075
00076 case 2:
00077 _fvf |= D3DFVF_XYZB2;
00078 break;
00079
00080 case 3:
00081 _fvf |= D3DFVF_XYZB3;
00082 break;
00083
00084 case 4:
00085 _fvf |= D3DFVF_XYZB4;
00086 break;
00087
00088 case 5:
00089 _fvf |= D3DFVF_XYZB5;
00090 break;
00091 }
00092 }
00093
00094 if (n < num_columns &&
00095 array_format->get_column(n)->get_name() == InternalName::get_normal()) {
00096 _fvf |= D3DFVF_NORMAL;
00097 ++n;
00098 }
00099 if (n < num_columns &&
00100 array_format->get_column(n)->get_name() == InternalName::get_color()) {
00101 _fvf |= D3DFVF_DIFFUSE;
00102 ++n;
00103 }
00104
00105
00106
00107 int texcoord_index = 0;
00108 while (n < num_columns &&
00109 array_format->get_column(n)->get_contents() == Geom::C_texcoord) {
00110 const GeomVertexColumn *column = array_format->get_column(n);
00111 switch (column->get_num_values()) {
00112 case 1:
00113 _fvf |= D3DFVF_TEXCOORDSIZE1(texcoord_index);
00114 ++n;
00115 break;
00116 case 2:
00117 _fvf |= D3DFVF_TEXCOORDSIZE2(texcoord_index);
00118 ++n;
00119 break;
00120 case 3:
00121 _fvf |= D3DFVF_TEXCOORDSIZE3(texcoord_index);
00122 ++n;
00123 break;
00124 case 4:
00125 _fvf |= D3DFVF_TEXCOORDSIZE4(texcoord_index);
00126 ++n;
00127 break;
00128 }
00129 ++texcoord_index;
00130 }
00131
00132 switch (texcoord_index) {
00133 case 0:
00134 break;
00135 case 1:
00136 _fvf |= D3DFVF_TEX1;
00137 break;
00138 case 2:
00139 _fvf |= D3DFVF_TEX2;
00140 break;
00141 case 3:
00142 _fvf |= D3DFVF_TEX3;
00143 break;
00144 case 4:
00145 _fvf |= D3DFVF_TEX4;
00146 break;
00147 case 5:
00148 _fvf |= D3DFVF_TEX5;
00149 break;
00150 case 6:
00151 _fvf |= D3DFVF_TEX6;
00152 break;
00153 case 7:
00154 _fvf |= D3DFVF_TEX7;
00155 break;
00156 case 8:
00157 _fvf |= D3DFVF_TEX8;
00158 break;
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167 DXVertexBufferContext8::
00168 ~DXVertexBufferContext8() {
00169 if (_vbuffer != NULL) {
00170 if (dxgsg8_cat.is_debug()) {
00171 dxgsg8_cat.debug()
00172 << "deleting vertex buffer " << _vbuffer << "\n";
00173 }
00174
00175 RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
00176 _vbuffer = NULL;
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 void DXVertexBufferContext8::
00196 evict_lru() {
00197 dequeue_lru();
00198
00199 if (_vbuffer != NULL) {
00200 if (dxgsg8_cat.is_debug()) {
00201 dxgsg8_cat.debug()
00202 << "deleting vertex buffer " << _vbuffer << "\n";
00203 }
00204
00205 RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
00206 _vbuffer = NULL;
00207 }
00208
00209 update_data_size_bytes(0);
00210 mark_unloaded();
00211 }
00212
00213
00214
00215
00216
00217
00218
00219 void DXVertexBufferContext8::
00220 create_vbuffer(DXScreenData &scrn,
00221 const GeomVertexArrayDataHandle *reader) {
00222 nassertv(reader->get_object() == get_data());
00223 Thread *current_thread = reader->get_current_thread();
00224
00225 if (_vbuffer != NULL) {
00226 if (dxgsg8_cat.is_debug()) {
00227 dxgsg8_cat.debug()
00228 << "deleting vertex buffer " << _vbuffer << "\n";
00229 }
00230
00231 RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
00232 _vbuffer = NULL;
00233 }
00234
00235 PStatTimer timer(GraphicsStateGuardian::_create_vertex_buffer_pcollector,
00236 current_thread);
00237
00238 HRESULT hr = scrn._d3d_device->CreateVertexBuffer
00239
00240
00241 (reader->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
00242 _fvf, D3DPOOL_DEFAULT, &_vbuffer);
00243 if (FAILED(hr)) {
00244 dxgsg8_cat.warning()
00245 << "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
00246 _vbuffer = NULL;
00247 } else {
00248 if (dxgsg8_cat.is_debug()) {
00249 dxgsg8_cat.debug()
00250 << "created vertex buffer " << _vbuffer << ": "
00251 << reader->get_num_rows() << " vertices "
00252 << *reader->get_array_format() << "\n";
00253 }
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 bool DXVertexBufferContext8::
00264 upload_data(const GeomVertexArrayDataHandle *reader, bool force) {
00265 nassertr(reader->get_object() == get_data(), false);
00266 nassertr(_vbuffer != NULL, false);
00267 Thread *current_thread = reader->get_current_thread();
00268
00269 const unsigned char *data_pointer = reader->get_read_pointer(force);
00270 if (data_pointer == NULL) {
00271 return false;
00272 }
00273 int data_size = reader->get_data_size_bytes();
00274
00275 if (dxgsg8_cat.is_spam()) {
00276 dxgsg8_cat.spam()
00277 << "copying " << data_size
00278 << " bytes into vertex buffer " << _vbuffer << "\n";
00279 }
00280
00281 PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector,
00282 current_thread);
00283
00284 BYTE *local_pointer;
00285
00286 HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD);
00287 if (FAILED(hr)) {
00288 dxgsg8_cat.error()
00289 << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
00290 return false;
00291 }
00292
00293 GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
00294 memcpy(local_pointer, data_pointer, data_size);
00295
00296 _vbuffer->Unlock();
00297 return true;
00298 }
00299