|
|
@@ -653,6 +653,12 @@ reset() {
|
|
|
Geom::GR_line_strip |
|
|
|
Geom::GR_flat_last_vertex;
|
|
|
|
|
|
+#ifndef OPENGLES
|
|
|
+ if (_supports_geometry_shaders) {
|
|
|
+ _supported_geom_rendering |= Geom::GR_adjacency;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
_supports_point_parameters = false;
|
|
|
|
|
|
#ifdef OPENGLES_1
|
|
|
@@ -4543,6 +4549,68 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Draws a series of disconnected triangles with adjacency information.
|
|
|
+ */
|
|
|
+#ifndef OPENGLES
|
|
|
+bool CLP(GraphicsStateGuardian)::
|
|
|
+draw_triangles_adj(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
+ // PStatGPUTimer timer(this, _draw_primitive_pcollector,
|
|
|
+ // reader->get_current_thread());
|
|
|
+
|
|
|
+#ifndef NDEBUG
|
|
|
+ if (GLCAT.is_spam()) {
|
|
|
+ GLCAT.spam() << "draw_triangles_adj: " << *(reader->get_object()) << "\n";
|
|
|
+ }
|
|
|
+#endif // NDEBUG
|
|
|
+
|
|
|
+#ifdef SUPPORT_IMMEDIATE_MODE
|
|
|
+ if (_use_sender) {
|
|
|
+ draw_immediate_simple_primitives(reader, GL_TRIANGLES_ADJACENCY);
|
|
|
+
|
|
|
+ } else
|
|
|
+#endif // SUPPORT_IMMEDIATE_MODE
|
|
|
+ {
|
|
|
+ int num_vertices = reader->get_num_vertices();
|
|
|
+ _vertices_tri_pcollector.add_level(num_vertices);
|
|
|
+ _primitive_batches_tri_pcollector.add_level(1);
|
|
|
+
|
|
|
+ if (reader->is_indexed()) {
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_TRIANGLES_ADJACENCY, num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer, _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_TRIANGLES_ADJACENCY,
|
|
|
+ reader->get_min_vertex(),
|
|
|
+ reader->get_max_vertex(),
|
|
|
+ num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawArraysInstanced(GL_TRIANGLES_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices, _instance_count);
|
|
|
+ } else {
|
|
|
+ glDrawArrays(GL_TRIANGLES_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+ return true;
|
|
|
+}
|
|
|
+#endif // OPENGLES
|
|
|
+
|
|
|
/**
|
|
|
* Draws a series of triangle strips.
|
|
|
*/
|
|
|
@@ -4669,6 +4737,128 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Draws a series of triangle strips with adjacency information.
|
|
|
+ */
|
|
|
+#ifndef OPENGLES
|
|
|
+bool CLP(GraphicsStateGuardian)::
|
|
|
+draw_tristrips_adj(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
+ // PStatGPUTimer timer(this, _draw_primitive_pcollector,
|
|
|
+ // reader->get_current_thread());
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+
|
|
|
+#ifndef NDEBUG
|
|
|
+ if (GLCAT.is_spam()) {
|
|
|
+ GLCAT.spam() << "draw_tristrips_adj: " << *(reader->get_object()) << "\n";
|
|
|
+ }
|
|
|
+#endif // NDEBUG
|
|
|
+
|
|
|
+#ifdef SUPPORT_IMMEDIATE_MODE
|
|
|
+ if (_use_sender) {
|
|
|
+ draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP_ADJACENCY);
|
|
|
+
|
|
|
+ } else
|
|
|
+#endif // SUPPORT_IMMEDIATE_MODE
|
|
|
+ {
|
|
|
+ if (reader->is_indexed() &&
|
|
|
+ (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
|
|
|
+ // One long line strip, connected by strip cut indices.
|
|
|
+ if (_explicit_primitive_restart) {
|
|
|
+ glEnable(GL_PRIMITIVE_RESTART);
|
|
|
+ _glPrimitiveRestartIndex(reader->get_strip_cut_index());
|
|
|
+ }
|
|
|
+ int num_vertices = reader->get_num_vertices();
|
|
|
+ _vertices_tristrip_pcollector.add_level(num_vertices);
|
|
|
+ _primitive_batches_tristrip_pcollector.add_level(1);
|
|
|
+ if (reader->is_indexed()) {
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_TRIANGLE_STRIP_ADJACENCY, num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer, _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_TRIANGLE_STRIP_ADJACENCY,
|
|
|
+ reader->get_min_vertex(),
|
|
|
+ reader->get_max_vertex(),
|
|
|
+ num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawArraysInstanced(GL_TRIANGLE_STRIP_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices, _instance_count);
|
|
|
+ } else {
|
|
|
+ glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (_explicit_primitive_restart) {
|
|
|
+ glDisable(GL_PRIMITIVE_RESTART);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Send the individual triangle strips, stepping over the degenerate
|
|
|
+ // vertices.
|
|
|
+ CPTA_int ends = reader->get_ends();
|
|
|
+
|
|
|
+ _primitive_batches_tristrip_pcollector.add_level(ends.size());
|
|
|
+ if (reader->is_indexed()) {
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int index_stride = reader->get_index_stride();
|
|
|
+ GeomVertexReader mins(reader->get_mins(), 0);
|
|
|
+ GeomVertexReader maxs(reader->get_maxs(), 0);
|
|
|
+ nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
|
|
+ reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
|
|
|
+
|
|
|
+ unsigned int start = 0;
|
|
|
+ for (size_t i = 0; i < ends.size(); i++) {
|
|
|
+ _vertices_tristrip_pcollector.add_level(ends[i] - start);
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_TRIANGLE_STRIP_ADJACENCY, ends[i] - start,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer + start * index_stride,
|
|
|
+ _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_TRIANGLE_STRIP_ADJACENCY,
|
|
|
+ mins.get_data1i(), maxs.get_data1i(),
|
|
|
+ ends[i] - start,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer + start * index_stride);
|
|
|
+ }
|
|
|
+ start = ends[i] + 1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ unsigned int start = 0;
|
|
|
+ int first_vertex = reader->get_first_vertex();
|
|
|
+ for (size_t i = 0; i < ends.size(); i++) {
|
|
|
+ _vertices_tristrip_pcollector.add_level(ends[i] - start);
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawArraysInstanced(GL_TRIANGLE_STRIP_ADJACENCY, first_vertex + start,
|
|
|
+ ends[i] - start, _instance_count);
|
|
|
+ } else {
|
|
|
+ glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY, first_vertex + start,
|
|
|
+ ends[i] - start);
|
|
|
+ }
|
|
|
+ start = ends[i] + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+ return true;
|
|
|
+}
|
|
|
+#endif // OPENGLES
|
|
|
+
|
|
|
/**
|
|
|
* Draws a series of triangle fans.
|
|
|
*/
|
|
|
@@ -4888,6 +5078,66 @@ draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Draws a series of disconnected line segments with adjacency information.
|
|
|
+ */
|
|
|
+#ifndef OPENGLES
|
|
|
+bool CLP(GraphicsStateGuardian)::
|
|
|
+draw_lines_adj(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
+ // PStatGPUTimer timer(this, _draw_primitive_pcollector,
|
|
|
+ // reader->get_current_thread());
|
|
|
+
|
|
|
+#ifndef NDEBUG
|
|
|
+ if (GLCAT.is_spam()) {
|
|
|
+ GLCAT.spam() << "draw_lines_adj: " << *(reader->get_object()) << "\n";
|
|
|
+ }
|
|
|
+#endif // NDEBUG
|
|
|
+
|
|
|
+#ifdef SUPPORT_IMMEDIATE_MODE
|
|
|
+ if (_use_sender) {
|
|
|
+ draw_immediate_simple_primitives(reader, GL_LINES_ADJACENCY);
|
|
|
+ } else
|
|
|
+#endif // SUPPORT_IMMEDIATE_MODE
|
|
|
+ {
|
|
|
+ int num_vertices = reader->get_num_vertices();
|
|
|
+ _vertices_other_pcollector.add_level(num_vertices);
|
|
|
+ _primitive_batches_other_pcollector.add_level(1);
|
|
|
+
|
|
|
+ if (reader->is_indexed()) {
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_LINES_ADJACENCY, num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer, _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_LINES_ADJACENCY,
|
|
|
+ reader->get_min_vertex(),
|
|
|
+ reader->get_max_vertex(),
|
|
|
+ num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawArraysInstanced(GL_LINES_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices, _instance_count);
|
|
|
+ } else {
|
|
|
+ glDrawArrays(GL_LINES_ADJACENCY,
|
|
|
+ reader->get_first_vertex(),
|
|
|
+ num_vertices);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+ return true;
|
|
|
+}
|
|
|
+#endif // OPENGLES
|
|
|
+
|
|
|
/**
|
|
|
* Draws a series of line strips.
|
|
|
*/
|
|
|
@@ -5010,6 +5260,117 @@ draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Draws a series of line strips with adjacency information.
|
|
|
+ */
|
|
|
+#ifndef OPENGLES
|
|
|
+bool CLP(GraphicsStateGuardian)::
|
|
|
+draw_linestrips_adj(const GeomPrimitivePipelineReader *reader, bool force) {
|
|
|
+ // PStatGPUTimer timer(this, _draw_primitive_pcollector,
|
|
|
+ // reader->get_current_thread());
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+
|
|
|
+#ifndef NDEBUG
|
|
|
+ if (GLCAT.is_spam()) {
|
|
|
+ GLCAT.spam() << "draw_linestrips_adj: " << *(reader->get_object()) << "\n";
|
|
|
+ }
|
|
|
+#endif // NDEBUG
|
|
|
+
|
|
|
+#ifdef SUPPORT_IMMEDIATE_MODE
|
|
|
+ if (_use_sender) {
|
|
|
+ draw_immediate_composite_primitives(reader, GL_LINE_STRIP_ADJACENCY);
|
|
|
+
|
|
|
+ } else
|
|
|
+#endif // SUPPORT_IMMEDIATE_MODE
|
|
|
+ {
|
|
|
+ if (reader->is_indexed() &&
|
|
|
+ (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
|
|
|
+ // One long line strip, connected by strip cut indices.
|
|
|
+ if (_explicit_primitive_restart) {
|
|
|
+ glEnable(GL_PRIMITIVE_RESTART);
|
|
|
+ _glPrimitiveRestartIndex(reader->get_strip_cut_index());
|
|
|
+ }
|
|
|
+
|
|
|
+ int num_vertices = reader->get_num_vertices();
|
|
|
+ _vertices_other_pcollector.add_level(num_vertices);
|
|
|
+ _primitive_batches_other_pcollector.add_level(1);
|
|
|
+
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_LINE_STRIP_ADJACENCY, num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer, _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_LINE_STRIP_ADJACENCY,
|
|
|
+ reader->get_min_vertex(),
|
|
|
+ reader->get_max_vertex(),
|
|
|
+ num_vertices,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_explicit_primitive_restart) {
|
|
|
+ glDisable(GL_PRIMITIVE_RESTART);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Send the individual line strips, stepping over the strip-cut indices.
|
|
|
+ CPTA_int ends = reader->get_ends();
|
|
|
+
|
|
|
+ _primitive_batches_other_pcollector.add_level(ends.size());
|
|
|
+ if (reader->is_indexed()) {
|
|
|
+ const unsigned char *client_pointer;
|
|
|
+ if (!setup_primitive(client_pointer, reader, force)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ int index_stride = reader->get_index_stride();
|
|
|
+ GeomVertexReader mins(reader->get_mins(), 0);
|
|
|
+ GeomVertexReader maxs(reader->get_maxs(), 0);
|
|
|
+ nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
|
|
+ reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
|
|
|
+
|
|
|
+ unsigned int start = 0;
|
|
|
+ for (size_t i = 0; i < ends.size(); i++) {
|
|
|
+ _vertices_other_pcollector.add_level(ends[i] - start);
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawElementsInstanced(GL_LINE_STRIP_ADJACENCY, ends[i] - start,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer + start * index_stride,
|
|
|
+ _instance_count);
|
|
|
+ } else {
|
|
|
+ _glDrawRangeElements(GL_LINE_STRIP_ADJACENCY,
|
|
|
+ mins.get_data1i(), maxs.get_data1i(),
|
|
|
+ ends[i] - start,
|
|
|
+ get_numeric_type(reader->get_index_type()),
|
|
|
+ client_pointer + start * index_stride);
|
|
|
+ }
|
|
|
+ start = ends[i] + 1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ unsigned int start = 0;
|
|
|
+ int first_vertex = reader->get_first_vertex();
|
|
|
+ for (size_t i = 0; i < ends.size(); i++) {
|
|
|
+ _vertices_other_pcollector.add_level(ends[i] - start);
|
|
|
+ if (_supports_geometry_instancing && _instance_count > 0) {
|
|
|
+ _glDrawArraysInstanced(GL_LINE_STRIP_ADJACENCY, first_vertex + start,
|
|
|
+ ends[i] - start, _instance_count);
|
|
|
+ } else {
|
|
|
+ glDrawArrays(GL_LINE_STRIP_ADJACENCY, first_vertex + start, ends[i] - start);
|
|
|
+ }
|
|
|
+ start = ends[i] + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ report_my_gl_errors();
|
|
|
+ return true;
|
|
|
+}
|
|
|
+#endif // OPENGLES
|
|
|
+
|
|
|
/**
|
|
|
* Draws a series of disconnected points.
|
|
|
*/
|