gobj: Add config switch for Panda not to default to packed vertex colors

See #981.  Setting `vertex-colors-prefer-packed` to false will make Panda default to OpenGL-style vertex colors, which is useful if are targeting OpenGL and not DirectX 9, avoiding a potential performance cost.
This commit is contained in:
rdb 2021-03-25 23:15:58 +01:00
parent b405df72fa
commit 43fb82fa66
27 changed files with 162 additions and 52 deletions

View File

@ -228,7 +228,7 @@ class BufferViewer(DirectObject):
be precise so that the frame exactly aligns to pixel
boundaries, and so that it doesn't overlap the card at all."""
format = GeomVertexFormat.getV3cp()
format = GeomVertexFormat.getV3c()
vdata = GeomVertexData('card-frame', format, Geom.UHDynamic)
vwriter = GeomVertexWriter(vdata, 'vertex')

View File

@ -34,7 +34,7 @@ def addCircle(attachNode, vertexCount, radius, color = Vec4(1.0, 1.0, 1.0, 1.0),
centerColor = color
zFloat = 0.025
targetCircleShape = getCirclePoints(5 + (vertexCount), 0.0, 0.0, radius)
gFormat = GeomVertexFormat.getV3cp()
gFormat = GeomVertexFormat.getV3c()
targetCircleVertexData = GeomVertexData("holds my vertices", gFormat, Geom.UHDynamic)
targetCircleVertexWriter = GeomVertexWriter(targetCircleVertexData, "vertex")
targetCircleColorWriter = GeomVertexWriter(targetCircleVertexData, "color")
@ -79,7 +79,7 @@ def addSquare(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer
color2 = color
color3 = color
gFormat = GeomVertexFormat.getV3n3cpt2()
gFormat = GeomVertexFormat.getV3n3ct2()
boxVertexData = GeomVertexData("vertices", gFormat, Geom.UHDynamic)
boxVertexWriter = GeomVertexWriter(boxVertexData, "vertex")
@ -147,7 +147,7 @@ def addBox(attachNode, sizeX, sizeY, sizeZ, color = Vec4(1.0, 1.0, 1.0, 1.0), da
color2 = color * 0.50 #Vec4(0.0, 0.0, 0.0, 1.0)
color3 = color * 0.25 #Vec4(0.0, 0.0, 0.0, 1.0)
gFormat = GeomVertexFormat.getV3n3cp()
gFormat = GeomVertexFormat.getV3n3c()
boxVertexData = GeomVertexData("vertices", gFormat, Geom.UHDynamic)
boxVertexWriter = GeomVertexWriter(boxVertexData, "vertex")
@ -328,7 +328,7 @@ def addArrow(attachNode, sizeX, sizeY, color = Vec4(1.0, 1.0, 1.0, 1.0), layer =
color2 = color
color3 = color
gFormat = GeomVertexFormat.getV3n3cp()
gFormat = GeomVertexFormat.getV3n3c()
boxVertexData = GeomVertexData("vertices", gFormat, Geom.UHDynamic)
boxVertexWriter = GeomVertexWriter(boxVertexData, "vertex")

View File

@ -70,7 +70,7 @@ fill_viz_geom() {
static const double scale = 100.0;
PT(GeomVertexData) vdata = new GeomVertexData
("collision", GeomVertexFormat::get_v3cp(),
("collision", GeomVertexFormat::get_v3c(),
Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter color(vdata, InternalName::get_color());

View File

@ -174,7 +174,7 @@ fill_viz_geom() {
static const int num_points = 100;
PT(GeomVertexData) vdata = new GeomVertexData
("collision", GeomVertexFormat::get_v3cp(),
("collision", GeomVertexFormat::get_v3c(),
Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter color(vdata, InternalName::get_color());

View File

@ -128,7 +128,7 @@ fill_viz_geom() {
static const double scale = 100.0;
PT(GeomVertexData) vdata = new GeomVertexData
("collision", GeomVertexFormat::get_v3cp(),
("collision", GeomVertexFormat::get_v3c(),
Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter color(vdata, InternalName::get_color());

View File

@ -146,7 +146,7 @@ fill_viz_geom() {
}
PT(GeomVertexData) vdata = new GeomVertexData
("collision", GeomVertexFormat::get_v3cp(),
("collision", GeomVertexFormat::get_v3c(),
Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());

View File

@ -159,13 +159,19 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
CPT(RenderState) empty_state = RenderState::make_empty();
CPT(RenderState) point_state = RenderState::make(RenderModeAttrib::make(RenderModeAttrib::M_unchanged, 1.0f, false));
PT(GeomVertexArrayFormat) point_array_format =
new GeomVertexArrayFormat(InternalName::get_vertex(), 3,
Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 1,
Geom::NT_packed_dabc, Geom::C_color,
InternalName::get_size(), 1,
Geom::NT_stdfloat, Geom::C_other);
PT(GeomVertexArrayFormat) point_array_format;
if (vertex_colors_prefer_packed) {
point_array_format = new GeomVertexArrayFormat(
InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 1, Geom::NT_packed_dabc, Geom::C_color,
InternalName::get_size(), 1, Geom::NT_stdfloat, Geom::C_other);
}
else {
point_array_format = new GeomVertexArrayFormat(
InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 4, Geom::NT_uint8, Geom::C_color,
InternalName::get_size(), 1, Geom::NT_stdfloat, Geom::C_other);
}
CPT(GeomVertexFormat) point_format =
GeomVertexFormat::register_format(point_array_format);
@ -212,7 +218,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
// Draw the normal vector at the surface point.
if (!point._surface_normal.almost_equal(LVector3::zero())) {
PT(GeomVertexData) line_vdata =
new GeomVertexData("viz", GeomVertexFormat::get_v3cp(),
new GeomVertexData("viz", GeomVertexFormat::get_v3c(),
Geom::UH_stream);
PT(GeomLines) lines = new GeomLines(Geom::UH_stream);

View File

@ -495,8 +495,14 @@ recompute_geom(Geom *geom, const LMatrix4 &rel_mat) {
}
if (_vignette_on && !vdata->has_column(InternalName::get_color())) {
// We need to add a column for color.
vdata = vdata->replace_column
(InternalName::get_color(), 1, Geom::NT_packed_dabc, Geom::C_color);
if (vertex_colors_prefer_packed) {
vdata = vdata->replace_column
(InternalName::get_color(), 1, Geom::NT_packed_dabc, Geom::C_color);
}
else {
vdata = vdata->replace_column
(InternalName::get_color(), 4, Geom::NT_uint8, Geom::C_color);
}
geom->set_vertex_data(vdata);
}

View File

@ -602,7 +602,7 @@ make_transform(const EggTransform *egg_transform) {
void EggLoader::
show_normals(EggVertexPool *vertex_pool, GeomNode *geom_node) {
PT(GeomPrimitive) primitive = new GeomLines(Geom::UH_static);
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3cp();
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3c();
PT(GeomVertexData) vertex_data =
new GeomVertexData(vertex_pool->get_name(), format, Geom::UH_static);
@ -2243,13 +2243,14 @@ make_vertex_data(const EggRenderState *render_state,
if (!ignore_color) {
// Let's not use Direct3D-style colors on platforms where we only have
// OpenGL anyway.
#ifdef _WIN32
array_format->add_column(InternalName::get_color(), 1,
Geom::NT_packed_dabc, Geom::C_color);
#else
array_format->add_column(InternalName::get_color(), 4,
Geom::NT_uint8, Geom::C_color);
#endif
if (vertex_colors_prefer_packed) {
array_format->add_column(InternalName::get_color(), 1,
Geom::NT_packed_dabc, Geom::C_color);
}
else {
array_format->add_column(InternalName::get_color(), 4,
Geom::NT_uint8, Geom::C_color);
}
}
vector_string uv_names, uvw_names, tbn_names;

View File

@ -675,7 +675,7 @@ load_default_model(const NodePath &parent) {
GeomNode *geomnode = new GeomNode("tri");
PT(GeomVertexData) vdata = new GeomVertexData
("tri", GeomVertexFormat::get_v3n3cpt2(),
("tri", vertex_colors_prefer_packed ? GeomVertexFormat::get_v3n3ct2() : GeomVertexFormat::get_v3n3ct2(),
Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter normal(vdata, InternalName::get_normal());

View File

@ -301,6 +301,22 @@ ConfigVariableBool vertex_animation_align_16
"impacts only vertex formats created within Panda subsystems; custom "
"vertex formats are not affected."));
ConfigVariableBool vertex_colors_prefer_packed
("vertex-colors-prefer-packed",
#ifdef _WIN32
true,
#else
false,
#endif
PRC_DESC("This specifies whether to optimize vertex colors for OpenGL or for "
"DirectX 9. If set to true (the default on Windows), Panda will "
"generate DirectX-style vertex colors, which are also supported in "
"newer OpenGL versions (although they may be buggy on some cards, "
"such as AMD RDNA). If false, Panda will always use OpenGL-style "
"vertex colors, causing a minor performance penalty in DirectX 9. "
"You probably should set this to false if you know you will not be "
"using DirectX 9."));
ConfigVariableEnum<AutoTextureScale> textures_power_2
("textures-power-2", ATS_down,
PRC_DESC("Specify whether textures should automatically be constrained to "

View File

@ -54,6 +54,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool cache_generated_shaders;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertices_float64;
extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_column_alignment;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_animation_align_16;
extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_colors_prefer_packed;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_power_2;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<AutoTextureScale> textures_square;

View File

@ -353,6 +353,47 @@ get_v3n3c4t2() {
return get_registry()->_v3n3c4t2;
}
/**
* Returns a standard vertex format with a 4-component color and a 3-component
* vertex position.
*/
INLINE const GeomVertexFormat *GeomVertexFormat::
get_v3c() {
Registry *registry = get_registry();
return vertex_colors_prefer_packed ? registry->_v3cp : registry->_v3c4;
}
/**
* Returns a standard vertex format with a 4-component color, a 3-component
* normal, and a 3-component vertex position.
*/
INLINE const GeomVertexFormat *GeomVertexFormat::
get_v3n3c() {
Registry *registry = get_registry();
return vertex_colors_prefer_packed ? registry->_v3n3cp : registry->_v3n3c4;
}
/**
* Returns a standard vertex format with a 2-component texture coordinate
* pair, a 4-component color, and a 3-component vertex position.
*/
INLINE const GeomVertexFormat *GeomVertexFormat::
get_v3ct2() {
Registry *registry = get_registry();
return vertex_colors_prefer_packed ? registry->_v3cpt2 : registry->_v3c4t2;
}
/**
* Returns a standard vertex format with a 2-component texture coordinate
* pair, a 4-component color, a 3-component normal, and a 3-component vertex
* position.
*/
INLINE const GeomVertexFormat *GeomVertexFormat::
get_v3n3ct2() {
Registry *registry = get_registry();
return vertex_colors_prefer_packed ? registry->_v3n3cpt2 : registry->_v3n3c4t2;
}
/**
* Returns the array index of the array including the "vertex" column, or -1
* if there is no such array.

View File

@ -14,7 +14,7 @@
#ifndef GEOMVERTEXFORMAT_H
#define GEOMVERTEXFORMAT_H
#include "pandabase.h"
#include "config_gobj.h"
#include "typedWritableReferenceCount.h"
#include "geomVertexAnimationSpec.h"
#include "geomVertexArrayFormat.h"
@ -164,6 +164,13 @@ PUBLISHED:
INLINE static const GeomVertexFormat *get_v3n3c4();
INLINE static const GeomVertexFormat *get_v3n3c4t2();
// These are like the above, but automatically select the appropriate format
// based on the setting of vertex-colors-prefer-packed.
INLINE static const GeomVertexFormat *get_v3c();
INLINE static const GeomVertexFormat *get_v3ct2();
INLINE static const GeomVertexFormat *get_v3n3c();
INLINE static const GeomVertexFormat *get_v3n3ct2();
public:
bool get_array_info(const InternalName *name,
int &array_index,

View File

@ -177,7 +177,7 @@ create(GeomNode *previous, bool dynamic) {
CPT(RenderState) state = RenderState::make(thick, vtxcolor);
_created_data = new GeomVertexData
("lineSegs", GeomVertexFormat::get_v3cp(),
("lineSegs", GeomVertexFormat::get_v3c(),
dynamic ? Geom::UH_dynamic : Geom::UH_static);
GeomVertexWriter vertex(_created_data, InternalName::get_vertex());
GeomVertexWriter color(_created_data, InternalName::get_color());

View File

@ -243,9 +243,16 @@ get_format(bool support_normals) const {
Geom::C_normal);
}
if (get_use_vertex_color()) {
array_format->add_column
(InternalName::get_color(), 1, Geom::NT_packed_dabc,
Geom::C_color);
if (vertex_colors_prefer_packed) {
array_format->add_column
(InternalName::get_color(), 1, Geom::NT_packed_dabc,
Geom::C_color);
}
else {
array_format->add_column
(InternalName::get_color(), 4, Geom::NT_uint8,
Geom::C_color);
}
}
if (get_uv_mode() != UV_none) {
array_format->add_column

View File

@ -250,7 +250,7 @@ render_sheet(CullTraverser *trav, CullTraverserData &data,
CPT(GeomVertexFormat) format;
if (use_vertex_color) {
format = GeomVertexFormat::get_v3n3cpt2();
format = GeomVertexFormat::get_v3n3ct2();
} else {
format = GeomVertexFormat::get_v3n3t2();
}

View File

@ -113,7 +113,7 @@ resize_pool(int new_size) {
void LineParticleRenderer::
init_geoms() {
_vdata = new GeomVertexData
("line_particles", GeomVertexFormat::get_v3cp(),
("line_particles", GeomVertexFormat::get_v3c(),
Geom::UH_stream);
PT(Geom) geom = new Geom(_vdata);
_line_primitive = geom;

View File

@ -88,7 +88,7 @@ resize_pool(int new_size) {
void PointParticleRenderer::
init_geoms() {
_vdata = new GeomVertexData
("point_particles", GeomVertexFormat::get_v3cp(),
("point_particles", GeomVertexFormat::get_v3c(),
Geom::UH_stream);
PT(Geom) geom = new Geom(_vdata);
_point_primitive = geom;

View File

@ -109,7 +109,7 @@ resize_pool(int new_size) {
void SparkleParticleRenderer::
init_geoms() {
_vdata = new GeomVertexData
("sparkle_particles", GeomVertexFormat::get_v3cp(),
("sparkle_particles", GeomVertexFormat::get_v3c(),
Geom::UH_stream);
PT(Geom) geom = new Geom(_vdata);
_line_primitive = geom;

View File

@ -410,9 +410,18 @@ init_geoms() {
int i,j;
// Setup format
PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat
(InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 1, Geom::NT_packed_dabc, Geom::C_color);
PT(GeomVertexArrayFormat) array_format;
if (vertex_colors_prefer_packed) {
array_format = new GeomVertexArrayFormat
(InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 1, Geom::NT_packed_dabc, Geom::C_color);
}
else {
array_format = new GeomVertexArrayFormat
(InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point,
InternalName::get_color(), 4, Geom::NT_uint8, Geom::C_color);
}
if (_animate_theta || _theta != 0.0f) {
array_format->add_column

View File

@ -271,10 +271,15 @@ set_color(Geom *geom, const LColor &color) {
// We have not yet converted these colors. Do so now.
if (sc._vertex_data->has_column(InternalName::get_color())) {
new_data._vdata = sc._vertex_data->set_color(color);
} else {
}
else if (vertex_colors_prefer_packed) {
new_data._vdata = sc._vertex_data->set_color
(color, 1, Geom::NT_packed_dabc, Geom::C_color);
}
else {
new_data._vdata = sc._vertex_data->set_color
(color, 4, Geom::NT_uint8, Geom::C_color);
}
}
geom->set_vertex_data(new_data._vdata);
@ -330,10 +335,15 @@ transform_colors(Geom *geom, const LVecBase4 &scale) {
// We have not yet converted these colors. Do so now.
if (sc._vertex_data->has_column(InternalName::get_color())) {
new_data._vdata = sc._vertex_data->scale_color(scale);
} else {
}
else if (vertex_colors_prefer_packed) {
new_data._vdata = sc._vertex_data->set_color
(scale, 1, Geom::NT_packed_dabc, Geom::C_color);
}
else {
new_data._vdata = sc._vertex_data->set_color
(scale, 4, Geom::NT_uint8, Geom::C_color);
}
}
geom->set_vertex_data(new_data._vdata);
@ -468,12 +478,18 @@ apply_texture_colors(Geom *geom, TextureStage *ts, Texture *tex,
// Make sure the vdata has a color column.
if (stc._vertex_data->has_column(InternalName::get_color())) {
vdata = new GeomVertexData(*stc._vertex_data);
} else {
}
else if (vertex_colors_prefer_packed) {
// Create a color column where there wasn't one before.
vdata = new GeomVertexData(*stc._vertex_data->set_color
(LColor(1.0f, 1.0f, 1.0f, 1.0f), 1, Geom::NT_packed_dabc, Geom::C_color));
keep_vertex_color = false;
}
else {
vdata = new GeomVertexData(*stc._vertex_data->set_color
(LColor(1.0f, 1.0f, 1.0f, 1.0f), 4, Geom::NT_uint8, Geom::C_color));
keep_vertex_color = false;
}
// Check whether it has 2-d or 3-d texture coordinates.
bool tex3d = false;

View File

@ -199,7 +199,7 @@ get_viz(CullTraverser *trav, CullTraverserData &data) {
const LPlane &plane = cdataw->_plane;
PT(GeomVertexData) vdata = new GeomVertexData
(get_name(), GeomVertexFormat::get_v3cp(), Geom::UH_static);
(get_name(), GeomVertexFormat::get_v3c(), Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
PT(GeomLines) lines = new GeomLines(Geom::UH_static);

View File

@ -147,7 +147,7 @@ draw_lines() {
_created_data = nullptr;
PT(GeomVertexData) vdata = new GeomVertexData
("portal", GeomVertexFormat::get_v3cp(), Geom::UH_static);
("portal", GeomVertexFormat::get_v3c(), Geom::UH_static);
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter color(vdata, InternalName::get_color());

View File

@ -854,7 +854,7 @@ compute_ring_viz() {
// for the inner edge.
static const PN_stdfloat edge_ratio = 0.1; // ratio of edge height to diameter.
const GeomVertexFormat *format = GeomVertexFormat::get_v3n3cp();
const GeomVertexFormat *format = GeomVertexFormat::get_v3n3c();
PT(GeomVertexData) vdata = new GeomVertexData("LOD_ring", format, Geom::UH_static);
// Fill up the vertex table with all of the vertices.
@ -978,7 +978,7 @@ compute_spindle_viz() {
static const int num_slices = 10;
static const int num_rings = 10;
const GeomVertexFormat *format = GeomVertexFormat::get_v3n3cp();
const GeomVertexFormat *format = GeomVertexFormat::get_v3n3c();
PT(GeomVertexData) vdata = new GeomVertexData("LOD_spindle", format, Geom::UH_static);
// Fill up the vertex table with all of the vertices.

View File

@ -337,9 +337,9 @@ generate_bevel_geom(const LVecBase4 &frame, bool in) {
CPT(GeomVertexFormat) format;
if (has_texture()) {
format = GeomVertexFormat::get_v3cpt2();
format = GeomVertexFormat::get_v3ct2();
} else {
format = GeomVertexFormat::get_v3cp();
format = GeomVertexFormat::get_v3c();
}
PT(GeomVertexData) vdata = new GeomVertexData
@ -528,9 +528,9 @@ generate_groove_geom(const LVecBase4 &frame, bool in) {
CPT(GeomVertexFormat) format;
if (has_texture()) {
format = GeomVertexFormat::get_v3cpt2();
format = GeomVertexFormat::get_v3ct2();
} else {
format = GeomVertexFormat::get_v3cp();
format = GeomVertexFormat::get_v3c();
}
PT(GeomVertexData) vdata = new GeomVertexData
("PGFrame", format, Geom::UH_static);

View File

@ -1773,7 +1773,7 @@ draw_underscore(TextAssembler::PlacedGlyphs &placed_glyphs,
PN_stdfloat underscore_start, PN_stdfloat underscore_end,
const TextProperties *underscore_properties) {
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3cp();
CPT(GeomVertexFormat) format = GeomVertexFormat::get_v3c();
PT(GeomVertexData) vdata =
new GeomVertexData("underscore", format, Geom::UH_static);
vdata->unclean_set_num_rows(2);