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();
}
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();
}
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;

View File

@ -55,6 +55,8 @@
#include "qpgeomTristrips.h"
#include "qpgeomTrifans.h"
#include "qpgeomLines.h"
#include "qpgeomLinestrips.h"
#include "qpgeomPoints.h"
#include "qpGeomVertexReader.h"
#include "dxGeomMunger8.h"
#include "config_gobj.h"
@ -223,7 +225,13 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
// they copy framebuffer-to-texture. Ok.
_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 =
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_flat_first_vertex;
}
@ -401,8 +409,7 @@ dx_init(void) {
_fog_enabled = false;
_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, _fog_enabled);
_current_projection_mat = LMatrix4f::ident_mat();
_projection_mat_stack_count = 0;
_projection_mat = LMatrix4f::ident_mat();
_has_scene_graph_color = false;
// Apply a default material when materials are turned off.
@ -663,6 +670,7 @@ prepare_display_region() {
if (_current_display_region == (DisplayRegion*)0L) {
dxgsg8_cat.error()
<< "Invalid NULL display region in prepare_display_region()\n";
} else if (_current_display_region != _actual_display_region) {
_actual_display_region = _current_display_region;
@ -719,7 +727,7 @@ prepare_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,
// 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, 1);
LMatrix4f new_projection_mat =
convert_mat * projection_mat * rescale_mat;
_projection_mat = convert_mat * lens_mat * rescale_mat;
if (_scene_setup->get_inverted()) {
// If the scene is supposed to be inverted, then invert the
// projection matrix.
static LMatrix4f invert_mat = LMatrix4f::scale_mat(1.0f, -1.0f, 1.0f);
new_projection_mat *= invert_mat;
_projection_mat *= invert_mat;
}
HRESULT hr =
_pD3DDevice->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)new_projection_mat.get_data());
(D3DMATRIX*)_projection_mat.get_data());
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()
// Access: Public, Virtual
@ -3887,47 +3936,23 @@ issue_tex_matrix(const TexMatrixAttrib *attrib) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
issue_tex_gen(const TexGenAttrib *attrib) {
/*
* Automatically generate texture coordinates for stage 0.
* Use the wrap mode from the texture coordinate set at index 1.
*/
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
if (attrib->is_empty()) {
TexGenAttrib::Mode mode = attrib->get_mode(TextureStage::get_default());
switch (mode) {
case TexGenAttrib::M_off:
_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
_pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
break;
//enable_texturing(false);
// reset the texcoordindex lookup to 0
//_pD3DDevice->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *)dm.get_data());
//_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
_pD3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);
case TexGenAttrib::M_eye_sphere_map:
_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
_pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
break;
} else if (attrib->get_mode(TextureStage::get_default()) == TexGenAttrib::M_eye_sphere_map) {
#if 0
// best reflection on a sphere is achieved by camera space normals in directx
_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);
case TexGenAttrib::M_point_sprite:
_pD3DDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
_pD3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
break;
}
}
@ -4015,6 +4040,27 @@ issue_render_mode(const RenderModeAttrib *attrib) {
<< "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;
}

View File

@ -100,6 +100,8 @@ public:
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void draw_trifans(const qpGeomTrifans *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 TextureContext *prepare_texture(Texture *tex);
@ -326,8 +328,8 @@ protected:
D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter;
DWORD _CurTexAnisoDegree;
Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV;
LMatrix4f _current_projection_mat;
int _projection_mat_stack_count;
LMatrix4f _projection_mat;
CPT(DisplayRegion) _actual_display_region;
const DXVertexBufferContext8 *_active_vbuffer;

View File

@ -371,6 +371,7 @@ reset() {
report_extensions();
_supported_geom_rendering =
qpGeom::GR_indexed_point |
qpGeom::GR_point | qpGeom::GR_point_uniform_size |
qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
qpGeom::GR_flat_last_vertex;
@ -520,9 +521,6 @@ reset() {
_supports_cube_map =
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 =
has_extension("GL_EXT_bgra") || is_at_least_version(1, 2);
_supports_rescale_normal =
@ -976,6 +974,8 @@ prepare_display_region() {
int 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 y = GLint(b);
GLsizei width = GLsizei(w);
@ -984,8 +984,6 @@ prepare_display_region() {
enable_scissor(true);
GLP(Scissor)(x, y, width, height);
GLP(Viewport)(x, y, width, height);
_viewport_width = width;
_viewport_height = height;
}
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());
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
// directly; we have to render them in software instead.
// Munge them into quads. This will replace the _geom and