make multipass work (sort of) on dx8
This commit is contained in:
parent
0732fe4122
commit
0e084fe310
|
|
@ -566,8 +566,7 @@ end_frame() {
|
|||
nassertv(has_texture());
|
||||
DisplayRegion dr(this, _x_size, _y_size);
|
||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
||||
TextureContext *tc = get_texture()->prepare_now(_gsg->get_prepared_objects(), _gsg);
|
||||
_gsg->copy_texture(tc, &dr, buffer);
|
||||
_gsg->copy_texture(get_texture(), &dr, buffer);
|
||||
}
|
||||
|
||||
// If we're not single-buffered, we're now ready to flip.
|
||||
|
|
|
|||
|
|
@ -677,6 +677,10 @@ make_mesh_geom(Geom *geom, Lens *lens, LMatrix4f &rel_mat) {
|
|||
// dimensions so the Z coordinate remains meaningful.
|
||||
LPoint3f film(0.0f, 0.0f, 0.0f);
|
||||
lens->project(vert * rel_mat, film);
|
||||
|
||||
// This might be necessary to compensate for DX's weird near plane
|
||||
// definition. Investigate further later.
|
||||
//film[2] = ((film[2] + 1.0f) / 2.0f);
|
||||
|
||||
new_coords.push_back(film);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3490,81 +3490,19 @@ release_texture(TextureContext *tc) {
|
|||
delete gtc;
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
void DXGraphicsStateGuardian7::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
||||
dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!";
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr) {
|
||||
dxgsg7_cat.error() << "DX copy_texture unimplemented!!!";
|
||||
}
|
||||
|
||||
#else
|
||||
static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
|
||||
4096, 0};
|
||||
|
||||
// This function returns the smallest power of two greater than or
|
||||
// equal to x.
|
||||
static int binary_log_cap(const int x) {
|
||||
int i = 0;
|
||||
for (; (x > logs[i]) && (logs[i] != 0); ++i);
|
||||
if (logs[i] == 0)
|
||||
return 4096;
|
||||
return logs[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian7::copy_texture
|
||||
// Access: Public, Virtual
|
||||
// Description: Copy the pixel region indicated by the display
|
||||
// region from the framebuffer into texture memory
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian7::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
||||
|
||||
nassertv(tc != NULL && dr != NULL);
|
||||
|
||||
Texture *tex = tc->_texture;
|
||||
|
||||
// Determine the size of the grab from the given display region
|
||||
// If the requested region is not a power of two, grab a region that is
|
||||
// a power of two that contains the requested region
|
||||
int xo, yo, req_w, req_h;
|
||||
dr->get_region_pixels(xo, yo, req_w, req_h);
|
||||
int w = binary_log_cap(req_w);
|
||||
int h = binary_log_cap(req_h);
|
||||
if (w != req_w || h != req_h) {
|
||||
tex->_requested_w = req_w;
|
||||
tex->_requested_h = req_h;
|
||||
tex->_has_requested_size = true;
|
||||
}
|
||||
|
||||
PixelBuffer *pb = tex->_pbuffer;
|
||||
|
||||
pb->set_xorg(xo);
|
||||
pb->set_yorg(yo);
|
||||
pb->set_xsize(w);
|
||||
pb->set_ysize(h);
|
||||
|
||||
|
||||
bind_texture(tc);
|
||||
glCopyTexImage2D( GL_TEXTURE_2D, tex->get_level(),
|
||||
get_internal_image_format(pb->get_format()),
|
||||
pb->get_xorg(), pb->get_yorg(),
|
||||
pb->get_xsize(), pb->get_ysize(), pb->get_border() );
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian7::copy_texture
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian7::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!";
|
||||
return;
|
||||
|
||||
set_read_buffer(rb);
|
||||
copy_texture(tc, dr);
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
dxgsg7_cat.error() << "DX copy_texture unimplemented!!!";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ public:
|
|||
virtual void apply_texture(TextureContext *tc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr);
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "graphicsChannel.h"
|
||||
#include "lens.h"
|
||||
#include "perspectiveLens.h"
|
||||
#include "orthographicLens.h"
|
||||
#include "ambientLight.h"
|
||||
#include "directionalLight.h"
|
||||
#include "pointLight.h"
|
||||
|
|
@ -1040,17 +1041,17 @@ prepare_lens() {
|
|||
LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
|
||||
projection_mat;
|
||||
|
||||
float vfov = _current_lens->get_vfov();
|
||||
float nearf = _current_lens->get_near();
|
||||
float farf = _current_lens->get_far();
|
||||
|
||||
//dxgsg8_cat.debug() << new_projection_mat << endl;
|
||||
|
||||
HRESULT hr;
|
||||
if (_current_lens->get_type().get_name() == "PerspectiveLens") {
|
||||
#if 0
|
||||
if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) {
|
||||
/*
|
||||
const LMatrix4f mat_temp;
|
||||
|
||||
float vfov = _current_lens->get_vfov();
|
||||
float hfov = _current_lens->get_hfov();
|
||||
float ar = _current_lens->get_aspect_ratio();
|
||||
float nearf = _current_lens->get_near();
|
||||
|
|
@ -1063,25 +1064,32 @@ prepare_lens() {
|
|||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)mat_temp.get_data());
|
||||
dxgsg8_cat.debug() << mat_temp << endl;
|
||||
#endif
|
||||
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_33 = farf / (farf-nearf);
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf);
|
||||
*/
|
||||
|
||||
new_projection_mat(2, 2) = farf / (farf-nearf);
|
||||
new_projection_mat(3, 2) = -nearf * farf / (farf - nearf);
|
||||
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg8_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg8_cat.debug() << "using perspective projection" << endl;
|
||||
}
|
||||
else {
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_33 = 1/(farf-nearf);
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf);
|
||||
|
||||
} else if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) {
|
||||
new_projection_mat(2, 2) = 1 / (farf - nearf);
|
||||
new_projection_mat(3, 2) = -nearf / (farf - nearf);
|
||||
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg8_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg8_cat.debug() << "using ortho projection" << endl;
|
||||
|
||||
} else {
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg8_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg8_cat.debug() << "using matrix projection" << endl;
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
|
@ -3021,17 +3029,19 @@ prepare_texture(Texture *tex) {
|
|||
void DXGraphicsStateGuardian8::
|
||||
apply_texture(TextureContext *tc) {
|
||||
if (tc==NULL) {
|
||||
return; // use enable_texturing to disable/enable
|
||||
// The texture wasn't bound properly or something, so ensure
|
||||
// texturing is disabled and just return.
|
||||
enable_texturing(false);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
add_to_texture_record(tc);
|
||||
#endif
|
||||
|
||||
// bind_texture(tc);
|
||||
|
||||
// specify_texture(tc->_texture);
|
||||
// Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well
|
||||
// so DX TSS renderstate matches dxgsg state
|
||||
// Note: if this code changes, make sure to change initialization
|
||||
// SetTSS code in dx_init as well so DX TSS renderstate matches
|
||||
// dxgsg state
|
||||
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
|
||||
|
|
@ -3057,7 +3067,6 @@ apply_texture(TextureContext *tc) {
|
|||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg8_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
|
||||
release_texture(dtc);
|
||||
enable_texturing(false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3065,7 +3074,8 @@ apply_texture(TextureContext *tc) {
|
|||
dtc->clear_dirty_flags();
|
||||
} else {
|
||||
if(_pCurTexContext == dtc) {
|
||||
return; // tex already set (and possible problem in state-sorting?)
|
||||
enable_texturing(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3171,6 +3181,7 @@ apply_texture(TextureContext *tc) {
|
|||
#endif
|
||||
|
||||
_pCurTexContext = dtc; // enable_texturing needs this
|
||||
enable_texturing(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3189,30 +3200,34 @@ release_texture(TextureContext *tc) {
|
|||
// copies current display region in framebuffer to the texture
|
||||
// usually its more efficient to do SetRenderTgt
|
||||
void DXGraphicsStateGuardian8::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr) {
|
||||
|
||||
HRESULT hr;
|
||||
int xo, yo, w, h;
|
||||
dr->get_region_pixels(xo, yo, w, h);
|
||||
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
PixelBuffer *pb = dtc->_tex->_pbuffer;
|
||||
PixelBuffer *pb = tex->_pbuffer;
|
||||
pb->set_size(0,0,w-xo,h-yo);
|
||||
|
||||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||
if (tc == (TextureContext *)NULL) {
|
||||
return;
|
||||
}
|
||||
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
|
||||
|
||||
IDirect3DSurface8 *pTexSurfaceLev0,*pCurRenderTarget;
|
||||
hr = dtc->_pD3DTexture8->GetSurfaceLevel(0,&pTexSurfaceLev0);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = _pD3DDevice->GetRenderTarget(&pCurRenderTarget);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RECT SrcRect;
|
||||
|
||||
SrcRect.left = xo;
|
||||
|
|
@ -3224,7 +3239,7 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
hr = _pD3DDevice->CopyRects(pCurRenderTarget,&SrcRect,1,pTexSurfaceLev0,NULL);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg8_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pCurRenderTarget);
|
||||
|
|
@ -3238,9 +3253,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_texture(tc, dr);
|
||||
copy_texture(tex, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3561,20 +3576,15 @@ void DXGraphicsStateGuardian8::SetTextureBlendMode(TextureApplyAttrib::Mode TexB
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DXGraphicsStateGuardian8::
|
||||
enable_texturing(bool val) {
|
||||
// if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes
|
||||
// return;
|
||||
// }
|
||||
_texturing_enabled = val;
|
||||
|
||||
if (!val) {
|
||||
_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
|
||||
|
||||
_texturing_enabled = val;
|
||||
|
||||
// assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false
|
||||
// I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs
|
||||
|
||||
if (val == false) {
|
||||
_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
|
||||
} else {
|
||||
SetTextureBlendMode(_CurTexBlendMode,true);
|
||||
}
|
||||
} else {
|
||||
nassertv(_pCurTexContext!=NULL);
|
||||
SetTextureBlendMode(_CurTexBlendMode,true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3643,7 +3653,6 @@ issue_texture(const TextureAttrib *attrib) {
|
|||
if (attrib->is_off()) {
|
||||
enable_texturing(false);
|
||||
} else {
|
||||
enable_texturing(true);
|
||||
Texture *tex = attrib->get_texture();
|
||||
nassertv(tex != (Texture *)NULL);
|
||||
|
||||
|
|
@ -4494,7 +4503,7 @@ save_frame_buffer(const RenderBuffer &buffer,
|
|||
if (buffer._buffer_type & RenderBuffer::T_back) {
|
||||
// Save the color buffer.
|
||||
sfb->_back_rgba = new Texture;
|
||||
copy_texture(sfb->_back_rgba->prepare(this), dr, buffer);
|
||||
copy_texture(sfb->_back_rgba, dr, buffer);
|
||||
}
|
||||
|
||||
return sfb;
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ public:
|
|||
virtual void apply_texture(TextureContext *tc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr);
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
|
||||
|
|
|
|||
|
|
@ -1429,17 +1429,9 @@ IDirect3DTexture8 *DXTextureContext8::CreateTexture(DXScreenData &scrn) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Note: user may want to create an empty "texture" that will be written to by rendering and copy operations.
|
||||
// this will never have a backing store of main memory in panda fmt, and on disk in a file.
|
||||
// so for this case, you dont want to call FillDDSurf.
|
||||
// need a better way for user to indicate this usage than lack of ram_image, because it conflicts
|
||||
// with the multi-open case mentioned below
|
||||
|
||||
if(_texture->has_ram_image()) {
|
||||
hr = FillDDSurfTexturePixels();
|
||||
if(FAILED(hr)) {
|
||||
goto error_exit;
|
||||
}
|
||||
hr = FillDDSurfTexturePixels();
|
||||
if(FAILED(hr)) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
// PRINT_REFCNT(dxgsg8,scrn.pD3D8);
|
||||
|
|
@ -1458,27 +1450,12 @@ FillDDSurfTexturePixels(void) {
|
|||
HRESULT hr=E_FAIL;
|
||||
assert(IS_VALID_PTR(_texture));
|
||||
|
||||
// It is a mistake to insist that has_ram_image() be true before
|
||||
// we try to load the texture. This function only indicates
|
||||
// whether the texture image is already present in main ram or
|
||||
// not; it has nothing to do with whether get_ram_image() will
|
||||
// fail. When there is only one GSG in the world, has_ram_image()
|
||||
// will generally be true whenever the texture has not been loaded
|
||||
// before, but when there are multiple GSG's (for instance, if we
|
||||
// close and reopen the main window), then has_ram_image() is
|
||||
// largely irrelevant to the GSG.
|
||||
/*
|
||||
if(!_texture->has_ram_image()) {
|
||||
dxgsg8_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n";
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
PixelBuffer *pbuf = _texture->get_ram_image();
|
||||
if (pbuf == (PixelBuffer *)NULL) {
|
||||
dxgsg8_cat.fatal() << "CreateTexture: get_ram_image() failed\n";
|
||||
// The texture doesn't have an image to load.
|
||||
return E_FAIL;
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
// operations or something.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
assert(IS_VALID_PTR(_pD3DTexture8));
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "graphicsChannel.h"
|
||||
#include "lens.h"
|
||||
#include "perspectiveLens.h"
|
||||
#include "orthographicLens.h"
|
||||
#include "ambientLight.h"
|
||||
#include "directionalLight.h"
|
||||
#include "pointLight.h"
|
||||
|
|
@ -1055,17 +1056,17 @@ prepare_lens() {
|
|||
LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) *
|
||||
projection_mat;
|
||||
|
||||
float vfov = _current_lens->get_vfov();
|
||||
float nearf = _current_lens->get_near();
|
||||
float farf = _current_lens->get_far();
|
||||
|
||||
//dxgsg9_cat.debug() << new_projection_mat << endl;
|
||||
|
||||
HRESULT hr;
|
||||
if (_current_lens->get_type().get_name() == "PerspectiveLens") {
|
||||
#if 0
|
||||
if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) {
|
||||
/*
|
||||
const LMatrix4f mat_temp;
|
||||
|
||||
float vfov = _current_lens->get_vfov();
|
||||
float hfov = _current_lens->get_hfov();
|
||||
float ar = _current_lens->get_aspect_ratio();
|
||||
float nearf = _current_lens->get_near();
|
||||
|
|
@ -1078,25 +1079,32 @@ prepare_lens() {
|
|||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)mat_temp.get_data());
|
||||
dxgsg9_cat.debug() << mat_temp << endl;
|
||||
#endif
|
||||
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_33 = farf / (farf-nearf);
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf);
|
||||
*/
|
||||
|
||||
new_projection_mat(2, 2) = farf / (farf-nearf);
|
||||
new_projection_mat(3, 2) = -nearf * farf / (farf - nearf);
|
||||
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg9_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg9_cat.debug() << "using perspective projection" << endl;
|
||||
}
|
||||
else {
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_33 = 1/(farf-nearf);
|
||||
((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf);
|
||||
|
||||
} else if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) {
|
||||
new_projection_mat(2, 2) = 1 / (farf - nearf);
|
||||
new_projection_mat(3, 2) = -nearf / (farf - nearf);
|
||||
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg9_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg9_cat.debug() << "using ortho projection" << endl;
|
||||
|
||||
} else {
|
||||
hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)new_projection_mat.get_data());
|
||||
//dxgsg9_cat.debug() << new_projection_mat << endl;
|
||||
//dxgsg9_cat.debug() << "using matrix projection" << endl;
|
||||
}
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
|
@ -3037,17 +3045,19 @@ prepare_texture(Texture *tex) {
|
|||
void DXGraphicsStateGuardian9::
|
||||
apply_texture(TextureContext *tc) {
|
||||
if (tc==NULL) {
|
||||
return; // use enable_texturing to disable/enable
|
||||
// The texture wasn't bound properly or something, so ensure
|
||||
// texturing is disabled and just return.
|
||||
enable_texturing(false);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
add_to_texture_record(tc);
|
||||
#endif
|
||||
|
||||
// bind_texture(tc);
|
||||
|
||||
// specify_texture(tc->_texture);
|
||||
// Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well
|
||||
// so DX TSS renderstate matches dxgsg state
|
||||
// Note: if this code changes, make sure to change initialization
|
||||
// SetTSS code in dx_init as well so DX TSS renderstate matches
|
||||
// dxgsg state
|
||||
|
||||
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||
|
||||
|
|
@ -3073,7 +3083,6 @@ apply_texture(TextureContext *tc) {
|
|||
// Oops, we can't re-create the texture for some reason.
|
||||
dxgsg9_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl;
|
||||
|
||||
release_texture(dtc);
|
||||
enable_texturing(false);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3081,7 +3090,8 @@ apply_texture(TextureContext *tc) {
|
|||
dtc->clear_dirty_flags();
|
||||
} else {
|
||||
if(_pCurTexContext == dtc) {
|
||||
return; // tex already set (and possible problem in state-sorting?)
|
||||
enable_texturing(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3187,6 +3197,7 @@ apply_texture(TextureContext *tc) {
|
|||
#endif
|
||||
|
||||
_pCurTexContext = dtc; // enable_texturing needs this
|
||||
enable_texturing(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3205,30 +3216,34 @@ release_texture(TextureContext *tc) {
|
|||
// copies current display region in framebuffer to the texture
|
||||
// usually its more efficient to do SetRenderTgt
|
||||
void DXGraphicsStateGuardian9::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr) {
|
||||
|
||||
HRESULT hr;
|
||||
int xo, yo, w, h;
|
||||
dr->get_region_pixels(xo, yo, w, h);
|
||||
|
||||
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||
PixelBuffer *pb = dtc->_tex->_pbuffer;
|
||||
PixelBuffer *pb = tex->_pbuffer;
|
||||
pb->set_size(0,0,w-xo,h-yo);
|
||||
|
||||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||
if (tc == (TextureContext *)NULL) {
|
||||
return;
|
||||
}
|
||||
DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc);
|
||||
|
||||
IDirect3DSurface9 *pTexSurfaceLev0,*pCurRenderTarget;
|
||||
hr = dtc->_pD3DTexture9->GetSurfaceLevel(0,&pTexSurfaceLev0);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = _pD3DDevice->GetRenderTarget(0, &pCurRenderTarget);
|
||||
if(FAILED(hr)) {
|
||||
dxgsg9_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RECT SrcRect;
|
||||
|
||||
SrcRect.left = xo;
|
||||
|
|
@ -3240,8 +3255,8 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
hr = _pD3DDevice->UpdateSurface(pCurRenderTarget,&SrcRect,pTexSurfaceLev0,NULL);
|
||||
|
||||
if(FAILED(hr)) {
|
||||
dxgsg9_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
exit(1);
|
||||
dxgsg9_cat.error() << "UpdateSurface failed in copy_texture" << D3DERRORSTRING(hr);
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pCurRenderTarget);
|
||||
|
|
@ -3255,9 +3270,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_texture(tc, dr);
|
||||
copy_texture(tex, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3578,20 +3593,15 @@ void DXGraphicsStateGuardian9::SetTextureBlendMode(TextureApplyAttrib::Mode TexB
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DXGraphicsStateGuardian9::
|
||||
enable_texturing(bool val) {
|
||||
// if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes
|
||||
// return;
|
||||
// }
|
||||
_texturing_enabled = val;
|
||||
|
||||
if (!val) {
|
||||
_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
|
||||
|
||||
_texturing_enabled = val;
|
||||
|
||||
// assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false
|
||||
// I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs
|
||||
|
||||
if (val == false) {
|
||||
_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
|
||||
} else {
|
||||
SetTextureBlendMode(_CurTexBlendMode,true);
|
||||
}
|
||||
} else {
|
||||
nassertv(_pCurTexContext!=NULL);
|
||||
SetTextureBlendMode(_CurTexBlendMode,true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3660,7 +3670,6 @@ issue_texture(const TextureAttrib *attrib) {
|
|||
if (attrib->is_off()) {
|
||||
enable_texturing(false);
|
||||
} else {
|
||||
enable_texturing(true);
|
||||
Texture *tex = attrib->get_texture();
|
||||
nassertv(tex != (Texture *)NULL);
|
||||
|
||||
|
|
@ -4511,7 +4520,7 @@ save_frame_buffer(const RenderBuffer &buffer,
|
|||
if (buffer._buffer_type & RenderBuffer::T_back) {
|
||||
// Save the color buffer.
|
||||
sfb->_back_rgba = new Texture;
|
||||
copy_texture(sfb->_back_rgba->prepare(this), dr, buffer);
|
||||
copy_texture(sfb->_back_rgba, dr, buffer);
|
||||
}
|
||||
|
||||
return sfb;
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ public:
|
|||
virtual void apply_texture(TextureContext *tc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr);
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
|
||||
|
|
|
|||
|
|
@ -1429,17 +1429,9 @@ IDirect3DTexture9 *DXTextureContext9::CreateTexture(DXScreenData &scrn) {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Note: user may want to create an empty "texture" that will be written to by rendering and copy operations.
|
||||
// this will never have a backing store of main memory in panda fmt, and on disk in a file.
|
||||
// so for this case, you dont want to call FillDDSurf.
|
||||
// need a better way for user to indicate this usage than lack of ram_image, because it conflicts
|
||||
// with the multi-open case mentioned below
|
||||
|
||||
if(_texture->has_ram_image()) {
|
||||
hr = FillDDSurfTexturePixels();
|
||||
if(FAILED(hr)) {
|
||||
goto error_exit;
|
||||
}
|
||||
hr = FillDDSurfTexturePixels();
|
||||
if(FAILED(hr)) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
// PRINT_REFCNT(dxgsg9,scrn.pD3D9);
|
||||
|
|
@ -1458,27 +1450,12 @@ FillDDSurfTexturePixels(void) {
|
|||
HRESULT hr=E_FAIL;
|
||||
assert(IS_VALID_PTR(_texture));
|
||||
|
||||
// It is a mistake to insist that has_ram_image() be true before
|
||||
// we try to load the texture. This function only indicates
|
||||
// whether the texture image is already present in main ram or
|
||||
// not; it has nothing to do with whether get_ram_image() will
|
||||
// fail. When there is only one GSG in the world, has_ram_image()
|
||||
// will generally be true whenever the texture has not been loaded
|
||||
// before, but when there are multiple GSG's (for instance, if we
|
||||
// close and reopen the main window), then has_ram_image() is
|
||||
// largely irrelevant to the GSG.
|
||||
/*
|
||||
if(!_texture->has_ram_image()) {
|
||||
dxgsg9_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n";
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
PixelBuffer *pbuf = _texture->get_ram_image();
|
||||
if (pbuf == (PixelBuffer *)NULL) {
|
||||
dxgsg9_cat.fatal() << "CreateTexture: get_ram_image() failed\n";
|
||||
// The texture doesn't have an image to load.
|
||||
return E_FAIL;
|
||||
// The texture doesn't have an image to load. That's ok; it
|
||||
// might be a texture we've rendered to by frame buffer
|
||||
// operations or something.
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
assert(IS_VALID_PTR(_pD3DTexture9));
|
||||
|
|
|
|||
|
|
@ -1907,9 +1907,8 @@ static int binary_log_cap(const int x) {
|
|||
// region from the framebuffer into texture memory
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
||||
nassertv(tc != NULL && dr != NULL);
|
||||
Texture *tex = tc->_texture;
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr) {
|
||||
nassertv(tex != NULL && dr != NULL);
|
||||
|
||||
int xo, yo, w, h;
|
||||
|
||||
|
|
@ -1937,11 +1936,13 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
PixelBuffer *pb = tex->_pbuffer;
|
||||
pb->set_size(xo,yo,w,h);
|
||||
|
||||
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(tc != (TextureContext *)NULL);
|
||||
bind_texture(tc);
|
||||
|
||||
GLP(CopyTexImage2D)(GL_TEXTURE_2D, 0,
|
||||
get_internal_image_format(pb->get_format()),
|
||||
xo, yo, w, h, pb->get_border());
|
||||
get_internal_image_format(pb->get_format()),
|
||||
xo, yo, w, h, pb->get_border());
|
||||
|
||||
// Clear the internal texture state, since we've just monkeyed with it.
|
||||
modify_state(get_untextured_state());
|
||||
|
|
@ -1953,9 +1954,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) {
|
||||
set_read_buffer(rb);
|
||||
copy_texture(tc, dr);
|
||||
copy_texture(tex, dr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -3969,8 +3970,7 @@ save_frame_buffer(const RenderBuffer &buffer,
|
|||
if (buffer._buffer_type & RenderBuffer::T_back) {
|
||||
// Save the color buffer.
|
||||
sfb->_back_rgba = new Texture;
|
||||
TextureContext *tc = sfb->_back_rgba->prepare_now(_prepared_objects, this);
|
||||
copy_texture(tc, dr, buffer);
|
||||
copy_texture(sfb->_back_rgba, dr, buffer);
|
||||
}
|
||||
|
||||
return sfb;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ public:
|
|||
GeomNodeContext *gnc);
|
||||
virtual void release_geom_node(GeomNodeContext *gnc);
|
||||
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr);
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr);
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb);
|
||||
|
|
|
|||
|
|
@ -196,10 +196,13 @@ prepare_texture_now(Texture *tex, GraphicsStateGuardianBase *gsg) {
|
|||
// all shared anyway).
|
||||
TextureContext *tc = gsg->prepare_texture(tex);
|
||||
|
||||
bool prepared = _prepared_textures.insert(tc).second;
|
||||
nassertr(prepared, tc);
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
bool prepared = _prepared_textures.insert(tc).second;
|
||||
nassertr(prepared, tc);
|
||||
|
||||
_total_texusage_pcollector.add_level(tc->estimate_texture_memory());
|
||||
}
|
||||
|
||||
_total_texusage_pcollector.add_level(tc->estimate_texture_memory());
|
||||
return tc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -502,26 +502,27 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
}
|
||||
|
||||
TextureContext *tc = prepared_objects->prepare_texture_now(this, gsg);
|
||||
_contexts[prepared_objects] = tc;
|
||||
if (tc != (TextureContext *)NULL) {
|
||||
_contexts[prepared_objects] = tc;
|
||||
|
||||
// Now that we have a new TextureContext with zero dirty flags, our
|
||||
// intersection of all dirty flags must be zero. This doesn't mean
|
||||
// that some other contexts aren't still dirty, but at least one
|
||||
// context isn't.
|
||||
_all_dirty_flags = 0;
|
||||
// Now that we have a new TextureContext with zero dirty flags, our
|
||||
// intersection of all dirty flags must be zero. This doesn't mean
|
||||
// that some other contexts aren't still dirty, but at least one
|
||||
// context isn't.
|
||||
_all_dirty_flags = 0;
|
||||
|
||||
if (!keep_texture_ram && !_keep_ram_image) {
|
||||
// Once we have prepared the texture, we can generally safely
|
||||
// remove the pixels from main RAM. The GSG is now responsible
|
||||
// for remembering what it looks like.
|
||||
if (!keep_texture_ram && !_keep_ram_image) {
|
||||
// Once we have prepared the texture, we can generally safely
|
||||
// remove the pixels from main RAM. The GSG is now responsible
|
||||
// for remembering what it looks like.
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Dumping RAM for texture " << get_name() << "\n";
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Dumping RAM for texture " << get_name() << "\n";
|
||||
}
|
||||
_pbuffer->_image.clear();
|
||||
}
|
||||
_pbuffer->_image.clear();
|
||||
}
|
||||
|
||||
return tc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ public:
|
|||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
|
||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
|
||||
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr)=0;
|
||||
virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr,
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr)=0;
|
||||
virtual void copy_texture(Texture *tex, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb)=0;
|
||||
|
||||
virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb)=0;
|
||||
|
|
|
|||
|
|
@ -130,8 +130,7 @@ end_frame() {
|
|||
|
||||
DisplayRegion dr(this, _x_size, _y_size);
|
||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());
|
||||
TextureContext *tc = get_texture()->prepare_now(_gsg->get_prepared_objects(), _gsg);
|
||||
_gsg->copy_texture(tc, &dr, buffer);
|
||||
_gsg->copy_texture(get_texture(), &dr, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue