mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
move rotate and decompose operations into cull
This commit is contained in:
parent
541bbe4403
commit
2434300804
@ -122,7 +122,7 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
_supports_generate_mipmap = false;
|
||||
_supports_render_texture = false;
|
||||
|
||||
_supported_point_rendering = 0;
|
||||
_supported_geom_rendering = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -153,20 +153,20 @@ get_supports_multisample() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_supported_point_rendering
|
||||
// Function: GraphicsStateGuardian::get_supported_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the union of Geom::PointRendering values that
|
||||
// this particular GSG can support directly. If a point
|
||||
// Description: Returns the union of Geom::GeomRendering values that
|
||||
// this particular GSG can support directly. If a Geom
|
||||
// needs to be rendered that requires some additional
|
||||
// properties, the StandardMunger will convert it into
|
||||
// quads instead.
|
||||
// properties, the StandardMunger and/or the
|
||||
// CullableObject will convert it as needed.
|
||||
//
|
||||
// This method is declared virtual solely so that it can
|
||||
// be queried from cullableObject.cxx.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsStateGuardian::
|
||||
get_supported_point_rendering() const {
|
||||
return _supported_point_rendering;
|
||||
get_supported_geom_rendering() const {
|
||||
return _supported_geom_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -723,10 +723,6 @@ draw_triangles(const qpGeomTriangles *) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
CPT(qpGeomPrimitive) new_prim = primitive->decompose();
|
||||
if (!new_prim->is_of_type(qpGeomTristrips::get_class_type())) {
|
||||
new_prim->draw(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -736,10 +732,6 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_trifans(const qpGeomTrifans *primitive) {
|
||||
CPT(qpGeomPrimitive) new_prim = primitive->decompose();
|
||||
if (!new_prim->is_of_type(qpGeomTrifans::get_class_type())) {
|
||||
new_prim->draw(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -758,10 +750,6 @@ draw_lines(const qpGeomLines *) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_linestrips(const qpGeomLinestrips *primitive) {
|
||||
CPT(qpGeomPrimitive) new_prim = primitive->decompose();
|
||||
if (!new_prim->is_of_type(qpGeomLinestrips::get_class_type())) {
|
||||
new_prim->draw(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -96,7 +96,7 @@ PUBLISHED:
|
||||
INLINE bool get_supports_generate_mipmap() const;
|
||||
INLINE bool get_supports_render_texture() const;
|
||||
|
||||
virtual int get_supported_point_rendering() const;
|
||||
virtual int get_supported_geom_rendering() const;
|
||||
|
||||
public:
|
||||
INLINE bool set_scene(SceneSetup *scene_setup);
|
||||
@ -326,7 +326,7 @@ protected:
|
||||
bool _supports_multisample;
|
||||
bool _supports_generate_mipmap;
|
||||
bool _supports_render_texture;
|
||||
int _supported_point_rendering;
|
||||
int _supported_geom_rendering;
|
||||
|
||||
public:
|
||||
// Statistics
|
||||
|
@ -133,6 +133,41 @@ munge_data_impl(const qpGeomVertexData *data) {
|
||||
return new_data->convert_to(new_format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StandardMunger::munge_geom_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Converts a Geom and/or its data as necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool StandardMunger::
|
||||
munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &vertex_data) {
|
||||
int geom_rendering = geom->get_geom_rendering();
|
||||
int supported_geom_rendering = _gsg->get_supported_geom_rendering();
|
||||
|
||||
int unsupported_bits = geom_rendering & ~supported_geom_rendering;
|
||||
|
||||
if (unsupported_bits != 0) {
|
||||
// Even beyond munging the vertex format, we have to convert the
|
||||
// Geom itself into a new primitive type the GSG can render
|
||||
// directly.
|
||||
if ((unsupported_bits & qpGeom::GR_composite_bits) != 0) {
|
||||
// This decomposes everything in the primitive, so that if (for
|
||||
// instance) the primitive contained both strips and fans, but
|
||||
// the GSG didn't support fans, it would decompose the strips
|
||||
// too. To handle this correctly, we'd need a separate
|
||||
// decompose_fans() and decompose_strips() call; but for now,
|
||||
// we'll just say it's good enough. In practice, we don't have
|
||||
// any GSG's that can support strips without also supporting
|
||||
// fans.
|
||||
geom = geom->decompose();
|
||||
}
|
||||
if ((unsupported_bits & qpGeom::GR_shade_model_bits) != 0) {
|
||||
geom = geom->rotate();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StandardMunger::compare_to_impl
|
||||
// Access: Protected, Virtual
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
protected:
|
||||
virtual CPT(qpGeomVertexData) munge_data_impl(const qpGeomVertexData *data);
|
||||
virtual int compare_to_impl(const qpGeomMunger *other) const;
|
||||
virtual bool munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
|
||||
virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
|
||||
|
||||
private:
|
||||
|
@ -35,12 +35,6 @@ NotifyCategoryDef(wdxdisplay7, "windisplay");
|
||||
ConfigVariableBool dx_full_screen
|
||||
("dx-full-screen", false);
|
||||
|
||||
// Configure this true to force the rendering to sync to the video
|
||||
// refresh, or false to let your frame rate go as high as it can,
|
||||
// irrespective of the video refresh.
|
||||
ConfigVariableBool dx_sync_video
|
||||
("sync-video", true);
|
||||
|
||||
// enable this to turn on full-screen anti-aliasing, if the HW supports it
|
||||
// this var is also used in wdxGraphicsWindows.cxx
|
||||
ConfigVariableBool dx_full_screen_antialiasing
|
||||
|
@ -29,7 +29,6 @@ NotifyCategoryDecl(dxgsg7, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
NotifyCategoryDecl(wdxdisplay7, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
|
||||
extern ConfigVariableBool dx_full_screen;
|
||||
extern ConfigVariableBool dx_sync_video;
|
||||
extern ConfigVariableBool dx_no_vertex_fog;
|
||||
extern ConfigVariableBool dx_full_screen_antialiasing;
|
||||
extern ConfigVariableBool dx_use_rangebased_fog;
|
||||
|
@ -4968,7 +4968,7 @@ void DXGraphicsStateGuardian7::show_full_screen_frame(void) {
|
||||
// Normally, we can just do the fast flip operation.
|
||||
DWORD dwFlipFlags = DDFLIP_WAIT;
|
||||
|
||||
if (!dx_sync_video) {
|
||||
if (!sync_video) {
|
||||
// If the user indicated via Config that we shouldn't wait for
|
||||
// video sync, then don't wait (if the hardware supports this).
|
||||
// This will introduce visible artifacts like tearing, and may
|
||||
@ -5008,7 +5008,7 @@ void DXGraphicsStateGuardian7::show_windowed_frame(void) {
|
||||
|
||||
DX_DECLARE_CLEAN(DDBLTFX, bltfx);
|
||||
|
||||
if (dx_sync_video) {
|
||||
if (sync_video) {
|
||||
// Wait for the video refresh *before* we blt the rendered image
|
||||
// onto the window. This will (a) prevent the "tearing" of the
|
||||
// image that would occur if only part of the image happened to be
|
||||
@ -5029,7 +5029,7 @@ void DXGraphicsStateGuardian7::show_windowed_frame(void) {
|
||||
|
||||
hr = _pScrn->pddsPrimary->Blt( &_pScrn->view_rect, _pScrn->pddsBack, NULL, DDBLT_DDFX | DDBLT_WAIT, &bltfx );
|
||||
|
||||
if (dx_sync_video) {
|
||||
if (sync_video) {
|
||||
HRESULT hr = _pScrn->pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
|
||||
if(hr != DD_OK) {
|
||||
dxgsg7_cat.error() << "WaitForVerticalBlank() failed : " << ConvD3DErrorToString(hr) << endl;
|
||||
|
@ -40,12 +40,6 @@ NotifyCategoryDef(wdxdisplay8, "windisplay");
|
||||
ConfigVariableBool dx_show_transforms
|
||||
("dx-show-transforms", false);
|
||||
|
||||
// Configure this true to force the rendering to sync to the video
|
||||
// refresh, or false to let your frame rate go as high as it can,
|
||||
// irrespective of the video refresh.
|
||||
ConfigVariableBool dx_sync_video
|
||||
("sync-video", true);
|
||||
|
||||
// Set Level of MultiSampling to be used, if HW supports it. Valid values are 2-16.
|
||||
ConfigVariableInt dx_multisample_antialiasing_level
|
||||
("dx-multisample-antialiasing-level", 0);
|
||||
|
@ -29,7 +29,6 @@
|
||||
NotifyCategoryDecl(dxgsg8, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
NotifyCategoryDecl(wdxdisplay8, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
|
||||
extern ConfigVariableBool dx_sync_video;
|
||||
extern ConfigVariableBool dx_no_vertex_fog;
|
||||
extern ConfigVariableBool dx_show_cursor_watermark;
|
||||
extern ConfigVariableBool dx_full_screen_antialiasing;
|
||||
|
@ -190,7 +190,6 @@ DXGraphicsStateGuardian8::
|
||||
DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
|
||||
GraphicsStateGuardian(properties, CS_yup_left)
|
||||
{
|
||||
|
||||
reset_panda_gsg();
|
||||
|
||||
_pScrn = NULL;
|
||||
@ -222,6 +221,10 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
|
||||
// DirectX drivers seem to consistently invert the texture when
|
||||
// they copy framebuffer-to-texture. Ok.
|
||||
_copy_texture_inverted = true;
|
||||
|
||||
_supported_geom_rendering =
|
||||
qpGeom::GR_triangle_strip | qpGeom::GR_triangle_fan |
|
||||
qpGeom::GR_flat_first_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -2749,7 +2752,7 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_flat_first_vertices(),
|
||||
primitive->get_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
@ -2765,8 +2768,6 @@ void DXGraphicsStateGuardian8::
|
||||
draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
int min_vertex = primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
// CPTA_ushort vertices = primitive->get_flat_first_vertices();
|
||||
CPTA_ushort vertices = primitive->get_vertices();
|
||||
|
||||
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
|
||||
// One long triangle strip, connected by the degenerate vertices
|
||||
@ -2779,17 +2780,15 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
|
||||
_pD3DDevice->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_vertices() - 2);
|
||||
|
||||
} else {
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
primitive->get_num_vertices() - 2,
|
||||
vertices, D3DFMT_INDEX16,
|
||||
primitive->get_vertices(), D3DFMT_INDEX16,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
@ -2821,6 +2820,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
} else {
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_ushort vertices = primitive->get_vertices();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@ -2838,6 +2838,59 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::draw_trifans
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_trifans(const qpGeomTrifans *primitive) {
|
||||
int min_vertex = primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
|
||||
// Send the individual triangle fans. There's no connecting fans
|
||||
// with degenerate vertices, so no worries about that.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_ushort mins = primitive->get_mins();
|
||||
CPTA_ushort maxs = primitive->get_maxs();
|
||||
nassertv(mins.size() == ends.size() && maxs.size() == ends.size());
|
||||
|
||||
if (_vbuffer_active) {
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_vertices_trifan_pcollector.add_level(ends[i] - start);
|
||||
_pD3DDevice->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLEFAN,
|
||||
mins[i], maxs[i] - mins[i] + 1,
|
||||
start, ends[i] - start - 2);
|
||||
|
||||
start = ends[i] + 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_ushort vertices = primitive->get_vertices();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_vertices_trifan_pcollector.add_level(ends[i] - start);
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLEFAN,
|
||||
mins[i], maxs[i] - mins[i] + 1,
|
||||
ends[i] - start - 2,
|
||||
vertices + start, D3DFMT_INDEX16,
|
||||
array_data, stride);
|
||||
|
||||
start = ends[i] + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::draw_lines
|
||||
// Access: Public, Virtual
|
||||
@ -2863,7 +2916,7 @@ draw_lines(const qpGeomLines *primitive) {
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_flat_first_vertices(),
|
||||
primitive->get_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
const qpGeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const qpGeomTristrips *primitive);
|
||||
virtual void draw_trifans(const qpGeomTrifans *primitive);
|
||||
virtual void draw_lines(const qpGeomLines *primitive);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
|
@ -104,7 +104,7 @@ upload_data() {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(local_pointer, get_data()->get_flat_first_vertices(), data_size);
|
||||
memcpy(local_pointer, get_data()->get_vertices(), data_size);
|
||||
|
||||
_ibuffer->Unlock();
|
||||
}
|
||||
|
@ -683,9 +683,12 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
|
||||
pPresParams->BackBufferFormat = Display.DisplayMode.Format; // dont need dest alpha, so just use adapter format
|
||||
|
||||
if (dx_sync_video && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
|
||||
wdxdisplay8_cat.info() << "HW doesnt support syncing to vertical refresh, ignoring dx_sync_video\n";
|
||||
dx_sync_video=false;
|
||||
bool do_sync = sync_video;
|
||||
|
||||
if (do_sync && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
|
||||
wdxdisplay8_cat.info()
|
||||
<< "HW doesnt support syncing to vertical refresh, ignoring sync-video\n";
|
||||
do_sync = false;
|
||||
}
|
||||
|
||||
// verify the rendertarget fmt one last time
|
||||
@ -779,7 +782,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
|
||||
if (is_fullscreen()) {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame
|
||||
pPresParams->FullScreen_PresentationInterval = (dx_sync_video ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
|
||||
pPresParams->FullScreen_PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
|
||||
pPresParams->FullScreen_RefreshRateInHz = Display.DisplayMode.RefreshRate;
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -831,7 +834,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
pPresParams->FullScreen_PresentationInterval = 0;
|
||||
|
||||
if (dx_multisample_antialiasing_level<2) {
|
||||
if (dx_sync_video) {
|
||||
if (do_sync) {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
|
||||
} else {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT_COPY; does this make any difference?
|
||||
|
@ -37,12 +37,6 @@ NotifyCategoryDef(wdxdisplay9, "windisplay");
|
||||
ConfigVariableBool dx_show_transforms
|
||||
("dx-show-transforms", false);
|
||||
|
||||
// Configure this true to force the rendering to sync to the video
|
||||
// refresh, or false to let your frame rate go as high as it can,
|
||||
// irrespective of the video refresh.
|
||||
ConfigVariableBool dx_sync_video
|
||||
("sync-video", true);
|
||||
|
||||
// Set Level of MultiSampling to be used, if HW supports it. Valid values are 2-16.
|
||||
ConfigVariableInt dx_multisample_antialiasing_level
|
||||
("dx-multisample-antialiasing-level", 0);
|
||||
|
@ -29,7 +29,6 @@
|
||||
NotifyCategoryDecl(dxgsg9, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
NotifyCategoryDecl(wdxdisplay9, EXPCL_PANDADX, EXPTP_PANDADX);
|
||||
|
||||
extern ConfigVariableBool dx_sync_video;
|
||||
extern ConfigVariableBool dx_no_vertex_fog;
|
||||
extern ConfigVariableBool dx_show_cursor_watermark;
|
||||
extern ConfigVariableBool dx_full_screen_antialiasing;
|
||||
|
@ -670,9 +670,12 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
|
||||
pPresParams->BackBufferFormat = Display.DisplayMode.Format; // dont need dest alpha, so just use adapter format
|
||||
|
||||
if (dx_sync_video && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
|
||||
wdxdisplay9_cat.info() << "HW doesnt support syncing to vertical refresh, ignoring dx_sync_video\n";
|
||||
dx_sync_video=false;
|
||||
bool do_sync = sync_video;
|
||||
|
||||
if (do_sync && !(pD3DCaps->Caps & D3DCAPS_READ_SCANLINE)) {
|
||||
wdxdisplay9_cat.info()
|
||||
<< "HW doesnt support syncing to vertical refresh, ignoring sync-video\n";
|
||||
do_sync = false;
|
||||
}
|
||||
|
||||
// verify the rendertarget fmt one last time
|
||||
@ -766,7 +769,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
|
||||
if (is_fullscreen()) {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame
|
||||
pPresParams->PresentationInterval = (dx_sync_video ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
|
||||
pPresParams->PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
|
||||
pPresParams->FullScreen_RefreshRateInHz = Display.DisplayMode.RefreshRate;
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -818,7 +821,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
|
||||
pPresParams->PresentationInterval = 0;
|
||||
|
||||
if (dx_multisample_antialiasing_level<2) {
|
||||
if (dx_sync_video) {
|
||||
if (do_sync) {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
} else {
|
||||
pPresParams->SwapEffect = D3DSWAPEFFECT_DISCARD; //D3DSWAPEFFECT_COPY; does this make any difference?
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -100,6 +100,7 @@ public:
|
||||
virtual void draw_triangles(const qpGeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const qpGeomTristrips *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();
|
||||
|
||||
@ -390,16 +391,24 @@ public:
|
||||
typedef pvector<GLuint> DeletedDisplayLists;
|
||||
DeletedDisplayLists _deleted_display_lists;
|
||||
|
||||
public:
|
||||
static GraphicsStateGuardian *
|
||||
make_GlGraphicsStateGuardian(const FactoryParams ¶ms);
|
||||
static PStatCollector _vertices_display_list_pcollector;
|
||||
|
||||
static TypeHandle get_class_type(void);
|
||||
static void init_type(void);
|
||||
virtual TypeHandle get_type(void) const;
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
static PStatCollector _vertices_display_list_pcollector;
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
|
||||
public:
|
||||
static void init_type() {
|
||||
GraphicsStateGuardian::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "GraphicsStateGuardian",
|
||||
GraphicsStateGuardian::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
@ -31,6 +31,32 @@ get_primitive_type() const {
|
||||
return cdata->_primitive_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_shade_model
|
||||
// Access: Published
|
||||
// Description: Returns the shade model common to all of the
|
||||
// individual GeomPrimitives that have been added to the
|
||||
// geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeom::ShadeModel qpGeom::
|
||||
get_shade_model() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_geom_rendering
|
||||
// Access: Published
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this Geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeom::
|
||||
get_geom_rendering() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_geom_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_usage_hint
|
||||
// Access: Published
|
||||
@ -48,19 +74,6 @@ get_usage_hint() const {
|
||||
return cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_point_rendering
|
||||
// Access: Published
|
||||
// Description: Returns the set of PointRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// the points (if any) represented within this Geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeom::
|
||||
get_point_rendering() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_point_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_vertex_data
|
||||
// Access: Published
|
||||
@ -123,6 +136,34 @@ modify_primitive(int i) {
|
||||
return cdata->_primitives[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::decompose
|
||||
// Access: Published
|
||||
// Description: Decomposes all of the primitives within this Geom,
|
||||
// returning the result. See
|
||||
// GeomPrimitive::decompose().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeom) qpGeom::
|
||||
decompose() const {
|
||||
PT(qpGeom) new_geom = new qpGeom(*this);
|
||||
new_geom->decompose_in_place();
|
||||
return new_geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::rotate
|
||||
// Access: Published
|
||||
// Description: Rotates all of the primitives within this Geom,
|
||||
// returning the result. See
|
||||
// GeomPrimitive::rotate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeom) qpGeom::
|
||||
rotate() const {
|
||||
PT(qpGeom) new_geom = new qpGeom(*this);
|
||||
new_geom->rotate_in_place();
|
||||
return new_geom;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_modified
|
||||
// Access: Published
|
||||
@ -179,7 +220,8 @@ operator < (const CacheEntry &other) const {
|
||||
INLINE qpGeom::CData::
|
||||
CData() :
|
||||
_primitive_type(PT_none),
|
||||
_point_rendering(0),
|
||||
_shade_model(SM_uniform),
|
||||
_geom_rendering(0),
|
||||
_usage_hint(UH_unspecified),
|
||||
_got_usage_hint(false)
|
||||
{
|
||||
@ -195,7 +237,8 @@ CData(const qpGeom::CData ©) :
|
||||
_data(copy._data),
|
||||
_primitives(copy._primitives),
|
||||
_primitive_type(copy._primitive_type),
|
||||
_point_rendering(copy._point_rendering),
|
||||
_shade_model(copy._shade_model),
|
||||
_geom_rendering(copy._geom_rendering),
|
||||
_usage_hint(copy._usage_hint),
|
||||
_got_usage_hint(copy._got_usage_hint),
|
||||
_modified(copy._modified)
|
||||
|
@ -162,7 +162,7 @@ set_vertex_data(const qpGeomVertexData *data) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_data = (qpGeomVertexData *)data;
|
||||
mark_bound_stale();
|
||||
reset_point_rendering(cdata);
|
||||
reset_geom_rendering(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -199,10 +199,9 @@ offset_vertices(const qpGeomVertexData *data, int offset) {
|
||||
#endif
|
||||
}
|
||||
|
||||
cdata->_got_usage_hint = false;
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
mark_bound_stale();
|
||||
reset_point_rendering(cdata);
|
||||
reset_geom_rendering(cdata);
|
||||
|
||||
nassertv(all_is_valid);
|
||||
}
|
||||
@ -225,25 +224,25 @@ set_primitive(int i, const qpGeomPrimitive *primitive) {
|
||||
nassertv(cdata->_primitive_type == PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
if (cdata->_got_usage_hint &&
|
||||
cdata->_primitives[i]->get_usage_hint() != primitive->get_usage_hint()) {
|
||||
if (cdata->_primitives[i]->get_usage_hint() < primitive->get_usage_hint()) {
|
||||
// If we're reducing the usage hint, we might also be reducing
|
||||
// the minimum usage hit.
|
||||
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||
} else { // (cdata->_primitives[i]->get_usage_hint() > primitive->get_usage_hint())
|
||||
// If we're increasing it, we might have to rederive the minimum.
|
||||
if (cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||
cdata->_got_usage_hint = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// They also should have the same fundamental shade model, but
|
||||
// SM_uniform is compatible with anything.
|
||||
nassertv(cdata->_shade_model == SM_uniform ||
|
||||
primitive->get_shade_model() == SM_uniform ||
|
||||
cdata->_shade_model == primitive->get_shade_model());
|
||||
|
||||
cdata->_primitives[i] = (qpGeomPrimitive *)primitive;
|
||||
PrimitiveType new_primitive_type = primitive->get_primitive_type();
|
||||
if (new_primitive_type != cdata->_primitive_type) {
|
||||
cdata->_primitive_type = new_primitive_type;
|
||||
reset_point_rendering(cdata);
|
||||
}
|
||||
ShadeModel new_shade_model = primitive->get_shade_model();
|
||||
if (new_shade_model != cdata->_shade_model &&
|
||||
new_shade_model != SM_uniform) {
|
||||
cdata->_shade_model = new_shade_model;
|
||||
}
|
||||
|
||||
reset_geom_rendering(cdata);
|
||||
cdata->_got_usage_hint = false;
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
@ -267,16 +266,25 @@ add_primitive(const qpGeomPrimitive *primitive) {
|
||||
nassertv(cdata->_primitive_type == PT_none ||
|
||||
cdata->_primitive_type == primitive->get_primitive_type());
|
||||
|
||||
// They also should have the same fundamental shade model, but
|
||||
// SM_uniform is compatible with anything.
|
||||
nassertv(cdata->_shade_model == SM_uniform ||
|
||||
primitive->get_shade_model() == SM_uniform ||
|
||||
cdata->_shade_model == primitive->get_shade_model());
|
||||
|
||||
cdata->_primitives.push_back((qpGeomPrimitive *)primitive);
|
||||
PrimitiveType new_primitive_type = primitive->get_primitive_type();
|
||||
if (new_primitive_type != cdata->_primitive_type) {
|
||||
cdata->_primitive_type = new_primitive_type;
|
||||
reset_point_rendering(cdata);
|
||||
}
|
||||
ShadeModel new_shade_model = primitive->get_shade_model();
|
||||
if (new_shade_model != cdata->_shade_model &&
|
||||
new_shade_model != SM_uniform) {
|
||||
cdata->_shade_model = new_shade_model;
|
||||
}
|
||||
|
||||
if (cdata->_got_usage_hint) {
|
||||
cdata->_usage_hint = min(cdata->_usage_hint, primitive->get_usage_hint());
|
||||
}
|
||||
reset_geom_rendering(cdata);
|
||||
cdata->_got_usage_hint = false;
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
@ -290,17 +298,13 @@ remove_primitive(int i) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||
if (cdata->_got_usage_hint &&
|
||||
cdata->_usage_hint == cdata->_primitives[i]->get_usage_hint()) {
|
||||
// Maybe we're raising the minimum usage_hint; we have to rederive
|
||||
// the usage_hint later.
|
||||
cdata->_got_usage_hint = false;
|
||||
}
|
||||
cdata->_primitives.erase(cdata->_primitives.begin() + i);
|
||||
if (cdata->_primitives.empty()) {
|
||||
cdata->_primitive_type = PT_none;
|
||||
reset_point_rendering(cdata);
|
||||
cdata->_shade_model = SM_uniform;
|
||||
}
|
||||
reset_geom_rendering(cdata);
|
||||
cdata->_got_usage_hint = false;
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
@ -318,7 +322,73 @@ clear_primitives() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_primitives.clear();
|
||||
cdata->_primitive_type = PT_none;
|
||||
reset_point_rendering(cdata);
|
||||
cdata->_shade_model = SM_uniform;
|
||||
reset_geom_rendering(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::decompose_in_place
|
||||
// Access: Published
|
||||
// Description: Decomposes all of the primitives within this Geom,
|
||||
// leaving the results in place. See
|
||||
// GeomPrimitive::decompose().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
decompose_in_place() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool all_is_valid = true;
|
||||
#endif
|
||||
Primitives::iterator pi;
|
||||
for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) {
|
||||
CPT(qpGeomPrimitive) new_prim = (*pi)->decompose();
|
||||
(*pi) = (qpGeomPrimitive *)new_prim.p();
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (!(*pi)->check_valid(cdata->_data)) {
|
||||
all_is_valid = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
reset_geom_rendering(cdata);
|
||||
|
||||
nassertv(all_is_valid);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::rotate_in_place
|
||||
// Access: Published
|
||||
// Description: Rotates all of the primitives within this Geom,
|
||||
// leaving the results in place. See
|
||||
// GeomPrimitive::rotate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
rotate_in_place() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool all_is_valid = true;
|
||||
#endif
|
||||
Primitives::iterator pi;
|
||||
for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) {
|
||||
CPT(qpGeomPrimitive) new_prim = (*pi)->rotate();
|
||||
(*pi) = (qpGeomPrimitive *)new_prim.p();
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (!(*pi)->check_valid(cdata->_data)) {
|
||||
all_is_valid = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
|
||||
nassertv(all_is_valid);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -712,26 +782,44 @@ reset_usage_hint(qpGeom::CDWriter &cdata) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::reset_point_rendering
|
||||
// Function: qpGeom::reset_geom_rendering
|
||||
// Access: Private
|
||||
// Description: Rederives the _point_rendering member.
|
||||
// Description: Rederives the _geom_rendering member.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
reset_point_rendering(qpGeom::CDWriter &cdata) {
|
||||
cdata->_point_rendering = 0;
|
||||
if (cdata->_primitive_type == PT_points) {
|
||||
cdata->_point_rendering |= PR_point;
|
||||
reset_geom_rendering(qpGeom::CDWriter &cdata) {
|
||||
cdata->_geom_rendering = 0;
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
cdata->_geom_rendering |= (*pi)->get_geom_rendering();
|
||||
}
|
||||
|
||||
if ((cdata->_geom_rendering & GR_point) != 0) {
|
||||
if (cdata->_data->has_column(InternalName::get_size())) {
|
||||
cdata->_point_rendering |= PR_per_point_size;
|
||||
cdata->_geom_rendering |= GR_per_point_size;
|
||||
}
|
||||
if (cdata->_data->has_column(InternalName::get_aspect_ratio())) {
|
||||
cdata->_point_rendering |= PR_aspect_ratio;
|
||||
cdata->_geom_rendering |= GR_point_aspect_ratio;
|
||||
}
|
||||
if (cdata->_data->has_column(InternalName::get_rotate())) {
|
||||
cdata->_point_rendering |= PR_rotate;
|
||||
cdata->_geom_rendering |= GR_point_rotate;
|
||||
}
|
||||
}
|
||||
|
||||
switch (get_shade_model()) {
|
||||
case SM_flat_first_vertex:
|
||||
cdata->_geom_rendering |= GR_flat_first_vertex;
|
||||
break;
|
||||
|
||||
case SM_flat_last_vertex:
|
||||
cdata->_geom_rendering |= GR_flat_last_vertex;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -862,7 +950,8 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
}
|
||||
|
||||
dg.add_uint8(_primitive_type);
|
||||
dg.add_uint16(_point_rendering);
|
||||
dg.add_uint8(_shade_model);
|
||||
dg.add_uint16(_geom_rendering);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -905,7 +994,8 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
||||
_primitive_type = (PrimitiveType)scan.get_uint8();
|
||||
_point_rendering = scan.get_uint16();
|
||||
_shade_model = (ShadeModel)scan.get_uint16();
|
||||
_geom_rendering = scan.get_uint16();
|
||||
_got_usage_hint = false;
|
||||
_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
@ -68,11 +68,12 @@ PUBLISHED:
|
||||
virtual Geom *make_copy() const;
|
||||
|
||||
INLINE PrimitiveType get_primitive_type() const;
|
||||
INLINE ShadeModel get_shade_model() const;
|
||||
INLINE int get_geom_rendering() const;
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
void set_usage_hint(UsageHint usage_hint);
|
||||
|
||||
INLINE int get_point_rendering() const;
|
||||
|
||||
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
||||
PT(qpGeomVertexData) modify_vertex_data();
|
||||
void set_vertex_data(const qpGeomVertexData *data);
|
||||
@ -86,6 +87,12 @@ PUBLISHED:
|
||||
void remove_primitive(int i);
|
||||
void clear_primitives();
|
||||
|
||||
INLINE CPT(qpGeom) decompose() const;
|
||||
INLINE CPT(qpGeom) rotate() const;
|
||||
|
||||
void decompose_in_place();
|
||||
void rotate_in_place();
|
||||
|
||||
int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
@ -160,7 +167,8 @@ private:
|
||||
PT(qpGeomVertexData) _data;
|
||||
Primitives _primitives;
|
||||
PrimitiveType _primitive_type;
|
||||
int _point_rendering;
|
||||
ShadeModel _shade_model;
|
||||
int _geom_rendering;
|
||||
UsageHint _usage_hint;
|
||||
bool _got_usage_hint;
|
||||
UpdateSeq _modified;
|
||||
@ -172,7 +180,7 @@ private:
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
void reset_usage_hint(CDWriter &cdata);
|
||||
void reset_point_rendering(CDWriter &cdata);
|
||||
void reset_geom_rendering(CDWriter &cdata);
|
||||
|
||||
static UpdateSeq _next_modified;
|
||||
|
||||
|
@ -82,48 +82,68 @@ PUBLISHED:
|
||||
UH_unspecified,
|
||||
};
|
||||
|
||||
// This type specifies a number of bits that are used to
|
||||
// representing the rendering capabilities and/or requirements for
|
||||
// fancy points.
|
||||
enum PointRendering {
|
||||
// This type specifies a number of bits that are used to represent
|
||||
// the rendering requirements of a particular Geom, as well as the
|
||||
// rendering capabilities of the GSG. The difference between the
|
||||
// two indicates whether the Geom needs to be munged for the GSG.
|
||||
enum GeomRendering {
|
||||
// If there are any points at all.
|
||||
PR_point = 0x0001,
|
||||
GR_point = 0x0001,
|
||||
|
||||
// If the points are all the same size, other than 1 pixel.
|
||||
PR_uniform_size = 0x0002,
|
||||
GR_point_uniform_size = 0x0002,
|
||||
|
||||
// If the points have a per-vertex size designation.
|
||||
PR_per_point_size = 0x0004,
|
||||
GR_per_point_size = 0x0004,
|
||||
|
||||
// If the points' size is specified in camera units rather than
|
||||
// screen pixels.
|
||||
PR_perspective = 0x0008,
|
||||
GR_point_perspective = 0x0008,
|
||||
|
||||
// If the points have a non-square aspect ratio.
|
||||
PR_aspect_ratio = 0x0010,
|
||||
GR_point_aspect_ratio = 0x0010,
|
||||
|
||||
// If the points are rotated off the orthonormal axis.
|
||||
PR_rotate = 0x0020,
|
||||
GR_point_rotate = 0x0020,
|
||||
|
||||
// If the points require texture coordinates interpolated across
|
||||
// their face, to render textures as sprites.
|
||||
PR_sprite = 0x0040,
|
||||
GR_point_sprite = 0x0040,
|
||||
|
||||
// The union of all the above point attributes.
|
||||
GR_point_bits = 0x007f,
|
||||
|
||||
// If there are any of these composite types.
|
||||
GR_triangle_strip = 0x0080,
|
||||
GR_triangle_fan = 0x0100,
|
||||
GR_line_strip = 0x0200,
|
||||
|
||||
// The union of all of the above composite types.
|
||||
GR_composite_bits = 0x0380,
|
||||
|
||||
// If the shade model requires a particular vertex for flat shading.
|
||||
GR_flat_first_vertex = 0x0400,
|
||||
GR_flat_last_vertex = 0x0800,
|
||||
|
||||
// The union of the above shade model types.
|
||||
GR_shade_model_bits = 0x0c00,
|
||||
};
|
||||
|
||||
// The shade model controls whether colors and/or lighting effects
|
||||
// are smoothly interpolated across the face of a triangle, or
|
||||
// uniform for the entire triangle.
|
||||
// The shade model specifies whether the per-vertex colors and
|
||||
// normals indexed by a given primitive truly represent per-vertex
|
||||
// colors and normals, or whether they actually represent
|
||||
// per-triangle flat-shaded colors and normals.
|
||||
enum ShadeModel {
|
||||
// SM_smooth: vertices within a single face have different
|
||||
// colors/normals that should be smoothed across the face. This
|
||||
// primitive should be rendered with SmoothModelAttrib::M_smooth.
|
||||
SM_smooth,
|
||||
|
||||
// SM_uniform: all vertices across all faces have the same colors
|
||||
// and normals. It doesn't really matter which ShadeModelAttrib
|
||||
// mode is used to render this primitive.
|
||||
SM_uniform,
|
||||
|
||||
// SM_smooth: vertices within a single face have different
|
||||
// colors/normals that should be smoothed across the face. This
|
||||
// primitive should be rendered with SmoothModelAttrib::M_smooth.
|
||||
SM_smooth,
|
||||
|
||||
// SM_flat_(first,last)_vertex: each face within the primitive
|
||||
// might have a different color/normal than the other faces, but
|
||||
// across a particular face there is only one color/normal. Each
|
||||
|
@ -134,7 +134,7 @@ rotate_impl() const {
|
||||
new_vertices.push_back(vertices[begin]);
|
||||
}
|
||||
|
||||
nassertr(new_vertices.size() == vertices.size(), vertices);
|
||||
nassertr(new_vertices.size() == vertices.size(), CPTA_ushort());
|
||||
return new_vertices;
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,18 @@ get_primitive_type() const {
|
||||
return PT_lines;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLinestrips::get_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomLinestrips::
|
||||
get_geom_rendering() const {
|
||||
return GR_line_strip;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomLinestrips::get_min_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
@ -167,7 +179,7 @@ rotate_impl() const {
|
||||
}
|
||||
begin = end;
|
||||
}
|
||||
nassertr(new_vertices.size() == vertices.size(), vertices);
|
||||
nassertr(new_vertices.size() == vertices.size(), CPTA_ushort());
|
||||
|
||||
return new_vertices;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual PT(qpGeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
|
||||
virtual int get_geom_rendering() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
|
@ -78,6 +78,21 @@ get_primitive_type() const {
|
||||
return PT_points;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPoints::get_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPoints::
|
||||
get_geom_rendering() const {
|
||||
// Fancy point attributes, if any, are based on whether the
|
||||
// appropriate columns are defined in the associated GeomVertexData;
|
||||
// these bits will be added by Geom::get_geom_rendering().
|
||||
return GR_point;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPoints::get_num_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
|
@ -37,6 +37,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual PT(qpGeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
virtual int get_geom_rendering() const;
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
@ -17,6 +17,36 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_shade_model
|
||||
// Access: Published
|
||||
// Description: Returns the ShadeModel hint for this primitive.
|
||||
// This is intended as a hint to the renderer to tell it
|
||||
// how the per-vertex colors and normals are applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomPrimitive::ShadeModel qpGeomPrimitive::
|
||||
get_shade_model() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::set_shade_model
|
||||
// Access: Published
|
||||
// Description: Changes the ShadeModel hint for this primitive.
|
||||
// This is different from the ShadeModelAttrib that
|
||||
// might also be applied from the scene graph. This
|
||||
// does not affect the shade model that is in effect
|
||||
// when rendering, but rather serves as a hint to the
|
||||
// renderer to tell it how the per-vertex colors and
|
||||
// normals on this primitive are applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomPrimitive::
|
||||
set_shade_model(qpGeomPrimitive::ShadeModel shade_model) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_shade_model = shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_usage_hint
|
||||
// Access: Published
|
||||
@ -47,42 +77,10 @@ get_usage_hint() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomPrimitive::
|
||||
set_usage_hint(qpGeomPrimitive::UsageHint usage_hint) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_usage_hint = usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_shade_model
|
||||
// Access: Published
|
||||
// Description: Returns the ShadeModel hint for this primitive.
|
||||
// This is intended as a hint to the renderer to tell it
|
||||
// how the per-vertex colors and normals are applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomPrimitive::ShadeModel qpGeomPrimitive::
|
||||
get_shade_model() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::set_shade_model
|
||||
// Access: Published
|
||||
// Description: Changes the ShadeModel hint for this primitive.
|
||||
// This is different from the ShadeModelAttrib that
|
||||
// might also be applied from the scene graph. This
|
||||
// does not affect the shade model that is in effect
|
||||
// when rendering, but rather serves as a hint to the
|
||||
// renderer to tell it how the per-vertex colors and
|
||||
// normals on this primitive are applied.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomPrimitive::
|
||||
set_shade_model(qpGeomPrimitive::ShadeModel shade_model) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_shade_model = shade_model;
|
||||
cdata->_rotated_vertices.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_num_vertices
|
||||
// Access: Published
|
||||
@ -246,64 +244,6 @@ get_vertices() const {
|
||||
return cdata->_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_flat_first_vertices
|
||||
// Access: Public
|
||||
// Description: Returns a const pointer to the vertex index array,
|
||||
// suitable for traversing for a renderer that expects
|
||||
// the key vertex of each triangle in a flat-shaded
|
||||
// model to be the triangle's first vertex (as DirectX
|
||||
// does).
|
||||
//
|
||||
// The result of this is dependent on the value
|
||||
// specified to set_shade_model(). If the shade model
|
||||
// indicates flat_last_vertex, this will return the
|
||||
// vertices rotated to bring them into first_vertex
|
||||
// compliance; otherwise, it will be the unmodified
|
||||
// result from get_vertices().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_ushort qpGeomPrimitive::
|
||||
get_flat_first_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_shade_model == SM_flat_last_vertex) {
|
||||
if (cdata->_rotated_vertices == (const ushort *)NULL) {
|
||||
return ((qpGeomPrimitive *)this)->do_rotate(cdata);
|
||||
}
|
||||
return cdata->_rotated_vertices;
|
||||
} else {
|
||||
return cdata->_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_flat_last_vertices
|
||||
// Access: Public
|
||||
// Description: Returns a const pointer to the vertex index array,
|
||||
// suitable for traversing for a renderer that expects
|
||||
// the key vertex of each triangle in a flat-shaded
|
||||
// model to be the triangle's last vertex (as OpenGL
|
||||
// does).
|
||||
//
|
||||
// The result of this is dependent on the value
|
||||
// specified to set_shade_model(). If the shade model
|
||||
// indicates flat_first_vertex, this will return the
|
||||
// vertices rotated to bring them into last_vertex
|
||||
// compliance; otherwise, it will be the unmodified
|
||||
// result from get_vertices().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_ushort qpGeomPrimitive::
|
||||
get_flat_last_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_shade_model == SM_flat_first_vertex) {
|
||||
if (cdata->_rotated_vertices == (const ushort *)NULL) {
|
||||
return ((qpGeomPrimitive *)this)->do_rotate(cdata);
|
||||
}
|
||||
return cdata->_rotated_vertices;
|
||||
} else {
|
||||
return cdata->_vertices;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_ends
|
||||
// Access: Public
|
||||
@ -391,7 +331,6 @@ CData(const qpGeomPrimitive::CData ©) :
|
||||
_usage_hint(copy._usage_hint),
|
||||
_shade_model(copy._shade_model),
|
||||
_vertices(copy._vertices),
|
||||
_rotated_vertices(copy._rotated_vertices),
|
||||
_ends(copy._ends),
|
||||
_mins(copy._mins),
|
||||
_maxs(copy._maxs),
|
||||
|
@ -30,7 +30,8 @@
|
||||
|
||||
TypeHandle qpGeomPrimitive::_type_handle;
|
||||
|
||||
PStatCollector qpGeomPrimitive::_rotate_pcollector("Draw:Rotate");
|
||||
PStatCollector qpGeomPrimitive::_decompose_pcollector("Cull:Munge:Decompose");
|
||||
PStatCollector qpGeomPrimitive::_rotate_pcollector("Cull:Munge:Rotate");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::Constructor
|
||||
@ -61,22 +62,20 @@ qpGeomPrimitive(const qpGeomPrimitive ©) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomPrimitive::
|
||||
~qpGeomPrimitive() {
|
||||
// When we destruct, we should ensure that all of our cached
|
||||
// entries, across all pipeline stages, are properly removed from
|
||||
// the cache manager.
|
||||
int num_stages = _cycler.get_num_stages();
|
||||
for (int i = 0; i < num_stages; i++) {
|
||||
if (_cycler.is_stage_unique(i)) {
|
||||
CData *cdata = _cycler.write_stage(i);
|
||||
if (cdata->_cache != (CacheEntry *)NULL) {
|
||||
cdata->_cache->erase();
|
||||
cdata->_cache = NULL;
|
||||
}
|
||||
_cycler.release_write_stage(i, cdata);
|
||||
}
|
||||
release_all();
|
||||
}
|
||||
|
||||
release_all();
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_geom_rendering() const {
|
||||
// The default is nothing fancy.
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -94,7 +93,6 @@ add_vertex(int vertex) {
|
||||
unsigned short short_vertex = vertex;
|
||||
nassertv((int)short_vertex == vertex);
|
||||
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
int num_primitives = get_num_primitives();
|
||||
@ -106,7 +104,6 @@ add_vertex(int vertex) {
|
||||
}
|
||||
|
||||
cdata->_vertices.push_back(short_vertex);
|
||||
cdata->_rotated_vertices.clear();
|
||||
|
||||
if (cdata->_got_minmax) {
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, short_vertex);
|
||||
@ -139,7 +136,6 @@ add_consecutive_vertices(int start, int num_vertices) {
|
||||
if (num_vertices == 0) {
|
||||
return;
|
||||
}
|
||||
clear_cache();
|
||||
int end = (start + num_vertices) - 1;
|
||||
unsigned short short_start = start;
|
||||
unsigned short short_end = end;
|
||||
@ -158,7 +154,6 @@ add_consecutive_vertices(int start, int num_vertices) {
|
||||
for (unsigned short v = short_start; v <= short_end; ++v) {
|
||||
cdata->_vertices.push_back(v);
|
||||
}
|
||||
cdata->_rotated_vertices.clear();
|
||||
|
||||
if (cdata->_got_minmax) {
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, short_start);
|
||||
@ -210,7 +205,6 @@ add_next_vertices(int num_vertices) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomPrimitive::
|
||||
close_primitive() {
|
||||
clear_cache();
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
@ -262,10 +256,8 @@ close_primitive() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
clear_vertices() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices.clear();
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_ends.clear();
|
||||
cdata->_mins.clear();
|
||||
cdata->_maxs.clear();
|
||||
@ -280,10 +272,8 @@ clear_vertices() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
offset_vertices(int offset) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_mins.clear();
|
||||
cdata->_maxs.clear();
|
||||
cdata->_got_minmax = false;
|
||||
@ -427,49 +417,44 @@ get_primitive_num_vertices(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomPrimitive) qpGeomPrimitive::
|
||||
decompose() const {
|
||||
CPT(qpGeomPrimitive) result;
|
||||
{
|
||||
// Use read() and release_read() instead of CDReader, because the
|
||||
// call to record_primitive() might recursively call back into
|
||||
// this object, and require a write.
|
||||
const CData *cdata = _cycler.read();
|
||||
if (cdata->_cache != (CacheEntry *)NULL) {
|
||||
result = cdata->_cache->_decomposed;
|
||||
_cycler.release_read(cdata);
|
||||
// Record a cache hit, so this element will stay in the cache a
|
||||
// while longer.
|
||||
cdata->_cache->refresh();
|
||||
|
||||
return result;
|
||||
}
|
||||
_cycler.release_read(cdata);
|
||||
}
|
||||
|
||||
result = decompose_impl();
|
||||
if (result.p() == this || result.p() == NULL) {
|
||||
// decomposing this primitive has no effect or cannot be done.
|
||||
return this;
|
||||
}
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Decomposing " << get_type() << ": " << (void *)this << "\n";
|
||||
}
|
||||
|
||||
// Record the result for the future.
|
||||
CacheEntry *entry;
|
||||
{
|
||||
CDWriter cdata(((qpGeomPrimitive *)this)->_cycler);
|
||||
entry = new CacheEntry;
|
||||
entry->_source = (qpGeomPrimitive *)this;
|
||||
entry->_decomposed = result;
|
||||
cdata->_cache = entry;
|
||||
PStatTimer timer(_decompose_pcollector);
|
||||
return decompose_impl();
|
||||
}
|
||||
|
||||
// And add *this* object to the cache manager.
|
||||
entry->record();
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::rotate
|
||||
// Access: Published
|
||||
// Description: Returns a new primitive with the shade_model reversed
|
||||
// (if it is flat shaded).
|
||||
//
|
||||
// If the current shade_model indicates
|
||||
// flat_vertex_last, this should bring the last vertex
|
||||
// to the first position; if it indicates
|
||||
// flat_vertex_first, this should bring the first vertex
|
||||
// to the last position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomPrimitive) qpGeomPrimitive::
|
||||
rotate() const {
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Rotating " << get_type() << ": " << (void *)this << "\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
PStatTimer timer(_rotate_pcollector);
|
||||
CPTA_ushort rotated_vertices = rotate_impl();
|
||||
|
||||
if (rotated_vertices.is_null()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
PT(qpGeomPrimitive) new_prim = make_copy();
|
||||
new_prim->set_vertices(rotated_vertices);
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -554,9 +539,7 @@ write(ostream &out, int indent_level) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_ushort qpGeomPrimitive::
|
||||
modify_vertices() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_got_minmax = false;
|
||||
return cdata->_vertices;
|
||||
}
|
||||
@ -570,10 +553,8 @@ modify_vertices() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_vertices(CPTA_ushort vertices) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices = (PTA_ushort &)vertices;
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_got_minmax = false;
|
||||
}
|
||||
|
||||
@ -591,9 +572,7 @@ set_vertices(CPTA_ushort vertices) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_int qpGeomPrimitive::
|
||||
modify_ends() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_got_minmax = false;
|
||||
return cdata->_ends;
|
||||
}
|
||||
@ -612,10 +591,8 @@ modify_ends() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_ends(CPTA_int ends) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_ends = (PTA_int &)ends;
|
||||
cdata->_rotated_vertices.clear();
|
||||
cdata->_got_minmax = false;
|
||||
}
|
||||
|
||||
@ -660,28 +637,6 @@ get_num_unused_vertices_per_primitive() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::clear_cache
|
||||
// Access: Public
|
||||
// Description: Removes all of the previously-cached results of
|
||||
// decompose().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
clear_cache() {
|
||||
// Probably we shouldn't do anything at all here unless we are
|
||||
// running in pipeline stage 0.
|
||||
CData *cdata = CDWriter(_cycler);
|
||||
if (cdata->_cache != (CacheEntry *)NULL) {
|
||||
cdata->_cache->erase();
|
||||
cdata->_cache = NULL;
|
||||
}
|
||||
|
||||
// This, on the other hand, should be applied to the current
|
||||
// pipeline stage.
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::prepare
|
||||
// Access: Public
|
||||
@ -892,13 +847,13 @@ decompose_impl() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::rotate_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: The virtual implementation of do_rotate().
|
||||
// Description: The virtual implementation of rotate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPTA_ushort qpGeomPrimitive::
|
||||
rotate_impl() const {
|
||||
// The default implementation doesn't even try to do anything.
|
||||
nassertr(false, get_vertices());
|
||||
return get_vertices();
|
||||
nassertr(false, CPTA_ushort());
|
||||
return CPTA_ushort();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -914,34 +869,6 @@ void qpGeomPrimitive::
|
||||
append_unused_vertices(PTA_ushort &, int) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::do_rotate
|
||||
// Access: Private
|
||||
// Description: Fills _rotated_vertices by rotating the individual
|
||||
// primitives to bring each flat-colored vertex to the
|
||||
// opposite position. If the current shade_model
|
||||
// indicates flat_vertex_last, this should bring the
|
||||
// last vertex to the first position; if it indicates
|
||||
// flat_vertex_first, this should bring the first vertex
|
||||
// to the last position. This is used internally to
|
||||
// implement get_flat_first_vertices() and
|
||||
// get_flat_last_vertices().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPTA_ushort qpGeomPrimitive::
|
||||
do_rotate(qpGeomPrimitive::CDReader &cdata) {
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Rotating " << get_type() << ": " << (void *)this << "\n";
|
||||
}
|
||||
|
||||
PStatTimer timer(_rotate_pcollector);
|
||||
CPTA_ushort rotated_vertices = rotate_impl();
|
||||
|
||||
CDWriter cdataw(_cycler, cdata);
|
||||
cdataw->_rotated_vertices = rotated_vertices;
|
||||
return rotated_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::recompute_minmax
|
||||
// Access: Private
|
||||
@ -1041,46 +968,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CacheEntry::evict_callback
|
||||
// Access: Public, Virtual
|
||||
// Description: Called when the entry is evicted from the cache, this
|
||||
// should clean up the owning object appropriately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::CacheEntry::
|
||||
evict_callback() {
|
||||
// We have to operate on stage 0 of the pipeline, since that's where
|
||||
// the cache really counts. Because of the multistage pipeline, we
|
||||
// might not actually have a cache entry there (it might have been
|
||||
// added to stage 1 instead). No big deal if we don't.
|
||||
CData *cdata = _source->_cycler.write_stage(0);
|
||||
if (cdata->_cache.p() == this) {
|
||||
cdata->_cache = NULL;
|
||||
}
|
||||
_source->_cycler.release_write_stage(0, cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CacheEntry::get_result_size
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the approximate number of bytes represented
|
||||
// by the computed result.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::CacheEntry::
|
||||
get_result_size() const {
|
||||
return _decomposed->get_num_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CacheEntry::output
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::CacheEntry::
|
||||
output(ostream &out) const {
|
||||
out << "primitive " << (void *)_source;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomEnums.h"
|
||||
#include "qpgeomCacheEntry.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "luse.h"
|
||||
#include "updateSeq.h"
|
||||
@ -72,13 +71,14 @@ PUBLISHED:
|
||||
virtual PT(qpGeomPrimitive) make_copy() const=0;
|
||||
|
||||
virtual PrimitiveType get_primitive_type() const=0;
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE void set_usage_hint(UsageHint usage_hint);
|
||||
virtual int get_geom_rendering() const;
|
||||
|
||||
INLINE ShadeModel get_shade_model() const;
|
||||
INLINE void set_shade_model(ShadeModel shade_model);
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE void set_usage_hint(UsageHint usage_hint);
|
||||
|
||||
// The following published methods are provided for safe, high-level
|
||||
// iteration through the vertices and sub-primitives within the
|
||||
// GeomPrimitive class. These work correctly regardless of the
|
||||
@ -109,6 +109,7 @@ PUBLISHED:
|
||||
INLINE int get_primitive_max_vertex(int n) const;
|
||||
|
||||
CPT(qpGeomPrimitive) decompose() const;
|
||||
CPT(qpGeomPrimitive) rotate() const;
|
||||
|
||||
int get_num_bytes() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
@ -131,8 +132,6 @@ public:
|
||||
// instead.
|
||||
|
||||
INLINE CPTA_ushort get_vertices() const;
|
||||
INLINE CPTA_ushort get_flat_first_vertices() const;
|
||||
INLINE CPTA_ushort get_flat_last_vertices() const;
|
||||
PTA_ushort modify_vertices();
|
||||
void set_vertices(CPTA_ushort vertices);
|
||||
|
||||
@ -147,7 +146,6 @@ public:
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
virtual int get_num_unused_vertices_per_primitive() const;
|
||||
|
||||
void clear_cache();
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
@ -172,9 +170,6 @@ protected:
|
||||
virtual CPTA_ushort rotate_impl() const;
|
||||
virtual void append_unused_vertices(PTA_ushort &vertices, int vertex);
|
||||
|
||||
protected:
|
||||
static PStatCollector _rotate_pcollector;
|
||||
|
||||
private:
|
||||
// A GeomPrimitive keeps a list (actually, a map) of all the
|
||||
// PreparedGraphicsObjects tables that it has been prepared into.
|
||||
@ -184,16 +179,6 @@ private:
|
||||
typedef pmap<PreparedGraphicsObjects *, IndexBufferContext *> Contexts;
|
||||
Contexts _contexts;
|
||||
|
||||
class CacheEntry : public qpGeomCacheEntry {
|
||||
public:
|
||||
virtual void evict_callback();
|
||||
virtual int get_result_size() const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
qpGeomPrimitive *_source;
|
||||
CPT(qpGeomPrimitive) _decomposed;
|
||||
};
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
@ -206,7 +191,6 @@ private:
|
||||
UsageHint _usage_hint;
|
||||
ShadeModel _shade_model;
|
||||
PTA_ushort _vertices;
|
||||
CPTA_ushort _rotated_vertices;
|
||||
PTA_int _ends;
|
||||
PTA_ushort _mins;
|
||||
PTA_ushort _maxs;
|
||||
@ -215,17 +199,17 @@ private:
|
||||
bool _got_minmax;
|
||||
unsigned short _min_vertex;
|
||||
unsigned short _max_vertex;
|
||||
|
||||
PT(CacheEntry) _cache;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
CPTA_ushort do_rotate(CDReader &cdata);
|
||||
void recompute_minmax(CDWriter &cdata);
|
||||
|
||||
static PStatCollector _decompose_pcollector;
|
||||
static PStatCollector _rotate_pcollector;
|
||||
|
||||
public:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
|
@ -78,6 +78,18 @@ get_primitive_type() const {
|
||||
return PT_polygons;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::get_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomTrifans::
|
||||
get_geom_rendering() const {
|
||||
return GR_triangle_fan;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::draw
|
||||
// Access: Public, Virtual
|
||||
@ -147,8 +159,8 @@ CPTA_ushort qpGeomTrifans::
|
||||
rotate_impl() const {
|
||||
// Actually, we can't rotate fans without chaging the winding order.
|
||||
// It's an error to define a flat shade model for a GeomTrifan.
|
||||
nassertr(false, get_vertices());
|
||||
return get_vertices();
|
||||
nassertr(false, CPTA_ushort());
|
||||
return CPTA_ushort();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -37,6 +37,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual PT(qpGeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
virtual int get_geom_rendering() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
|
@ -79,6 +79,18 @@ get_primitive_type() const {
|
||||
return PT_polygons;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::get_geom_rendering
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the set of GeomRendering bits that represent
|
||||
// the rendering properties required to properly render
|
||||
// this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomTristrips::
|
||||
get_geom_rendering() const {
|
||||
return GR_triangle_strip;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::get_num_unused_vertices_per_primitive
|
||||
// Access: Public, Virtual
|
||||
@ -256,7 +268,7 @@ rotate_impl() const {
|
||||
// If this assertion is triggered, there was a triangle strip with
|
||||
// an odd number of vertices and either SM_flat_first_vertex or
|
||||
// SM_flat_last_vertex specified--which is not allowed.
|
||||
nassertr(!any_odd, new_vertices);
|
||||
nassertr(!any_odd, CPTA_ushort());
|
||||
return new_vertices;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ PUBLISHED:
|
||||
public:
|
||||
virtual PT(qpGeomPrimitive) make_copy() const;
|
||||
virtual PrimitiveType get_primitive_type() const;
|
||||
virtual int get_geom_rendering() const;
|
||||
virtual int get_num_unused_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
|
@ -230,7 +230,6 @@ void qpGeomVertexData::
|
||||
set_array(int i, const qpGeomVertexArrayData *array) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_arrays.size());
|
||||
nassertv(array->get_array_format() == cdata->_arrays[i]->get_array_format());
|
||||
cdata->_arrays[i] = (qpGeomVertexArrayData *)array;
|
||||
cdata->_modified = qpGeom::get_next_modified();
|
||||
cdata->_animated_vertices_modified = UpdateSeq();
|
||||
|
@ -120,7 +120,7 @@ class Lens;
|
||||
class EXPCL_PANDA GraphicsStateGuardianBase : public TypedWritableReferenceCount {
|
||||
public:
|
||||
virtual bool get_supports_multisample() const=0;
|
||||
virtual int get_supported_point_rendering() const=0;
|
||||
virtual int get_supported_geom_rendering() const=0;
|
||||
|
||||
// These functions will be queried by the GeomIssuer to determine if
|
||||
// it should issue normals, texcoords, and/or colors, based on the
|
||||
|
@ -51,10 +51,10 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
||||
CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom);
|
||||
_munged_data = qpgeom->get_vertex_data();
|
||||
|
||||
int point_rendering = _state->get_point_rendering(qpgeom->get_point_rendering());
|
||||
int geom_rendering = _state->get_geom_rendering(qpgeom->get_geom_rendering());
|
||||
|
||||
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
|
||||
if ((point_rendering & ~gsg->get_supported_point_rendering()) != 0) {
|
||||
if ((geom_rendering & ~gsg->get_supported_geom_rendering() & 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
|
||||
|
@ -73,25 +73,25 @@ get_perspective() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderModeAttrib::get_point_rendering
|
||||
// Function: RenderModeAttrib::get_geom_rendering
|
||||
// Access: Published
|
||||
// Description: Returns the union of the Geom::PointRendering bits
|
||||
// Description: Returns the union of the Geom::GeomRendering bits
|
||||
// that will be required once this RenderModeAttrib is
|
||||
// applied to a geom which includes the indicated
|
||||
// geom_point_rendering bits.
|
||||
// geom_rendering bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int RenderModeAttrib::
|
||||
get_point_rendering(int geom_point_rendering) const {
|
||||
get_geom_rendering(int geom_rendering) const {
|
||||
if (_mode == M_point) {
|
||||
geom_point_rendering |= qpGeom::PR_point;
|
||||
geom_rendering |= qpGeom::GR_point;
|
||||
}
|
||||
if ((geom_point_rendering & qpGeom::PR_point) != 0) {
|
||||
if ((geom_rendering & qpGeom::GR_point) != 0) {
|
||||
if (_perspective) {
|
||||
geom_point_rendering |= (qpGeom::PR_perspective | qpGeom::PR_uniform_size);
|
||||
geom_rendering |= (qpGeom::GR_point_perspective | qpGeom::GR_point_uniform_size);
|
||||
} else if (_thickness != 1.0f) {
|
||||
geom_point_rendering |= qpGeom::PR_uniform_size;
|
||||
geom_rendering |= qpGeom::GR_point_uniform_size;
|
||||
}
|
||||
}
|
||||
|
||||
return geom_point_rendering;
|
||||
return geom_rendering;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ PUBLISHED:
|
||||
INLINE float get_thickness() const;
|
||||
INLINE bool get_perspective() const;
|
||||
|
||||
INLINE int get_point_rendering(int geom_point_rendering) const;
|
||||
INLINE int get_geom_rendering(int geom_rendering) const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
|
@ -250,23 +250,23 @@ get_render_mode() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: RenderState::get_point_rendering
|
||||
// Function: RenderState::get_geom_rendering
|
||||
// Access: Published
|
||||
// Description: Returns the union of the Geom::PointRendering bits
|
||||
// Description: Returns the union of the Geom::GeomRendering bits
|
||||
// that will be required once this RenderState is
|
||||
// applied to a geom which includes the indicated
|
||||
// geom_point_rendering bits.
|
||||
// geom_rendering bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int RenderState::
|
||||
get_point_rendering(int geom_point_rendering) const {
|
||||
get_geom_rendering(int geom_rendering) const {
|
||||
if (get_render_mode() != (const RenderModeAttrib *)NULL) {
|
||||
geom_point_rendering = _render_mode->get_point_rendering(geom_point_rendering);
|
||||
geom_rendering = _render_mode->get_geom_rendering(geom_rendering);
|
||||
}
|
||||
if (get_tex_gen() != (const TexGenAttrib *)NULL) {
|
||||
geom_point_rendering = _tex_gen->get_point_rendering(geom_point_rendering);
|
||||
geom_rendering = _tex_gen->get_geom_rendering(geom_rendering);
|
||||
}
|
||||
|
||||
return geom_point_rendering;
|
||||
return geom_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -127,7 +127,7 @@ PUBLISHED:
|
||||
INLINE const TexGenAttrib *get_tex_gen() const;
|
||||
INLINE const RenderModeAttrib *get_render_mode() const;
|
||||
|
||||
INLINE int get_point_rendering(int geom_point_rendering) const;
|
||||
INLINE int get_geom_rendering(int geom_rendering) const;
|
||||
|
||||
public:
|
||||
CPT(RenderState) issue_delta_modify(const RenderState *other,
|
||||
|
@ -44,22 +44,22 @@ TexGenAttrib(const TexGenAttrib ©) :
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexGenAttrib::get_point_rendering
|
||||
// Function: TexGenAttrib::get_geom_rendering
|
||||
// Access: Published
|
||||
// Description: Returns the union of the Geom::PointRendering bits
|
||||
// Description: Returns the union of the Geom::GeomRendering bits
|
||||
// that will be required once this TexGenAttrib is
|
||||
// applied to a geom which includes the indicated
|
||||
// geom_point_rendering bits.
|
||||
// geom_rendering bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int TexGenAttrib::
|
||||
get_point_rendering(int geom_point_rendering) const {
|
||||
if ((geom_point_rendering & qpGeom::PR_point) != 0) {
|
||||
get_geom_rendering(int geom_rendering) const {
|
||||
if ((geom_rendering & qpGeom::GR_point) != 0) {
|
||||
if (_num_point_sprites > 0) {
|
||||
return geom_point_rendering |= qpGeom::PR_sprite;
|
||||
return geom_rendering |= qpGeom::GR_point_sprite;
|
||||
}
|
||||
}
|
||||
|
||||
return geom_point_rendering;
|
||||
return geom_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -104,7 +104,7 @@ PUBLISHED:
|
||||
bool has_stage(TextureStage *stage) const;
|
||||
Mode get_mode(TextureStage *stage) const;
|
||||
|
||||
INLINE int get_point_rendering(int geom_point_rendering) const;
|
||||
INLINE int get_geom_rendering(int geom_rendering) const;
|
||||
|
||||
public:
|
||||
INLINE const Geom::NoTexCoordStages &get_no_texcoords() const;
|
||||
|
@ -129,6 +129,8 @@ static TimeCollectorProperties time_properties[] = {
|
||||
{ 1, "Cull:Munge", { 0.3, 0.3, 0.9 } },
|
||||
{ 1, "Cull:Munge:Points", { 0.2, 0.8, 0.4 } },
|
||||
{ 1, "Cull:Munge:Data", { 0.7, 0.5, 0.2 } },
|
||||
{ 1, "Cull:Munge:Rotate", { 0.9, 0.8, 0.5 } },
|
||||
{ 1, "Cull:Munge:Decompose", { 0.1, 0.3, 0.1 } },
|
||||
{ 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
|
||||
{ 1, "Draw:Make current", { 0.4, 0.2, 0.6 } },
|
||||
{ 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },
|
||||
@ -140,7 +142,6 @@ static TimeCollectorProperties time_properties[] = {
|
||||
{ 1, "Draw:Flip:End", { 0.9, 0.3, 0.6 } },
|
||||
{ 1, "Draw:Bins", { 0.3, 0.6, 0.0 } },
|
||||
{ 0, "Draw:Primitive", { 0.0, 0.0, 0.5 } },
|
||||
{ 1, "Draw:Rotate", { 0.9, 0.8, 0.5 } },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user