dx points and point sprites

This commit is contained in:
David Rose 2005-04-21 22:17:03 +00:00
parent 5157ec72c8
commit a4677868e2
5 changed files with 110 additions and 54 deletions

View File

@ -161,8 +161,17 @@ munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &vertex_data) {
geom = geom->decompose(); geom = geom->decompose();
} }
if ((unsupported_bits & qpGeom::GR_shade_model_bits) != 0) { if ((unsupported_bits & qpGeom::GR_shade_model_bits) != 0) {
// Rotate the vertices to account for different shade-model
// expectations (e.g. SM_flat_last_vertex to
// SM_flat_first_vertex)
geom = geom->rotate(); geom = geom->rotate();
} }
if ((unsupported_bits & qpGeom::GR_indexed_bits) != 0) {
// Convert indexed geometry to nonindexed geometry.
PT(qpGeom) new_geom = new qpGeom(*geom);
new_geom->make_nonindexed(false);
geom = new_geom;
}
} }
return true; return true;

View File

@ -55,6 +55,8 @@
#include "qpgeomTristrips.h" #include "qpgeomTristrips.h"
#include "qpgeomTrifans.h" #include "qpgeomTrifans.h"
#include "qpgeomLines.h" #include "qpgeomLines.h"
#include "qpgeomLinestrips.h"
#include "qpgeomPoints.h"
#include "qpGeomVertexReader.h" #include "qpGeomVertexReader.h"
#include "dxGeomMunger8.h" #include "dxGeomMunger8.h"
#include "config_gobj.h" #include "config_gobj.h"
@ -223,7 +225,13 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
// they copy framebuffer-to-texture. Ok. // they copy framebuffer-to-texture. Ok.
_copy_texture_inverted = true; _copy_texture_inverted = true;
// D3DRS_POINTSPRITEENABLE doesn't seem to support remapping the
// texture coordinates via a texture matrix, a fatal flaw. Without
// that support, we don't advertise this capability, and fall back
// to always generating quads for textured sprites.
_supported_geom_rendering = _supported_geom_rendering =
qpGeom::GR_point | qpGeom::GR_point_uniform_size |
qpGeom::GR_point_perspective | /* qpGeom::GR_point_sprite |*/
qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan | qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
qpGeom::GR_flat_first_vertex; qpGeom::GR_flat_first_vertex;
} }
@ -401,8 +409,7 @@ dx_init(void) {
_fog_enabled = false; _fog_enabled = false;
_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, _fog_enabled); _pD3DDevice->SetRenderState(D3DRS_FOGENABLE, _fog_enabled);
_current_projection_mat = LMatrix4f::ident_mat(); _projection_mat = LMatrix4f::ident_mat();
_projection_mat_stack_count = 0;
_has_scene_graph_color = false; _has_scene_graph_color = false;
// Apply a default material when materials are turned off. // Apply a default material when materials are turned off.
@ -663,6 +670,7 @@ prepare_display_region() {
if (_current_display_region == (DisplayRegion*)0L) { if (_current_display_region == (DisplayRegion*)0L) {
dxgsg8_cat.error() dxgsg8_cat.error()
<< "Invalid NULL display region in prepare_display_region()\n"; << "Invalid NULL display region in prepare_display_region()\n";
} else if (_current_display_region != _actual_display_region) { } else if (_current_display_region != _actual_display_region) {
_actual_display_region = _current_display_region; _actual_display_region = _current_display_region;
@ -719,7 +727,7 @@ prepare_lens() {
} }
// Start with the projection matrix from the lens. // Start with the projection matrix from the lens.
const LMatrix4f &projection_mat = _current_lens->get_projection_mat(); const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
// The projection matrix must always be left-handed Y-up internally, // The projection matrix must always be left-handed Y-up internally,
// to match DirectX's convention, even if our coordinate system of // to match DirectX's convention, even if our coordinate system of
@ -736,19 +744,18 @@ prepare_lens() {
0, 0, 0.5, 0, 0, 0, 0.5, 0,
0, 0, 0.5, 1); 0, 0, 0.5, 1);
LMatrix4f new_projection_mat = _projection_mat = convert_mat * lens_mat * rescale_mat;
convert_mat * projection_mat * rescale_mat;
if (_scene_setup->get_inverted()) { if (_scene_setup->get_inverted()) {
// If the scene is supposed to be inverted, then invert the // If the scene is supposed to be inverted, then invert the
// projection matrix. // projection matrix.
static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f); static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
new_projection_mat *= invert_mat; _projection_mat *= invert_mat;
} }
HRESULT hr = HRESULT hr =
_pD3DDevice->SetTransform(D3DTS_PROJECTION, _pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data()); (D3DMATRIX*)_projection_mat.get_data());
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
@ -3095,6 +3102,48 @@ draw_lines(const qpGeomLines *primitive) {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::draw_linestrips
// Access: Public, Virtual
// Description: Draws a series of line strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_linestrips(const qpGeomLinestrips *primitive) {
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::draw_points
// Access: Public, Virtual
// Description: Draws a series of disconnected points.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_points(const qpGeomPoints *primitive) {
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
_primitive_batches_other_pcollector.add_level(1);
// The munger should have protected us from indexed points--DirectX
// doesn't support them.
nassertv(!primitive->is_indexed());
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_pD3DDevice->DrawPrimitive
(D3DPT_POINTLIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
} else {
// Nonindexed, client arrays.
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
unsigned int first_vertex = primitive->get_first_vertex();
_pD3DDevice->DrawPrimitiveUP
(D3DPT_POINTLIST,
primitive->get_num_primitives(),
_vertex_data->get_array(0)->get_data() + stride * first_vertex,
stride);
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::end_draw_primitives() // Function: DXGraphicsStateGuardian8::end_draw_primitives()
// Access: Public, Virtual // Access: Public, Virtual
@ -3887,47 +3936,23 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8:: void DXGraphicsStateGuardian8::
issue_tex_gen(const TexGenAttrib *attrib) { issue_tex_gen(const TexGenAttrib *attrib) {
/* TexGenAttrib::Mode mode = attrib->get_mode(TextureStage::get_default());
* Automatically generate texture coordinates for stage 0. switch (mode) {
* Use the wrap mode from the texture coordinate set at index 1. case TexGenAttrib::M_off:
*/ _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
if (attrib->is_empty()) { break;
//enable_texturing(false); case TexGenAttrib::M_eye_sphere_map:
// reset the texcoordindex lookup to 0 _pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
//_pD3DDevice->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)dm.get_data()); D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
//_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0); _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); break;
} else if (attrib->get_mode(TextureStage::get_default()) == TexGenAttrib::M_eye_sphere_map) { case TexGenAttrib::M_point_sprite:
_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
#if 0 _pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
// best reflection on a sphere is achieved by camera space normals in directx break;
_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACENORMAL);
// We have set up the texture matrix to scale and translate the
// texture coordinates to get from camera space (-1, +1) to
// texture space (0,1)
LMatrix4f dm(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
#else
// since this is a reflection map, we want the camera space
// reflection vector. A close approximation of the asin(theta)/pi
// + 0.5 is achieved by the following matrix
_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
LMatrix4f dm(0.33f, 0.0f, 0.0f, 0.0f,
0.0f, 0.33f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
#endif
_pD3DDevice->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)dm.get_data());
_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
D3DTTFF_COUNT2);
//_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, false);
} }
} }
@ -4015,6 +4040,27 @@ issue_render_mode(const RenderModeAttrib *attrib) {
<< "Unknown render mode " << (int)mode << endl; << "Unknown render mode " << (int)mode << endl;
} }
// This might also specify the point size.
float point_size = attrib->get_thickness();
_pD3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&point_size));
if (attrib->get_perspective()) {
_pD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
LVector3f height(0.0f, point_size, 1.0f);
height = height * _projection_mat;
float s = height[1] / point_size;
float zero = 0.0f;
float one_over_s2 = 1.0f / (s * s);
_pD3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *((DWORD*)&zero));
_pD3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *((DWORD*)&zero));
_pD3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *((DWORD*)&one_over_s2));
} else {
_pD3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
}
_current_fill_mode = mode; _current_fill_mode = mode;
} }

View File

@ -100,6 +100,8 @@ public:
virtual void draw_tristrips(const qpGeomTristrips *primitive); virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void draw_trifans(const qpGeomTrifans *primitive); virtual void draw_trifans(const qpGeomTrifans *primitive);
virtual void draw_lines(const qpGeomLines *primitive); virtual void draw_lines(const qpGeomLines *primitive);
virtual void draw_linestrips(const qpGeomLinestrips *primitive);
virtual void draw_points(const qpGeomPoints *primitive);
virtual void end_draw_primitives(); virtual void end_draw_primitives();
virtual TextureContext *prepare_texture(Texture *tex); virtual TextureContext *prepare_texture(Texture *tex);
@ -326,8 +328,8 @@ protected:
D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter; D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter;
DWORD _CurTexAnisoDegree; DWORD _CurTexAnisoDegree;
Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV; Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV;
LMatrix4f _current_projection_mat;
int _projection_mat_stack_count; LMatrix4f _projection_mat;
CPT(DisplayRegion) _actual_display_region; CPT(DisplayRegion) _actual_display_region;
const DXVertexBufferContext8 *_active_vbuffer; const DXVertexBufferContext8 *_active_vbuffer;

View File

@ -371,6 +371,7 @@ reset() {
report_extensions(); report_extensions();
_supported_geom_rendering = _supported_geom_rendering =
qpGeom::GR_indexed_point |
qpGeom::GR_point | qpGeom::GR_point_uniform_size | qpGeom::GR_point | qpGeom::GR_point_uniform_size |
qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan | qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
qpGeom::GR_flat_last_vertex; qpGeom::GR_flat_last_vertex;
@ -520,9 +521,6 @@ reset() {
_supports_cube_map = _supports_cube_map =
has_extension("GL_ARB_texture_cube_map") || is_at_least_version(1, 3); has_extension("GL_ARB_texture_cube_map") || is_at_least_version(1, 3);
_supports_rescale_normal =
has_extension("GL_EXT_rescale_normal") || is_at_least_version(1, 2);
_supports_bgr = _supports_bgr =
has_extension("GL_EXT_bgra") || is_at_least_version(1, 2); has_extension("GL_EXT_bgra") || is_at_least_version(1, 2);
_supports_rescale_normal = _supports_rescale_normal =
@ -976,6 +974,8 @@ prepare_display_region() {
int l, b, w, h; int l, b, w, h;
_actual_display_region->get_region_pixels(l, b, w, h); _actual_display_region->get_region_pixels(l, b, w, h);
_viewport_width = w;
_viewport_height = h;
GLint x = GLint(l); GLint x = GLint(l);
GLint y = GLint(b); GLint y = GLint(b);
GLsizei width = GLsizei(w); GLsizei width = GLsizei(w);
@ -984,8 +984,6 @@ prepare_display_region() {
enable_scissor(true); enable_scissor(true);
GLP(Scissor)(x, y, width, height); GLP(Scissor)(x, y, width, height);
GLP(Viewport)(x, y, width, height); GLP(Viewport)(x, y, width, height);
_viewport_width = width;
_viewport_height = height;
} }
report_my_gl_errors(); report_my_gl_errors();

View File

@ -54,7 +54,8 @@ munge_geom(GraphicsStateGuardianBase *gsg,
int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering()); int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering());
GraphicsStateGuardianBase *gsg = traverser->get_gsg(); GraphicsStateGuardianBase *gsg = traverser->get_gsg();
if ((geom_rendering & ~gsg->get_supported_geom_rendering() & qpGeom::GR_point_bits) != 0) { int unsupported_bits = geom_rendering & ~gsg->get_supported_geom_rendering();
if ((unsupported_bits & qpGeom::GR_point_bits) != 0) {
// The GSG doesn't support rendering these fancy points // The GSG doesn't support rendering these fancy points
// directly; we have to render them in software instead. // directly; we have to render them in software instead.
// Munge them into quads. This will replace the _geom and // Munge them into quads. This will replace the _geom and