add ScissorAttrib

This commit is contained in:
David Rose 2008-08-01 18:15:23 +00:00
parent dc064dfa41
commit 89adb4d176
2 changed files with 92 additions and 27 deletions

View File

@ -118,6 +118,8 @@ DXGraphicsStateGuardian8(GraphicsPipe *pipe) :
Geom::GR_triangle_strip | Geom::GR_triangle_fan | Geom::GR_triangle_strip | Geom::GR_triangle_fan |
Geom::GR_flat_first_vertex; Geom::GR_flat_first_vertex;
_scissor_mat = TransformState::make_identity();
get_gamma_table(); get_gamma_table();
atexit (atexit_function); atexit (atexit_function);
} }
@ -578,28 +580,8 @@ prepare_display_region(DisplayRegionPipelineReader *dr,
// Create the viewport // Create the viewport
D3DVIEWPORT8 vp = { l, u, w, h, 0.0f, 1.0f }; D3DVIEWPORT8 vp = { l, u, w, h, 0.0f, 1.0f };
HRESULT hr = _d3d_device->SetViewport(&vp); _current_viewport = vp;
if (FAILED(hr)) { set_scissor(0.0f, 1.0f, 0.0f, 1.0f);
dxgsg8_cat.error()
<< "_screen->_swap_chain = " << _screen->_swap_chain << " _swap_chain = " << _swap_chain << "\n";
dxgsg8_cat.error()
<< "SetViewport(" << l << ", " << u << ", " << w << ", " << h
<< ") failed" << D3DERRORSTRING(hr);
D3DVIEWPORT8 vp_old;
_d3d_device->GetViewport(&vp_old);
dxgsg8_cat.error()
<< "GetViewport(" << vp_old.X << ", " << vp_old.Y << ", " << vp_old.Width << ", "
<< vp_old.Height << ") returned: Trying to set that vp---->\n";
hr = _d3d_device->SetViewport(&vp_old);
if (FAILED(hr)) {
dxgsg8_cat.error() << "Failed again\n";
throw_event("panda3d-render-error");
nassertv(false);
}
}
// Note: for DX9, also change scissor clipping state here
if (_screen->_can_direct_disable_color_writes) { if (_screen->_can_direct_disable_color_writes) {
_d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, _color_write_mask); _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, _color_write_mask);
@ -664,9 +646,10 @@ calc_projection_mat(const Lens *lens) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8:: bool DXGraphicsStateGuardian8::
prepare_lens() { prepare_lens() {
CPT(TransformState) scissor_proj_mat = _scissor_mat->compose(_projection_mat);
HRESULT hr = HRESULT hr =
_d3d_device->SetTransform(D3DTS_PROJECTION, _d3d_device->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)_projection_mat->get_mat().get_data()); (D3DMATRIX*)scissor_proj_mat->get_mat().get_data());
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
@ -2242,10 +2225,6 @@ set_state_and_transform(const RenderState *target,
target->store_into_slots(&_target); target->store_into_slots(&_target);
_state_rs = 0; _state_rs = 0;
// There might be some physical limits to the actual target
// attributes we issue. Impose them now.
_target._texture = _target._texture->filter_to_max(_max_texture_stages);
if (_target._alpha_test != _state._alpha_test) { if (_target._alpha_test != _state._alpha_test) {
do_issue_alpha_test(); do_issue_alpha_test();
_state._alpha_test = _target._alpha_test; _state._alpha_test = _target._alpha_test;
@ -2331,6 +2310,15 @@ set_state_and_transform(const RenderState *target,
if (_target._texture != _state._texture || if (_target._texture != _state._texture ||
_target._tex_gen != _state._tex_gen) { _target._tex_gen != _state._tex_gen) {
determine_effective_texture(); determine_effective_texture();
// For some mysterious and disturbing reason, making this call
// here--which should have no effect--actually prevents the DX
// context from going awry. If this call is omitted, the DX
// context goes foobar when switching states and refuses to draw
// anything at all. I strongly suspect memory corruption
// somewhere, but can't locate it.
_target._texture->filter_to_max(_max_texture_stages);
do_issue_texture(); do_issue_texture();
_state._texture = _target._texture; _state._texture = _target._texture;
_state._tex_gen = _target._tex_gen; _state._tex_gen = _target._tex_gen;
@ -2351,6 +2339,11 @@ set_state_and_transform(const RenderState *target,
_state._stencil = _target._stencil; _state._stencil = _target._stencil;
} }
if (_target._scissor != _state._scissor) {
do_issue_scissor();
_state._scissor = _target._scissor;
}
_state_rs = _target_rs; _state_rs = _target_rs;
} }
@ -3725,6 +3718,8 @@ create_swap_chain(DXScreenData *new_context) {
wdxdisplay8_cat.debug() << "Swapchain creation failed :"<<D3DERRORSTRING(hr)<<"\n"; wdxdisplay8_cat.debug() << "Swapchain creation failed :"<<D3DERRORSTRING(hr)<<"\n";
return false; return false;
} }
wdxdisplay8_cat.debug()
<< "Created swap chain " << new_context->_swap_chain << "\n";
return true; return true;
} }
@ -3736,6 +3731,8 @@ create_swap_chain(DXScreenData *new_context) {
bool DXGraphicsStateGuardian8:: bool DXGraphicsStateGuardian8::
release_swap_chain(DXScreenData *new_context) { release_swap_chain(DXScreenData *new_context) {
HRESULT hr; HRESULT hr;
wdxdisplay8_cat.debug()
<< "Releasing swap chain " << new_context->_swap_chain << "\n";
if (new_context->_swap_chain) { if (new_context->_swap_chain) {
hr = new_context->_swap_chain->Release(); hr = new_context->_swap_chain->Release();
if (FAILED(hr)) { if (FAILED(hr)) {
@ -4202,6 +4199,68 @@ get_d3d_device() {
return _d3d_device; return _d3d_device;
} }
////////////////////////////////////////////////////////////////////
// Function: dxGraphicsStateGuardian8::do_issue_scissor
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
do_issue_scissor() {
const LVecBase4f &frame = _target._scissor->get_frame();
set_scissor(frame[0], frame[1], frame[2], frame[3]);
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::set_scissor
// Access: Private
// Description: Sets up the scissor region, as a set of coordinates
// relative to the current viewport.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
set_scissor(float left, float right, float bottom, float top) {
// DirectX8 doesn't have an explicit scissor control, independent of
// the viewport, so we have to do it by hand, by moving the viewport
// smaller but adjusting the projection matrix to compensate.
// First, constrain the viewport to the scissor region.
D3DVIEWPORT8 vp;
vp.Width = _current_viewport.Width * (right - left);
vp.X = _current_viewport.X + _current_viewport.Width * left;
vp.Height = _current_viewport.Height * (top - bottom);
vp.Y = _current_viewport.Y + _current_viewport.Height * (1.0f - top);
HRESULT hr = _d3d_device->SetViewport(&vp);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "_screen->_swap_chain = " << _screen->_swap_chain << " _swap_chain = " << _swap_chain << "\n";
dxgsg8_cat.error()
<< "SetViewport(" << vp.X << ", " << vp.Y << ", " << vp.Width << ", " << vp.Height
<< ") failed" << D3DERRORSTRING(hr);
D3DVIEWPORT8 vp_old;
_d3d_device->GetViewport(&vp_old);
dxgsg8_cat.error()
<< "GetViewport(" << vp_old.X << ", " << vp_old.Y << ", " << vp_old.Width << ", "
<< vp_old.Height << ") returned: Trying to set that vp---->\n";
hr = _d3d_device->SetViewport(&vp_old);
if (FAILED(hr)) {
dxgsg8_cat.error() << "Failed again\n";
throw_event("panda3d-render-error");
nassertv(false);
}
}
// Now, compute _scissor_mat, which we use to compensate the
// projection matrix.
float xsize = right - left;
float ysize = top - bottom;
float xcenter = (left + right) - 1.0f;
float ycenter = (bottom + top) - 1.0f;
_scissor_mat = TransformState::make_scale(LVecBase3f(1.0f / xsize, 1.0f / ysize, 1.0f))->compose(TransformState::make_pos(LPoint3f(-xcenter, -ycenter, 0.0f)));
prepare_lens();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: dxGraphicsStateGuardian8::calc_fb_properties // Function: dxGraphicsStateGuardian8::calc_fb_properties
// Access: Public // Access: Public

View File

@ -140,6 +140,9 @@ protected:
void do_issue_texture(); void do_issue_texture();
void do_issue_blending(); void do_issue_blending();
void do_issue_stencil(); void do_issue_stencil();
void do_issue_scissor();
void set_scissor(float left, float right, float bottom, float top);
virtual void enable_lighting(bool enable); virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color); virtual void set_ambient_light(const Colorf &color);
@ -233,6 +236,8 @@ protected:
}; };
DxgsgFogType _do_fog_type; DxgsgFogType _do_fog_type;
D3DVIEWPORT8 _current_viewport;
DWORD _clip_plane_bits; DWORD _clip_plane_bits;
CullFaceAttrib::Mode _cull_face_mode; CullFaceAttrib::Mode _cull_face_mode;
RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid
@ -246,6 +251,7 @@ protected:
bool _tex_stats_retrieval_impossible; bool _tex_stats_retrieval_impossible;
static D3DMATRIX _d3d_ident_mat; static D3DMATRIX _d3d_ident_mat;
CPT(TransformState) _scissor_mat;
static unsigned char *_temp_buffer; static unsigned char *_temp_buffer;
static unsigned char *_safe_buffer_start; static unsigned char *_safe_buffer_start;