00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wdxGraphicsPipe8.h"
00016 #include "wdxGraphicsBuffer8.h"
00017 #include "pStatTimer.h"
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #define FL << "\n" << __FILE__ << " " << __LINE__ << "\n"
00030
00031 TypeHandle wdxGraphicsBuffer8::_type_handle;
00032
00033
00034
00035
00036
00037
00038
00039 wdxGraphicsBuffer8::
00040 wdxGraphicsBuffer8(GraphicsEngine *engine, GraphicsPipe *pipe,
00041 const string &name,
00042 const FrameBufferProperties &fb_prop,
00043 const WindowProperties &win_prop,
00044 int flags,
00045 GraphicsStateGuardian *gsg,
00046 GraphicsOutput *host):
00047 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
00048 {
00049
00050 _cube_map_index = -1;
00051 _saved_color_buffer = NULL;
00052 _saved_depth_buffer = NULL;
00053 _color_backing_store = NULL;
00054 _depth_backing_store = NULL;
00055
00056
00057
00058
00059 _screenshot_buffer_type = _draw_buffer_type;
00060
00061 _this = 0;
00062
00063 if (_gsg) {
00064
00065 DXGraphicsStateGuardian8 *dxgsg;
00066
00067 dxgsg = DCAST (DXGraphicsStateGuardian8, _gsg);
00068 _this = new (wdxGraphicsBuffer8 *);
00069 *_this = this;
00070 dxgsg -> _graphics_buffer_list.push_back(_this);
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079 wdxGraphicsBuffer8::
00080 ~wdxGraphicsBuffer8() {
00081 this -> close_buffer ( );
00082
00083 if (_gsg) {
00084
00085 DXGraphicsStateGuardian8 *dxgsg;
00086
00087 dxgsg = DCAST (DXGraphicsStateGuardian8, _gsg);
00088 if (_this) {
00089 dxgsg -> _graphics_buffer_list.remove(_this);
00090 }
00091 _this = 0;
00092 _gsg.clear();
00093 _gsg = 0;
00094 }
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 bool wdxGraphicsBuffer8::
00107 begin_frame(FrameMode mode, Thread *current_thread) {
00108
00109 begin_frame_spam(mode);
00110 if (_gsg == (GraphicsStateGuardian *)NULL) {
00111 return false;
00112 }
00113 if (_dxgsg -> _d3d_device == 0) {
00114 return false;
00115 }
00116
00117 if (mode == FM_render) {
00118 if (!save_bitplanes()) {
00119 return false;
00120 }
00121 if (!rebuild_bitplanes()) {
00122 restore_bitplanes();
00123 return false;
00124 }
00125 clear_cube_map_selection();
00126 }
00127
00128 _gsg->set_current_properties(&get_fb_properties());
00129 return _gsg->begin_frame(current_thread);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 void wdxGraphicsBuffer8::
00140 end_frame(FrameMode mode, Thread *current_thread) {
00141
00142 end_frame_spam(mode);
00143 nassertv(_gsg != (GraphicsStateGuardian *)NULL);
00144
00145 if (mode == FM_render) {
00146 copy_to_textures();
00147 }
00148
00149 _gsg->end_frame(current_thread);
00150
00151 if (mode == FM_render) {
00152 trigger_flip();
00153 clear_cube_map_selection();
00154 restore_bitplanes();
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 bool wdxGraphicsBuffer8::
00165 save_bitplanes() {
00166 HRESULT hr;
00167
00168 hr = _dxgsg -> _d3d_device -> GetRenderTarget (&_saved_color_buffer);
00169 if (!SUCCEEDED (hr)) {
00170 dxgsg8_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
00171 return false;
00172 }
00173 hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer);
00174 if (!SUCCEEDED (hr)) {
00175 dxgsg8_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
00176 return false;
00177 }
00178 return true;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 void wdxGraphicsBuffer8::
00188 restore_bitplanes() {
00189 DXGraphicsStateGuardian8 *dxgsg;
00190 DCAST_INTO_V(dxgsg, _gsg);
00191
00192 HRESULT hr;
00193
00194 hr = dxgsg -> _d3d_device ->
00195 SetRenderTarget (_saved_color_buffer, _saved_depth_buffer);
00196
00197 if (!SUCCEEDED (hr)) {
00198 dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
00199 }
00200
00201 _saved_color_buffer->Release();
00202 _saved_depth_buffer->Release();
00203 _saved_color_buffer = NULL;
00204 _saved_depth_buffer = NULL;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214 bool wdxGraphicsBuffer8::
00215 rebuild_bitplanes() {
00216
00217 HRESULT hr;
00218 Texture *color_tex = 0;
00219 Texture *depth_tex = 0;
00220 DXTextureContext8 *color_ctx = 0;
00221 DXTextureContext8 *depth_ctx = 0;
00222 IDirect3DTexture8 *color_d3d_tex = 0;
00223 IDirect3DTexture8 *depth_d3d_tex = 0;
00224 IDirect3DCubeTexture8 *color_cube = 0;
00225 IDirect3DCubeTexture8 *depth_cube = 0;
00226 IDirect3DSurface8 *color_surf = 0;
00227 IDirect3DSurface8 *depth_surf = 0;
00228
00229
00230
00231 if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) {
00232 if ((_host->get_x_size() != _x_size)||
00233 (_host->get_y_size() != _y_size)) {
00234 set_size_and_recalc(_host->get_x_size(),
00235 _host->get_y_size());
00236 }
00237 }
00238 int bitplane_x = _x_size;
00239 int bitplane_y = _y_size;
00240 if (Texture::get_textures_power_2() != ATS_none) {
00241 bitplane_x = Texture::up_to_power_2(bitplane_x);
00242 bitplane_y = Texture::up_to_power_2(bitplane_y);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 int color_tex_index = -1;
00252 int depth_tex_index = -1;
00253 for (int i=0; i<count_textures(); i++) {
00254 if (get_rtm_mode(i) == RTM_bind_or_copy) {
00255 if ((get_texture(i)->get_format() != Texture::F_depth_stencil)&&
00256 (get_texture(i)->get_format() != Texture::F_depth_component)&&
00257 (color_tex_index < 0)) {
00258 color_tex_index = i;
00259 }
00260 }
00261 }
00262
00263
00264 if (color_tex_index < 0) {
00265
00266 if ((_color_backing_store)&&
00267 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
00268 _color_backing_store->Release();
00269 _color_backing_store = NULL;
00270 }
00271 if (!_color_backing_store) {
00272 hr = _dxgsg -> _d3d_device ->
00273 CreateImageSurface(bitplane_x, bitplane_y, _saved_color_desc.Format, &_color_backing_store);
00274 if (!SUCCEEDED(hr)) {
00275 dxgsg8_cat.error ( ) << "CreateImageSurface " << D3DERRORSTRING(hr) FL;
00276 }
00277 }
00278 color_surf = _color_backing_store;
00279 } else {
00280
00281 if (_color_backing_store) {
00282 _color_backing_store->Release();
00283 _color_backing_store = NULL;
00284 }
00285 color_tex = get_texture(color_tex_index);
00286 color_tex->set_x_size(bitplane_x);
00287 color_tex->set_y_size(bitplane_y);
00288 color_tex->set_format(Texture::F_rgba);
00289 color_ctx =
00290 DCAST(DXTextureContext8,
00291 color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
00292 if (color_ctx) {
00293 if (!color_ctx->create_texture(*_dxgsg->_screen)) {
00294 dxgsg8_cat.error()
00295 << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
00296 return false;
00297 }
00298 if (color_tex->get_texture_type() == Texture::TT_2d_texture) {
00299 color_d3d_tex = color_ctx->_d3d_2d_texture;
00300 nassertr(color_d3d_tex != 0, false);
00301 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
00302 if (!SUCCEEDED(hr)) {
00303 dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
00304 }
00305 } else {
00306 color_cube = color_ctx->_d3d_cube_texture;
00307 nassertr(color_cube != 0, false);
00308 if (_cube_map_index >= 0 && _cube_map_index < 6) {
00309 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
00310 if (!SUCCEEDED(hr)) {
00311 dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
00312 }
00313 }
00314 }
00315 }
00316 }
00317
00318 if (depth_tex_index < 0) {
00319
00320 if ((_depth_backing_store)&&
00321 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
00322 _depth_backing_store->Release();
00323 _depth_backing_store = NULL;
00324 }
00325 if (!_depth_backing_store) {
00326 hr = _dxgsg -> _d3d_device ->
00327 CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
00328 _saved_depth_desc.MultiSampleType, &_depth_backing_store);
00329 if (!SUCCEEDED(hr)) {
00330 dxgsg8_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
00331 }
00332 }
00333 depth_surf = _depth_backing_store;
00334 } else {
00335
00336 if (_depth_backing_store) {
00337 _depth_backing_store->Release();
00338 _depth_backing_store = NULL;
00339 }
00340 depth_tex = get_texture(depth_tex_index);
00341 depth_tex->set_x_size(bitplane_x);
00342 depth_tex->set_y_size(bitplane_y);
00343 depth_tex->set_format(Texture::F_depth_stencil);
00344 depth_ctx =
00345 DCAST(DXTextureContext8,
00346 depth_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
00347 if (depth_ctx) {
00348 if (!depth_ctx->create_texture(*_dxgsg->_screen)) {
00349 dxgsg8_cat.error()
00350 << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
00351 return false;
00352 }
00353
00354 if (depth_tex->get_texture_type() == Texture::TT_2d_texture) {
00355 depth_d3d_tex = depth_ctx->_d3d_2d_texture;
00356 nassertr(depth_d3d_tex != 0, false);
00357 hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf);
00358 if (!SUCCEEDED(hr)) {
00359 dxgsg8_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
00360 }
00361 } else {
00362 depth_cube = depth_ctx->_d3d_cube_texture;
00363 nassertr(depth_cube != 0, false);
00364 hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf);
00365 if (!SUCCEEDED(hr)) {
00366 dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
00367 }
00368 }
00369 }
00370 }
00371
00372 _backing_sizex = bitplane_x;
00373 _backing_sizey = bitplane_y;
00374
00375
00376
00377 if (color_surf && depth_surf) {
00378 hr = _dxgsg -> _d3d_device -> SetRenderTarget (color_surf, depth_surf);
00379 if (!SUCCEEDED (hr)) {
00380 dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
00381 }
00382 }
00383
00384
00385
00386
00387 if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
00388 color_surf->Release();
00389 }
00390 if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
00391 depth_surf->Release();
00392 }
00393 return true;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 void wdxGraphicsBuffer8::
00406 select_cube_map(int cube_map_index) {
00407 _cube_map_index = cube_map_index;
00408
00409 HRESULT hr;
00410 Texture *color_tex = 0;
00411 DXTextureContext8 *color_ctx = 0;
00412 IDirect3DCubeTexture8 *color_cube = 0;
00413 IDirect3DSurface8 *color_surf = 0;
00414 int color_tex_index = -1;
00415
00416 for (int i=0; i<count_textures(); i++) {
00417 if (get_rtm_mode(i) == RTM_bind_or_copy) {
00418 if ((get_texture(i)->get_format() != Texture::F_depth_stencil)&&
00419 (get_texture(i)->get_format() != Texture::F_depth_component)&&
00420 (color_tex_index < 0)) {
00421 color_tex_index = i;
00422 }
00423 }
00424 }
00425
00426 color_tex = get_texture(color_tex_index);
00427 if (color_tex) {
00428 color_ctx =
00429 DCAST(DXTextureContext8,
00430 color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
00431 if (!color_ctx->create_texture(*_dxgsg->_screen)) {
00432 dxgsg8_cat.error()
00433 << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
00434 return;
00435 }
00436
00437 color_cube = color_ctx->_d3d_cube_texture;
00438
00439 if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) {
00440 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
00441 if (!SUCCEEDED(hr)) {
00442 dxgsg8_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
00443 }
00444
00445 hr = _dxgsg -> _d3d_device -> SetRenderTarget (color_surf, 0);
00446 if (!SUCCEEDED (hr)) {
00447 dxgsg8_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
00448 }
00449 else {
00450 color_surf->Release();
00451 }
00452 }
00453 }
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 void wdxGraphicsBuffer8::
00467 process_events() {
00468 GraphicsBuffer::process_events();
00469
00470 MSG msg;
00471
00472
00473
00474
00475 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
00476 process_1_event();
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486 void wdxGraphicsBuffer8::
00487 close_buffer() {
00488
00489 if (_gsg != (GraphicsStateGuardian *)NULL) {
00490 _gsg.clear();
00491 }
00492
00493 if (_color_backing_store) {
00494 _color_backing_store->Release();
00495 _color_backing_store = NULL;
00496 }
00497 if (_depth_backing_store) {
00498 _depth_backing_store->Release();
00499 _depth_backing_store = NULL;
00500 }
00501
00502 _cube_map_index = -1;
00503 _is_valid = false;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513 bool wdxGraphicsBuffer8::
00514 open_buffer() {
00515
00516
00517 if (_gsg == 0) {
00518
00519
00520
00521
00522 return false;
00523 }
00524
00525 DCAST_INTO_R(_dxgsg, _gsg, false);
00526
00527 if (!save_bitplanes()) {
00528 return false;
00529 }
00530
00531 HRESULT hr;
00532 hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
00533 if (!SUCCEEDED (hr)) {
00534 dxgsg8_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
00535 return false;
00536 }
00537 hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
00538 if (!SUCCEEDED (hr)) {
00539 dxgsg8_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
00540 return false;
00541 }
00542 _fb_properties = _dxgsg->
00543 calc_fb_properties(_saved_color_desc.Format,
00544 _saved_depth_desc.Format,
00545 _saved_depth_desc.MultiSampleType);
00546 _fb_properties.set_force_hardware(1);
00547
00548 if (!rebuild_bitplanes()) {
00549 restore_bitplanes();
00550 return false;
00551 }
00552
00553 restore_bitplanes();
00554 return true;
00555 }
00556
00557
00558
00559
00560
00561
00562 void wdxGraphicsBuffer8::
00563 process_1_event() {
00564 MSG msg;
00565
00566 if (!GetMessage(&msg, NULL, 0, 0)) {
00567
00568
00569 exit(msg.wParam);
00570 }
00571
00572
00573 TranslateMessage(&msg);
00574
00575 DispatchMessage(&msg);
00576 }