Add render to texture support for DX8

This commit is contained in:
aignacio_sf 2005-12-14 02:01:23 +00:00
parent 8d01e31524
commit 269d0e7e83
9 changed files with 811 additions and 162 deletions

View File

@ -38,7 +38,8 @@
dxTextureContext8.cxx \
dxGeomMunger8.cxx \
dxGraphicsDevice8.cxx \
wdxGraphicsPipe8.cxx wdxGraphicsWindow8.cxx
wdxGraphicsPipe8.cxx \
wdxGraphicsWindow8.cxx \
wdxGraphicsBuffer8.cxx
#end lib_target

View File

@ -111,12 +111,15 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
// D3DRS_POINTSPRITEENABLE doesn't seem to support remapping the
// texture coordinates via a texture matrix, so we don't advertise
// GR_point_sprite_tex_matrix.
_supported_geom_rendering =
_supported_geom_rendering =
Geom::GR_point | Geom::GR_point_uniform_size |
Geom::GR_point_perspective | Geom::GR_point_sprite |
Geom::GR_indexed_other |
Geom::GR_triangle_strip | Geom::GR_triangle_fan |
Geom::GR_flat_first_vertex;
// default render to texture format
_render_to_texture_d3d_format = D3DFMT_X8R8G8B8;
}
////////////////////////////////////////////////////////////////////
@ -182,20 +185,20 @@ apply_texture(int i, TextureContext *tc) {
// If the texture image has changed, or if its use of mipmaps has
// changed, we need to re-create the image. Ignore other types of
// changes, which aren't significant for DX.
if ((dirty & (Texture::DF_image | Texture::DF_mipmap)) != 0) {
// If this is *only* because of a mipmap change, issue a
// warning--it is likely that this change is the result of an
// error or oversight.
if ((dirty & Texture::DF_image) == 0) {
dxgsg8_cat.warning()
<< "Texture " << *dtc->_texture << " has changed mipmap state.\n";
<< "Texture " << *dtc->_texture << " has changed mipmap state.\n";
}
if (!dtc->create_texture(*_screen)) {
// Oops, we can't re-create the texture for some reason.
dxgsg8_cat.error()
<< "Unable to re-create texture " << *dtc->_texture << endl;
<< "Unable to re-create texture " << *dtc->_texture << endl;
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE);
return;
}
@ -211,8 +214,8 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTextureStageState(i, D3DTSS_ADDRESSV, get_texture_wrap_mode(wrap_v));
_d3d_device->SetTextureStageState(i, D3DTSS_ADDRESSW, get_texture_wrap_mode(wrap_w));
_d3d_device->SetTextureStageState(i, D3DTSS_BORDERCOLOR,
Colorf_to_D3DCOLOR(tex->get_border_color()));
_d3d_device->SetTextureStageState(i, D3DTSS_BORDERCOLOR,
Colorf_to_D3DCOLOR(tex->get_border_color()));
uint aniso_degree = tex->get_anisotropic_degree();
Texture::FilterType ft = tex->get_magfilter();
@ -351,7 +354,7 @@ apply_vertex_buffer(VertexBufferContext *vbc) {
HRESULT hr = _d3d_device->SetVertexShader(dvbc->_fvf);
#ifndef NDEBUG
if (FAILED(hr)) {
dxgsg8_cat.error()
dxgsg8_cat.error()
<< "SetVertexShader(0x" << (void*)dvbc->_fvf
<< ") failed" << D3DERRORSTRING(hr);
}
@ -622,7 +625,7 @@ prepare_lens() {
// The projection matrix must always be left-handed Y-up internally,
// to match DirectX's convention, even if our coordinate system of
// choice is otherwise.
const LMatrix4f &convert_mat =
const LMatrix4f &convert_mat =
LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system());
// DirectX also uses a Z range of 0 to 1, whereas the Panda
@ -643,7 +646,7 @@ prepare_lens() {
_projection_mat *= invert_mat;
}
HRESULT hr =
HRESULT hr =
_d3d_device->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)_projection_mat.get_data());
return SUCCEEDED(hr);
@ -795,7 +798,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
nassertr(vbc != (VertexBufferContext *)NULL, false);
apply_vertex_buffer(vbc);
const GeomVertexAnimationSpec &animation =
const GeomVertexAnimationSpec &animation =
vertex_data->get_format()->get_animation();
if (animation.get_animation_type() == Geom::AT_hardware) {
// Set up vertex blending.
@ -928,10 +931,10 @@ draw_triangles(const GeomTriangles *primitive) {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
}
}
}
@ -966,7 +969,7 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Indexed, client arrays, one long triangle strip.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
draw_indexed_primitive_up
draw_indexed_primitive_up
(D3DPT_TRIANGLESTRIP,
min_vertex, max_vertex,
primitive->get_num_vertices() - 2,
@ -984,12 +987,12 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Indexed, client arrays, one long triangle strip.
draw_primitive_up(D3DPT_TRIANGLESTRIP,
primitive->get_num_vertices() - 2,
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_TRIANGLESTRIP,
primitive->get_num_vertices() - 2,
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
}
}
@ -1040,7 +1043,7 @@ draw_tristrips(const GeomTristrips *primitive) {
_vertices_tristrip_pcollector.add_level(ends[i] - start);
unsigned int min = mins.get_data1i();
unsigned int max = maxs.get_data1i();
draw_indexed_primitive_up
draw_indexed_primitive_up
(D3DPT_TRIANGLESTRIP,
min, max,
ends[i] - start - 2,
@ -1073,10 +1076,10 @@ draw_tristrips(const GeomTristrips *primitive) {
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_vertices_tristrip_pcollector.add_level(ends[i] - start);
draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2,
first_vertex + start,
ends[i] - start,
array_data, stride);
draw_primitive_up(D3DPT_TRIANGLESTRIP, ends[i] - start - 2,
first_vertex + start,
ends[i] - start,
array_data, stride);
start = ends[i] + 2;
}
@ -1139,7 +1142,7 @@ draw_trifans(const GeomTrifans *primitive) {
_vertices_trifan_pcollector.add_level(ends[i] - start);
unsigned int min = mins.get_data1i();
unsigned int max = maxs.get_data1i();
draw_indexed_primitive_up
draw_indexed_primitive_up
(D3DPT_TRIANGLEFAN,
min, max,
ends[i] - start - 2,
@ -1172,11 +1175,11 @@ draw_trifans(const GeomTrifans *primitive) {
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_vertices_trifan_pcollector.add_level(ends[i] - start);
draw_primitive_up(D3DPT_TRIANGLEFAN,
ends[i] - start - 2,
first_vertex,
ends[i] - start,
array_data, stride);
draw_primitive_up(D3DPT_TRIANGLEFAN,
ends[i] - start - 2,
first_vertex,
ends[i] - start,
array_data, stride);
start = ends[i];
}
}
@ -1232,10 +1235,10 @@ draw_lines(const GeomLines *primitive) {
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_LINELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
}
}
}
@ -1273,10 +1276,10 @@ draw_points(const GeomPoints *primitive) {
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_POINTLIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
}
}
@ -1327,7 +1330,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
dr->get_region_pixels_i(xo, yo, w, h);
tex->set_x_size(Texture::up_to_power_2(w));
tex->set_y_size(Texture::up_to_power_2(h));
TextureContext *tc = tex->prepare_now(get_prepared_objects(), this);
if (tc == (TextureContext *)NULL) {
return;
@ -1388,7 +1391,7 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
return;
}
}
IDirect3DSurface8 *render_target;
hr = _d3d_device->GetRenderTarget(&render_target);
if (FAILED(hr)) {
@ -1462,7 +1465,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
tex->get_format() != format ||
tex->get_texture_type() != texture_type) {
// Re-setup the texture; its properties have changed.
tex->setup_texture(texture_type, w, h, tex->get_z_size(),
tex->setup_texture(texture_type, w, h, tex->get_z_size(),
component_type, format);
}
@ -1493,12 +1496,12 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
// Since we might not be able to Lock the back buffer, we will
// need to copy it to a temporary surface of the appropriate type
// first.
hr = _d3d_device->CreateImageSurface(w, h, _screen->_display_mode.Format,
&temp_surface);
hr = _d3d_device->CreateImageSurface(w, h, _screen->_display_mode.Format,
&temp_surface);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
backbuffer->Release();
return false;
}
@ -1519,29 +1522,29 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
if (_screen->_presentation_params.Windowed) {
// GetFrontBuffer() retrieves the entire desktop for a monitor,
// so we need to reserve space for that.
// We have to use GetMonitorInfo(), since this GSG may not be
// for the primary monitor.
MONITORINFO minfo;
minfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(_screen->_monitor, &minfo);
w = RECT_XSIZE(minfo.rcMonitor);
h = RECT_YSIZE(minfo.rcMonitor);
// set rect to client area of window in scrn coords
ClientToScreen(_screen->_window, (POINT*)&rect.left);
ClientToScreen(_screen->_window, (POINT*)&rect.right);
}
// For GetFrontBuffer(), we need a temporary surface of type
// A8R8G8B8. Unlike GetBackBuffer(), GetFrontBuffer() implicitly
// performs a copy.
hr = _d3d_device->CreateImageSurface(w, h, D3DFMT_A8R8G8B8, &temp_surface);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
return false;
}
@ -1549,7 +1552,7 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
if (hr == D3DERR_DEVICELOST) {
dxgsg8_cat.error()
<< "copy_pixel_buffer failed: device lost\n";
<< "copy_pixel_buffer failed: device lost\n";
temp_surface->Release();
return false;
}
@ -1565,8 +1568,8 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
return false;
}
DXTextureContext8::d3d_surface_to_texture(rect, temp_surface,
copy_inverted, tex, z);
DXTextureContext8::d3d_surface_to_texture(rect, temp_surface,
copy_inverted, tex, z);
RELEASE(temp_surface, dxgsg8, "temp_surface", RELEASE_ONCE);
@ -1644,6 +1647,27 @@ reset() {
_supports_texture_saved_result = ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0);
_supports_texture_dot3 = true;
// check for render to texture support
D3DDEVICE_CREATION_PARAMETERS creation_parameters;
_supports_render_texture = false;
hr = _d3d_device->GetCreationParameters (&creation_parameters);
if (SUCCEEDED (hr)) {
hr = _screen->_d3d8->CheckDeviceFormat (
creation_parameters.AdapterOrdinal,
creation_parameters.DeviceType,
_screen->_display_mode.Format,
D3DUSAGE_RENDERTARGET,
D3DRTYPE_TEXTURE,
_render_to_texture_d3d_format);
if (SUCCEEDED (hr)) {
_supports_render_texture = true;
}
}
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug() << "Render to Texture Support = " << _supports_render_texture << "\n";
}
_supports_3d_texture = ((d3d_caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) != 0);
if (_supports_3d_texture) {
_max_3d_texture_dimension = d3d_caps.MaxVolumeExtent;
@ -1735,7 +1759,7 @@ reset() {
// turn on dithering if the rendertarget is < 8bits/color channel
bool dither_enabled = ((!dx_no_dithering) && IS_16BPP_DISPLAY_FORMAT(_screen->_presentation_params.BackBufferFormat)
&& (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
&& (_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER));
_d3d_device->SetRenderState(D3DRS_DITHERENABLE, dither_enabled);
_d3d_device->SetRenderState(D3DRS_CLIPPING, true);
@ -2083,7 +2107,7 @@ set_state_and_transform(const RenderState *target,
_internal_transform = _cs_transform->compose(transform);
do_issue_transform();
}
if (target == _state_rs) {
return;
}
@ -2095,87 +2119,87 @@ set_state_and_transform(const RenderState *target,
// 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) {
do_issue_alpha_test();
_state._alpha_test = _target._alpha_test;
}
if (_target._antialias != _state._antialias) {
// Antialias not implemented under DX8
_state._antialias = _target._antialias;
}
if (_target._clip_plane != _state._clip_plane) {
do_issue_clip_plane();
_state._clip_plane = _target._clip_plane;
}
if (_target._color != _state._color) {
do_issue_color();
_state._color = _target._color;
}
if (_target._color_scale != _state._color_scale) {
do_issue_color_scale();
_state._color_scale = _target._color_scale;
}
if (_target._cull_face != _state._cull_face) {
do_issue_cull_face();
_state._cull_face = _target._cull_face;
}
if (_target._depth_offset != _state._depth_offset) {
do_issue_depth_offset();
_state._depth_offset = _target._depth_offset;
}
if (_target._depth_test != _state._depth_test) {
do_issue_depth_test();
_state._depth_test = _target._depth_test;
}
if (_target._depth_write != _state._depth_write) {
do_issue_depth_write();
_state._depth_write = _target._depth_write;
}
if (_target._fog != _state._fog) {
do_issue_fog();
_state._fog = _target._fog;
}
if (_target._render_mode != _state._render_mode) {
do_issue_render_mode();
_state._render_mode = _target._render_mode;
}
if (_target._rescale_normal != _state._rescale_normal) {
do_issue_rescale_normal();
_state._rescale_normal = _target._rescale_normal;
}
if (_target._shade_model != _state._shade_model) {
do_issue_shade_model();
_state._shade_model = _target._shade_model;
}
// Shaders not implemented under DX8
if (_target._shader != _state._shader) {
_state._shader = _target._shader;
}
if (_target._tex_gen != _state._tex_gen) {
_state._texture = 0;
_state._tex_gen = _target._tex_gen;
}
if (_target._tex_matrix != _state._tex_matrix) {
_state._texture = 0;
_state._tex_matrix = _target._tex_matrix;
}
if ((_target._transparency != _state._transparency)||
(_target._color_write != _state._color_write)||
(_target._color_blend != _state._color_blend)) {
@ -2184,7 +2208,7 @@ set_state_and_transform(const RenderState *target,
_state._color_write = _target._color_write;
_state._color_blend = _target._color_blend;
}
if (_target._texture != _state._texture) {
do_issue_texture();
_state._texture = _target._texture;
@ -2194,7 +2218,7 @@ set_state_and_transform(const RenderState *target,
do_issue_material();
_state._material = _target._material;
}
if (_target._light != _state._light) {
do_issue_light();
_state._light = _target._light;
@ -2489,7 +2513,7 @@ do_issue_texture() {
if (_state._tex_matrix->has_stage(stage)) {
tex_mat = _state._tex_matrix->get_transform(stage);
}
// Issue the texgen mode.
TexGenAttrib::Mode mode = _state._tex_gen->get_mode(stage);
bool any_point_sprite = false;
@ -2499,7 +2523,7 @@ do_issue_texture() {
case TexGenAttrib::M_light_vector:
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index);
break;
case TexGenAttrib::M_eye_sphere_map:
{
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
@ -2523,7 +2547,7 @@ do_issue_texture() {
// transform. In the case of a vector, we should not apply the
// pos component of the transform.
{
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
texcoord_dimensions = 3;
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
@ -2532,7 +2556,7 @@ do_issue_texture() {
break;
case TexGenAttrib::M_eye_cube_map:
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
tex_mat = tex_mat->compose(_inv_cs_transform);
texcoord_dimensions = 3;
@ -2544,7 +2568,7 @@ do_issue_texture() {
// the case of a normal, we should not apply the pos component
// of the transform.
{
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
texcoord_dimensions = 3;
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
@ -2553,7 +2577,7 @@ do_issue_texture() {
break;
case TexGenAttrib::M_eye_normal:
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACENORMAL);
texcoord_dimensions = 3;
tex_mat = tex_mat->compose(_inv_cs_transform);
@ -2564,7 +2588,7 @@ do_issue_texture() {
// coordinates to world coordinates; i.e. apply the
// camera transform.
{
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
texcoord_dimensions = 3;
CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
@ -2573,18 +2597,18 @@ do_issue_texture() {
break;
case TexGenAttrib::M_eye_position:
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX,
texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION);
texcoord_dimensions = 3;
tex_mat = tex_mat->compose(_inv_cs_transform);
break;
case TexGenAttrib::M_point_sprite:
_d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index);
any_point_sprite = true;
break;
}
_d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite);
if (!tex_mat->is_identity()) {
@ -2601,12 +2625,12 @@ do_issue_texture() {
} else {
LMatrix4f m = tex_mat->get_mat();
_d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data());
DWORD transform_flags = texcoord_dimensions;
if (m.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) {
// If we have a projected texture matrix, we also need to
// set D3DTTFF_COUNT4.
transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
}
DWORD transform_flags = texcoord_dimensions;
if (m.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) {
// If we have a projected texture matrix, we also need to
// set D3DTTFF_COUNT4.
transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED;
}
_d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS,
transform_flags);
}
@ -2741,12 +2765,12 @@ do_issue_blending() {
if (_target._color_write->get_channels() == ColorWriteAttrib::C_off) {
if (_target._color_write != _state._color_write) {
if (_screen->_can_direct_disable_color_writes) {
_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
_d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0);
} else {
_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
_d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
_d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
_d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
_d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
_d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
}
return;
@ -2788,10 +2812,10 @@ do_issue_blending() {
break;
}
_d3d_device->SetRenderState(D3DRS_SRCBLEND,
get_blend_func(color_blend->get_operand_a()));
_d3d_device->SetRenderState(D3DRS_DESTBLEND,
get_blend_func(color_blend->get_operand_b()));
_d3d_device->SetRenderState(D3DRS_SRCBLEND,
get_blend_func(color_blend->get_operand_a()));
_d3d_device->SetRenderState(D3DRS_DESTBLEND,
get_blend_func(color_blend->get_operand_b()));
return;
}
@ -3069,7 +3093,7 @@ report_texmgr_stats() {
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::set_context
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
set_context(DXScreenData *new_context) {
@ -3110,13 +3134,13 @@ set_render_target() {
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::set_texture_blend_mode
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
set_texture_blend_mode(int i, const TextureStage *stage) {
switch (stage->get_mode()) {
case TextureStage::M_modulate:
// emulates GL_MODULATE glTexEnv mode
// emulates GL_MODULATE glTexEnv mode
_d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_MODULATE);
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
@ -3160,7 +3184,7 @@ set_texture_blend_mode(int i, const TextureStage *stage) {
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG0, D3DTA_TEXTURE);
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG2, D3DTA_CURRENT);
_d3d_device->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TFACTOR);
_d3d_device->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
_d3d_device->SetTextureStageState(i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
_d3d_device->SetTextureStageState(i, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
@ -3171,63 +3195,63 @@ set_texture_blend_mode(int i, const TextureStage *stage) {
// M_combine mode begins a collection of more sophisticated modes,
// which match up more closely with DirectX's built-in modes.
_d3d_device->SetTextureStageState
(i, D3DTSS_COLOROP,
(i, D3DTSS_COLOROP,
get_texture_operation(stage->get_combine_rgb_mode(),
stage->get_rgb_scale()));
switch (stage->get_num_combine_rgb_operands()) {
case 3:
_d3d_device->SetTextureStageState
(i, D3DTSS_COLORARG0,
(i, D3DTSS_COLORARG0,
get_texture_argument(stage->get_combine_rgb_source2(),
stage->get_combine_rgb_operand2()));
// fall through
case 2:
_d3d_device->SetTextureStageState
(i, D3DTSS_COLORARG2,
(i, D3DTSS_COLORARG2,
get_texture_argument(stage->get_combine_rgb_source1(),
stage->get_combine_rgb_operand1()));
// fall through
case 1:
_d3d_device->SetTextureStageState
(i, D3DTSS_COLORARG1,
(i, D3DTSS_COLORARG1,
get_texture_argument(stage->get_combine_rgb_source0(),
stage->get_combine_rgb_operand0()));
// fall through
default:
break;
}
_d3d_device->SetTextureStageState
(i, D3DTSS_ALPHAOP,
(i, D3DTSS_ALPHAOP,
get_texture_operation(stage->get_combine_alpha_mode(),
stage->get_alpha_scale()));
switch (stage->get_num_combine_alpha_operands()) {
case 3:
_d3d_device->SetTextureStageState
(i, D3DTSS_ALPHAARG0,
(i, D3DTSS_ALPHAARG0,
get_texture_argument(stage->get_combine_alpha_source2(),
stage->get_combine_alpha_operand2()));
// fall through
case 2:
_d3d_device->SetTextureStageState
(i, D3DTSS_ALPHAARG2,
(i, D3DTSS_ALPHAARG2,
get_texture_argument(stage->get_combine_alpha_source1(),
stage->get_combine_alpha_operand1()));
// fall through
case 1:
_d3d_device->SetTextureStageState
(i, D3DTSS_ALPHAARG1,
(i, D3DTSS_ALPHAARG1,
get_texture_argument(stage->get_combine_alpha_source0(),
stage->get_combine_alpha_operand0()));
// fall through
default:
break;
}
@ -3306,7 +3330,7 @@ dx_cleanup() {
// screen
////////////////////////////////////////////////////////////////////
HRESULT DXGraphicsStateGuardian8::
reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
DXScreenData **screen) {
HRESULT hr;
@ -3334,9 +3358,9 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
<< " presentation_params = "
<< presentation_params->BackBufferWidth << "x" << presentation_params->BackBufferHeight << "\n";
}
get_engine()->reset_all_windows(false);// reset old swapchain by releasing
if (_screen->_swap_chain) { //other windows might be using bigger buffers
_presentation_reset.BackBufferWidth = max(_presentation_reset.BackBufferWidth, presentation_params->BackBufferWidth);
_presentation_reset.BackBufferHeight = max(_presentation_reset.BackBufferHeight, presentation_params->BackBufferHeight);
@ -3357,12 +3381,12 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
// cheap to replace.
release_all_vertex_buffers();
release_all_index_buffers();
hr = _d3d_device->Reset(&_presentation_reset);
if (FAILED(hr)) {
return hr;
}
get_engine()->reset_all_windows(true);// reset with new swapchains by creating
if (screen) {
*screen = NULL;
@ -3378,7 +3402,7 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
// release the old swapchain and create a new one
if (_screen && _screen->_swap_chain) {
_screen->_swap_chain->Release();
wdxdisplay8_cat.debug()
wdxdisplay8_cat.debug()
<< "swap chain " << _screen->_swap_chain << " is released\n";
_screen->_swap_chain = NULL;
hr = _d3d_device->CreateAdditionalSwapChain(presentation_params, &_screen->_swap_chain);
@ -3397,7 +3421,7 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::check_cooperative_level
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
check_cooperative_level() {
@ -3479,7 +3503,7 @@ show_frame() {
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::create_swap_chain
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
create_swap_chain(DXScreenData *new_context) {
@ -3710,10 +3734,10 @@ get_texture_argument_modifier(TextureStage::CombineOperand operand) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
unsigned int primitive_count,
unsigned int first_vertex,
unsigned int num_vertices,
const unsigned char *buffer, size_t stride) {
unsigned int primitive_count,
unsigned int first_vertex,
unsigned int num_vertices,
const unsigned char *buffer, size_t stride) {
// It appears that the common ATI driver seems to fail to draw
// anything in the DrawPrimitiveUP() call if the address range of
@ -3728,12 +3752,12 @@ draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
// Actually, the buffer doesn't fit within the required limit
// anyway. Go ahead and draw it and hope for the best.
_d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
buffer_start, stride);
buffer_start, stride);
} else if ((((long)buffer_end ^ (long)buffer_start) & ~0xffff) == 0) {
// No problem; we can draw the buffer directly.
_d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
buffer_start, stride);
buffer_start, stride);
} else {
// We have a problem--the buffer crosses over a 0x10000 boundary.
@ -3742,8 +3766,8 @@ draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
unsigned char *safe_buffer_start = get_safe_buffer_start();
memcpy(safe_buffer_start, buffer_start, buffer_end - buffer_start);
_d3d_device->DrawPrimitiveUP(primitive_type, primitive_count,
safe_buffer_start, stride);
safe_buffer_start, stride);
}
}
@ -3760,11 +3784,11 @@ draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
unsigned int min_index, unsigned int max_index,
unsigned int num_primitives,
const unsigned char *index_data,
D3DFORMAT index_type,
const unsigned char *buffer, size_t stride) {
unsigned int min_index, unsigned int max_index,
unsigned int num_primitives,
const unsigned char *index_data,
D3DFORMAT index_type,
const unsigned char *buffer, size_t stride) {
// As above, we'll hack the case of the buffer crossing the 0x10000
// boundary.
const unsigned char *buffer_start = buffer + stride * min_index;

View File

@ -74,7 +74,7 @@ public:
virtual void end_scene();
virtual void end_frame();
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const Geom *geom,
const GeomMunger *munger,
const GeomVertexData *vertex_data);
virtual void draw_triangles(const GeomTriangles *primitive);
@ -94,11 +94,11 @@ public:
virtual void apply_fog(Fog *fog);
virtual void bind_light(PointLight *light_obj, const NodePath &light,
virtual void bind_light(PointLight *light_obj, const NodePath &light,
int light_id);
virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
int light_id);
virtual void bind_light(Spotlight *light_obj, const NodePath &light,
virtual void bind_light(Spotlight *light_obj, const NodePath &light,
int light_id);
static D3DFORMAT get_index_type(Geom::NumericType numeric_type);
@ -123,7 +123,7 @@ protected:
void do_issue_material();
void do_issue_texture();
void do_issue_blending();
virtual void enable_lighting(bool enable);
virtual void set_ambient_light(const Colorf &color);
virtual void enable_light(int light_id, bool enable);
@ -154,7 +154,7 @@ protected:
void set_texture_blend_mode(int i, const TextureStage *stage);
void dx_cleanup();
HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *p_presentation_params,
HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *p_presentation_params,
DXScreenData **screen = NULL);
bool check_cooperative_level();
@ -173,16 +173,16 @@ protected:
static DWORD get_texture_argument_modifier(TextureStage::CombineOperand operand);
void draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
unsigned int primitive_count,
unsigned int first_vertex,
unsigned int num_vertices,
const unsigned char *buffer, size_t stride);
unsigned int primitive_count,
unsigned int first_vertex,
unsigned int num_vertices,
const unsigned char *buffer, size_t stride);
void draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
unsigned int min_index, unsigned int max_index,
unsigned int num_primitives,
const unsigned char *index_data,
D3DFORMAT index_type,
const unsigned char *buffer, size_t stride);
unsigned int min_index, unsigned int max_index,
unsigned int num_primitives,
const unsigned char *index_data,
D3DFORMAT index_type,
const unsigned char *buffer, size_t stride);
INLINE static unsigned char *get_safe_buffer_start();
@ -234,6 +234,8 @@ protected:
static unsigned char *_temp_buffer;
static unsigned char *_safe_buffer_start;
D3DFORMAT _render_to_texture_d3d_format;
public:
virtual TypeHandle get_type() const {
return get_class_type();
@ -255,6 +257,7 @@ private:
static TypeHandle _type_handle;
friend class wdxGraphicsWindow8;
friend class wdxGraphicsBuffer8;
friend class wdxGraphicsPipe8;
friend class wdxGraphicsWindowGroup8;
friend class DXTextureContext8;

View File

@ -41,10 +41,10 @@ public:
INLINE IDirect3DVolumeTexture8 *get_d3d_volume_texture() const;
INLINE IDirect3DCubeTexture8 *get_d3d_cube_texture() const;
static HRESULT d3d_surface_to_texture(RECT &source_rect,
IDirect3DSurface8 *d3d_surface,
bool inverted, Texture *result,
int z);
static HRESULT d3d_surface_to_texture(RECT &source_rect,
IDirect3DSurface8 *d3d_surface,
bool inverted, Texture *result,
int z);
private:
HRESULT fill_d3d_texture_pixels();
@ -77,6 +77,8 @@ public:
private:
static TypeHandle _type_handle;
friend class wdxGraphicsBuffer8;
};
#include "dxTextureContext8.I"

View File

@ -6,4 +6,5 @@
#include "dxGeomMunger8.cxx"
#include "wdxGraphicsPipe8.cxx"
#include "wdxGraphicsWindow8.cxx"
#include "wdxGraphicsBuffer8.cxx"
#include "dxGraphicsDevice8.cxx"

View File

@ -0,0 +1,502 @@
// Filename: wdxGraphicsBuffer8.cxx
// Created by: drose (08Feb04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2005, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "wdxGraphicsPipe8.h"
#include "wdxGraphicsBuffer8.h"
#include "pStatTimer.h"
// ISSUES:
// size issues
// texture size must not exeeed the original frame buffer width
// or height due to the size of the original depth/stencil buffer
// render to texure format
// can be specified via the DXGraphicsStateGuardian8 member
// _render_to_texture_d3d_format default = D3DFMT_X8R8G8B8
// LOST DEVICE case for D3DPOOL_DEFAULT buffers
// should check texture creation with CheckDepthStencilMatch
// support copy from texture to ram?
// check D3DCAPS2_DYNAMICTEXTURES
TypeHandle wdxGraphicsBuffer8::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsBuffer8::
wdxGraphicsBuffer8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size) :
GraphicsBuffer(pipe, gsg, name, x_size, y_size)
{
// initialize all class members
_cube_map_index = -1;
_back_buffer = NULL;
_z_stencil_buffer = NULL;
_direct_3d_surface = NULL;
_dx_texture_context8 = NULL;
// is this correct ???
// Since the pbuffer never gets flipped, we get screenshots from the
// same buffer we draw into.
_screenshot_buffer_type = _draw_buffer_type;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
wdxGraphicsBuffer8::
~wdxGraphicsBuffer8() {
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
// should do whatever setup is required, and return true
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer8::
begin_frame() {
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_R(dxgsg, _gsg, false);
return GraphicsBuffer::begin_frame();
}
////////////////////////////////////////////////////////////////////
// Function: wglGraphicsStateGuardian::begin_render_texture
// Access: Public, Virtual
// Description: If the GraphicsOutput supports direct render-to-texture,
// and if any setup needs to be done during begin_frame,
// then the setup code should go here. Any textures that
// can not be rendered to directly should be reflagged
// as RTM_copy_texture.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
begin_render_texture() {
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_V(dxgsg, _gsg);
HRESULT hr;
bool state;
state = false;
// save render context
hr = dxgsg -> _d3d_device -> GetRenderTarget (&_back_buffer);
if (SUCCEEDED (hr)) {
hr = dxgsg -> _d3d_device -> GetDepthStencilSurface (&_z_stencil_buffer);
if (SUCCEEDED (hr)) {
state = true;
}
}
// set render context
if (state && _dx_texture_context8)
{
int tex_index;
DXTextureContext8 *dx_texture_context8;
// ***** assume 0 ???
tex_index = 0;
Texture *tex = get_texture(tex_index);
// ***** ??? CAST
// use saved dx_texture_context8
dx_texture_context8 = _dx_texture_context8;
UINT mipmap_level;
mipmap_level = 0;
_direct_3d_surface = NULL;
// render to texture 2D
IDirect3DTexture8 *direct_3d_texture;
direct_3d_texture = dx_texture_context8 -> _d3d_2d_texture;
if (direct_3d_texture) {
hr = direct_3d_texture -> GetSurfaceLevel (mipmap_level, &_direct_3d_surface);
if (SUCCEEDED (hr)) {
hr = dxgsg -> _d3d_device -> SetRenderTarget (_direct_3d_surface,
_z_stencil_buffer);
if (SUCCEEDED (hr)) {
}
}
}
// render to cubemap face
IDirect3DCubeTexture8 *direct_3d_cube_texture;
direct_3d_cube_texture = dx_texture_context8 -> _d3d_cube_texture;
if (direct_3d_cube_texture) {
if (_cube_map_index >= 0 && _cube_map_index < 6) {
hr = direct_3d_cube_texture -> GetCubeMapSurface (
(D3DCUBEMAP_FACES) _cube_map_index, mipmap_level, &_direct_3d_surface);
if (SUCCEEDED (hr)) {
hr = dxgsg -> _d3d_device -> SetRenderTarget (_direct_3d_surface,
_z_stencil_buffer);
if (SUCCEEDED (hr)) {
}
}
} else {
// error: invalid cube map face index
}
}
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::end_render_texture
// Access: Public, Virtual
// Description: If the GraphicsOutput supports direct render-to-texture,
// and if any setup needs to be done during end_frame,
// then the setup code should go here. Any textures that
// could not be rendered to directly should be reflagged
// as RTM_copy_texture.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
end_render_texture() {
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_V(dxgsg, _gsg);
// is this really needed ??? seems to work without it though
/*
// Find the color texture, if there is one. That one can be bound to
// the framebuffer. All others must be marked RTM_copy_to_texture.
int tex_index = -1;
for (int i=0; i<count_textures(); i++) {
if (get_rtm_mode(i) == RTM_bind_or_copy) {
if ((get_texture(i)->get_format() != Texture::F_depth_component)&&
(get_texture(i)->get_format() != Texture::F_stencil_index)&&
(tex_index < 0)) {
tex_index = i;
} else {
_textures[i]._rtm_mode = RTM_copy_texture;
}
}
}
if (tex_index >= 0) {
Texture *tex = get_texture(tex_index);
TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
nassertv(tc != (TextureContext *)NULL);
}
*/
// restore render context
HRESULT hr;
if (_back_buffer) {
hr = dxgsg -> _d3d_device -> SetRenderTarget (_back_buffer,
_z_stencil_buffer);
if (SUCCEEDED (hr)) {
_back_buffer -> Release ( );
}
_back_buffer = NULL;
}
if (_z_stencil_buffer) {
_z_stencil_buffer -> Release ( );
_z_stencil_buffer = NULL;
}
if (_direct_3d_surface) {
_direct_3d_surface -> Release ( );
_direct_3d_surface = NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::select_cube_map
// Access: Public, Virtual
// Description: Called internally when the window is in
// render-to-a-texture mode and we are in the process of
// rendering the six faces of a cube map. This should
// do whatever needs to be done to switch the buffer to
// the indicated face.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
select_cube_map(int cube_map_index) {
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_V(dxgsg, _gsg);
_cube_map_index = cube_map_index;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::make_current
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// during begin_frame() to ensure the graphics context
// is ready for drawing.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
make_current() {
PStatTimer timer(_make_current_pcollector);
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_V(dxgsg, _gsg);
// do nothing here
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::release_gsg
// Access: Public, Virtual
// Description: Releases the current GSG pointer, if it is currently
// held, and resets the GSG to NULL. The window will be
// permanently unable to render; this is normally called
// only just before destroying the window. This should
// only be called from within the draw thread.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
release_gsg() {
GraphicsBuffer::release_gsg();
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::process_events
// Access: Public, Virtual
// Description: Do whatever processing is necessary to ensure that
// the window responds to user events. Also, honor any
// requests recently made via request_properties()
//
// This function is called only within the window
// thread.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
process_events() {
GraphicsBuffer::process_events();
MSG msg;
// Handle all the messages on the queue in a row. Some of these
// might be for another window, but they will get dispatched
// appropriately.
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
process_1_event();
}
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::close_buffer
// Access: Protected, Virtual
// Description: Closes the buffer right now. Called from the window
// thread.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
close_buffer() {
if (_gsg != (GraphicsStateGuardian *)NULL) {
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_V(dxgsg, _gsg);
DXTextureContext8 *dx_texture_context8;
dx_texture_context8 = _dx_texture_context8;
if (dx_texture_context8) {
// release render texture
if (dx_texture_context8 -> _d3d_texture) {
dx_texture_context8 -> _d3d_texture -> Release ( );
}
dx_texture_context8 -> _d3d_texture = NULL;
dx_texture_context8 -> _d3d_2d_texture = NULL;
dx_texture_context8 -> _d3d_volume_texture = NULL;
dx_texture_context8 -> _d3d_cube_texture = NULL;
}
}
_cube_map_index = -1;
_is_valid = false;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::open_buffer
// Access: Protected, Virtual
// Description: Opens the window right now. Called from the window
// thread. Returns true if the window is successfully
// opened, or false if there was a problem.
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer8::
open_buffer() {
bool state;
DXGraphicsStateGuardian8 *dxgsg;
DCAST_INTO_R(dxgsg, _gsg, false);
// create texture
int tex_index;
UINT texture_depth;
DXTextureContext8 *dx_texture_context8;
state = false;
_is_valid = false;
// **** assume tex_index is 0 ???
tex_index = 0;
texture_depth = 1;
Texture *tex = get_texture(tex_index);
TextureContext *tc = tex->prepare_now(_gsg->get_prepared_objects(), _gsg);
// ***** ??? CAST
dx_texture_context8 = (DXTextureContext8 *) tc;
// release managed texture
if (dx_texture_context8 -> _d3d_texture) {
dx_texture_context8 -> _d3d_texture -> Release ( );
}
dx_texture_context8 -> _d3d_texture = NULL;
dx_texture_context8 -> _d3d_2d_texture = NULL;
dx_texture_context8 -> _d3d_volume_texture = NULL;
dx_texture_context8 -> _d3d_cube_texture = NULL;
// save dx_texture_context8
_dx_texture_context8 = dx_texture_context8;
// create render texture
if (wdxGraphicsBuffer8::create_render_texture (
get_x_size ( ),
get_y_size ( ),
texture_depth,
dxgsg -> _render_to_texture_d3d_format,
dx_texture_context8,
dxgsg -> _d3d_device)) {
// override texture managed format
dx_texture_context8 -> _d3d_format = dxgsg -> _render_to_texture_d3d_format;
dx_texture_context8 -> _has_mipmaps = false;
_is_valid = true;
state = true;
}
return state;
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::process_1_event
// Access: Private, Static
// Description: Handles one event from the message queue.
////////////////////////////////////////////////////////////////////
void wdxGraphicsBuffer8::
process_1_event() {
MSG msg;
if (!GetMessage(&msg, NULL, 0, 0)) {
// WM_QUIT received. We need a cleaner way to deal with this.
// DestroyAllWindows(false);
exit(msg.wParam); // this will invoke AtExitFn
}
// Translate virtual key messages
TranslateMessage(&msg);
// Call window_proc
DispatchMessage(&msg);
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsBuffer8::create_render_texture
// Access: Private
// Description: Creates a texture that can be rendered into
////////////////////////////////////////////////////////////////////
bool wdxGraphicsBuffer8::
create_render_texture (UINT texture_width, UINT texture_height, UINT texture_depth, D3DFORMAT texture_format, DXTextureContext8 *dx_texture_context8, IDirect3DDevice8 *direct_3d_device)
{
bool state;
HRESULT hr;
DWORD usage;
D3DPOOL pool;
UINT mip_level_count;
D3DFORMAT pixel_format;
int texture_type;
state = false;
texture_type = dx_texture_context8 -> _texture -> get_texture_type ( );
// assume 1 mip level
mip_level_count = 1;
// REQUIRED pool and usage
pool = D3DPOOL_DEFAULT;
usage = D3DUSAGE_RENDERTARGET;
// ???
// usage |= D3DUSAGE_DYNAMIC;
pixel_format = texture_format;
switch (texture_type)
{
case Texture::TT_2d_texture:
hr = direct_3d_device->CreateTexture
(texture_width, texture_height, mip_level_count, usage,
pixel_format, pool, &dx_texture_context8 -> _d3d_2d_texture);
dx_texture_context8 -> _d3d_texture = dx_texture_context8 -> _d3d_2d_texture;
break;
case Texture::TT_3d_texture:
// DX8 does not support rendering to volume textures so this should fail
hr = direct_3d_device->CreateVolumeTexture
(texture_width, texture_height, texture_depth, mip_level_count, usage,
pixel_format, pool, &dx_texture_context8 -> _d3d_volume_texture);
dx_texture_context8 -> _d3d_texture = dx_texture_context8 -> _d3d_volume_texture;
break;
case Texture::TT_cube_map:
hr = direct_3d_device->CreateCubeTexture
(texture_width, mip_level_count, usage,
pixel_format, pool, &dx_texture_context8 -> _d3d_cube_texture);
dx_texture_context8 -> _d3d_texture = dx_texture_context8 -> _d3d_cube_texture;
break;
default:
break;
}
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "create_render_texture failed" << D3DERRORSTRING(hr);
}
else {
state = true;
}
return state;
}

View File

@ -0,0 +1,94 @@
// Filename: wdxGraphicsBuffer8.h
// Created by: drose (08Feb04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2005, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef wdxGraphicsBuffer8_H
#define wdxGraphicsBuffer8_H
#include "pandabase.h"
#include "graphicsBuffer.h"
#include "dxgsg8base.h"
////////////////////////////////////////////////////////////////////
// Class : wdxGraphicsBuffer8
// Description : An offscreen render buffer. In OpenGL under Windows,
// this simply renders into a window that is never made
// visible. There's a Windows interface for rendering
// into a DIB, but this puts restrictions on the kind of
// pixelformat we can use, and thus makes it difficult
// to support one GSG rendering into an offscreen buffer
// and also into a window.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX wdxGraphicsBuffer8 : public GraphicsBuffer {
public:
wdxGraphicsBuffer8(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
const string &name,
int x_size, int y_size);
virtual ~wdxGraphicsBuffer8();
virtual bool begin_frame();
virtual void select_cube_map(int cube_map_index);
virtual void make_current();
virtual void release_gsg();
virtual void begin_render_texture();
virtual void end_render_texture();
virtual void process_events();
protected:
virtual void close_buffer();
virtual bool open_buffer();
private:
static void process_1_event();
int _cube_map_index;
IDirect3DSurface8 *_back_buffer;
IDirect3DSurface8 *_z_stencil_buffer;
IDirect3DSurface8 *_direct_3d_surface;
DXTextureContext8 *_dx_texture_context8;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GraphicsBuffer::init_type();
register_type(_type_handle, "wdxGraphicsBuffer8",
GraphicsBuffer::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
bool create_render_texture (UINT texture_width, UINT texture_height, UINT texture_depth, D3DFORMAT texture_format, DXTextureContext8 *dx_texture_context8, IDirect3DDevice8 *direct_3d_device);
private:
static TypeHandle _type_handle;
friend class DXGraphicsStateGuardian8;
friend class DXTextureContext8;
};
// #include "wdxGraphicsBuffer8.I"
#endif

View File

@ -19,6 +19,7 @@
#include "wdxGraphicsPipe8.h"
#include "dxGraphicsDevice8.h"
#include "wdxGraphicsWindow8.h"
#include "wdxGraphicsBuffer8.h"
#include "config_dxgsg8.h"
TypeHandle wdxGraphicsPipe8::_type_handle;
@ -97,6 +98,25 @@ make_window(GraphicsStateGuardian *gsg, const string &name) {
return new wdxGraphicsWindow8(this, gsg, name);
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe8::make_buffer
// Access: Protected, Virtual
// Description: Creates a new offscreen buffer on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsBuffer) wdxGraphicsPipe8::
make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size) {
// hmmmm must return NULL if render to texture is supported and you don't
// want to use it, otherwise it doesn't work
if (support_render_texture && gsg->get_supports_render_texture ( )) {
return new wdxGraphicsBuffer8(this, gsg, name, x_size, y_size);
}
else {
return NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: wdxGraphicsPipe8::init
// Access: Private

View File

@ -54,11 +54,13 @@ public:
D3DFORMAT *pSuggestedPixFmt,
bool bForce16bppZBuffer,
bool bVerboseMode = false);
bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
protected:
virtual PT(GraphicsWindow) make_window(GraphicsStateGuardian *gsg, const string &name);
virtual PT(GraphicsBuffer) make_buffer(GraphicsStateGuardian *gsg, const string &name,
int x_size, int y_size);
private:
bool init();
@ -90,7 +92,7 @@ private:
GUID DX7_DeviceGUID;
DWORD VendorID, DeviceID;
};
typedef pvector<CardID> CardIDs;
CardIDs _card_ids;
bool __is_dx8_1;