support GLSL tessellation shaders

This commit is contained in:
David Rose 2012-04-27 20:29:47 +00:00
parent b7d369ec27
commit e9053ff910
45 changed files with 12051 additions and 6296 deletions

View File

@ -633,6 +633,28 @@ get_supports_basic_shaders() const {
return _supports_basic_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_geometry_shaders
// Access: Published
// Description: Returns true if this particular GSG supports
// geometry shaders.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_geometry_shaders() const {
return _supports_geometry_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_tessellation_shaders
// Access: Published
// Description: Returns true if this particular GSG supports
// tesselation shaders.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_tessellation_shaders() const {
return _supports_tessellation_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_glsl
// Access: Published

View File

@ -80,10 +80,12 @@ PStatCollector GraphicsStateGuardian::_primitive_batches_pcollector("Primitive b
PStatCollector GraphicsStateGuardian::_primitive_batches_tristrip_pcollector("Primitive batches:Triangle strips");
PStatCollector GraphicsStateGuardian::_primitive_batches_trifan_pcollector("Primitive batches:Triangle fans");
PStatCollector GraphicsStateGuardian::_primitive_batches_tri_pcollector("Primitive batches:Triangles");
PStatCollector GraphicsStateGuardian::_primitive_batches_patch_pcollector("Primitive batches:Patches");
PStatCollector GraphicsStateGuardian::_primitive_batches_other_pcollector("Primitive batches:Other");
PStatCollector GraphicsStateGuardian::_vertices_tristrip_pcollector("Vertices:Triangle strips");
PStatCollector GraphicsStateGuardian::_vertices_trifan_pcollector("Vertices:Triangle fans");
PStatCollector GraphicsStateGuardian::_vertices_tri_pcollector("Vertices:Triangles");
PStatCollector GraphicsStateGuardian::_vertices_patch_pcollector("Vertices:Patches");
PStatCollector GraphicsStateGuardian::_vertices_other_pcollector("Vertices:Other");
PStatCollector GraphicsStateGuardian::_state_pcollector("State changes");
PStatCollector GraphicsStateGuardian::_transform_state_pcollector("State changes:Transforms");
@ -214,6 +216,8 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
_supports_depth_stencil = false;
_supports_shadow_filter = false;
_supports_basic_shaders = false;
_supports_geometry_shaders = false;
_supports_tessellation_shaders = false;
_supports_glsl = false;
_supports_stencil = false;
@ -1554,10 +1558,12 @@ end_frame(Thread *current_thread) {
_primitive_batches_tristrip_pcollector.flush_level();
_primitive_batches_trifan_pcollector.flush_level();
_primitive_batches_tri_pcollector.flush_level();
_primitive_batches_patch_pcollector.flush_level();
_primitive_batches_other_pcollector.flush_level();
_vertices_tristrip_pcollector.flush_level();
_vertices_trifan_pcollector.flush_level();
_vertices_tri_pcollector.flush_level();
_vertices_patch_pcollector.flush_level();
_vertices_other_pcollector.flush_level();
_state_pcollector.flush_level();
@ -1720,6 +1726,17 @@ draw_trifans(const GeomPrimitivePipelineReader *, bool) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::draw_patches
// Access: Public, Virtual
// Description: Draws a series of "patches", which can only be
// processed by a tessellation shader.
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
draw_patches(const GeomPrimitivePipelineReader *, bool) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::draw_lines
// Access: Public, Virtual
@ -2241,10 +2258,12 @@ init_frame_pstats() {
_primitive_batches_tristrip_pcollector.clear_level();
_primitive_batches_trifan_pcollector.clear_level();
_primitive_batches_tri_pcollector.clear_level();
_primitive_batches_patch_pcollector.clear_level();
_primitive_batches_other_pcollector.clear_level();
_vertices_tristrip_pcollector.clear_level();
_vertices_trifan_pcollector.clear_level();
_vertices_tri_pcollector.clear_level();
_vertices_patch_pcollector.clear_level();
_vertices_other_pcollector.clear_level();
_state_pcollector.clear_level();

View File

@ -143,6 +143,8 @@ PUBLISHED:
INLINE bool get_supports_depth_stencil() const;
INLINE bool get_supports_shadow_filter() const;
INLINE bool get_supports_basic_shaders() const;
INLINE bool get_supports_geometry_shaders() const;
INLINE bool get_supports_tessellation_shaders() const;
INLINE bool get_supports_glsl() const;
INLINE bool get_supports_stencil() const;
INLINE bool get_supports_two_sided_stencil() const;
@ -274,6 +276,8 @@ public:
bool force);
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader,
@ -482,6 +486,8 @@ protected:
bool _supports_depth_stencil;
bool _supports_shadow_filter;
bool _supports_basic_shaders;
bool _supports_geometry_shaders;
bool _supports_tessellation_shaders;
bool _supports_glsl;
bool _supports_framebuffer_multisample;
bool _supports_framebuffer_blit;
@ -534,10 +540,12 @@ public:
static PStatCollector _primitive_batches_tristrip_pcollector;
static PStatCollector _primitive_batches_trifan_pcollector;
static PStatCollector _primitive_batches_tri_pcollector;
static PStatCollector _primitive_batches_patch_pcollector;
static PStatCollector _primitive_batches_other_pcollector;
static PStatCollector _vertices_tristrip_pcollector;
static PStatCollector _vertices_trifan_pcollector;
static PStatCollector _vertices_tri_pcollector;
static PStatCollector _vertices_patch_pcollector;
static PStatCollector _vertices_other_pcollector;
static PStatCollector _vertices_indexed_tristrip_pcollector;
static PStatCollector _state_pcollector;

View File

@ -916,6 +916,26 @@ GEOMETRY ENTRIES
or even within a texture.
<Patch> name {
[attributes]
<VertexRef> {
indices
<Ref> { pool-name }
}
}
A patch is similar to a polygon, but it is a special primitive that
can only be rendered with the use of a tessellation shader. Each
patch consists of an arbitrary number of vertices; all patches with
the same number of vertices are collected together into the same
GeomPatches object to be delivered to the shader in a single batch.
It is then up to the shader to create the correct set of triangles
from the patch data.
All of the attributes that are valid for Polygon, above, may also be
specified for Patch.
<PointLight> name {
[attributes]
<VertexRef> {
@ -944,7 +964,6 @@ GEOMETRY ENTRIES
viewer normally.
<Line> name {
[attributes]
<VertexRef> {

View File

@ -37,7 +37,9 @@
eggNamedObject.I eggNamedObject.h eggNameUniquifier.h \
eggNode.I eggNode.h eggNurbsCurve.I eggNurbsCurve.h \
eggNurbsSurface.I eggNurbsSurface.h eggObject.I eggObject.h \
eggParameters.h eggPoint.I eggPoint.h eggPolygon.I \
eggParameters.h \
eggPatch.I eggPatch.h \
eggPoint.I eggPoint.h eggPolygon.I \
eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h \
eggPrimitive.I eggPrimitive.h \
eggRenderMode.I eggRenderMode.h \
@ -77,7 +79,9 @@
eggMiscFuncs.cxx eggMorphList.cxx \
eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx \
eggNurbsCurve.cxx eggNurbsSurface.cxx eggObject.cxx \
eggParameters.cxx eggPoint.cxx eggPolygon.cxx eggPolysetMaker.cxx \
eggParameters.cxx \
eggPatch.cxx \
eggPoint.cxx eggPolygon.cxx eggPolysetMaker.cxx \
eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx \
eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \
eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \
@ -110,7 +114,9 @@
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
eggNamedObject.I eggNamedObject.h eggNameUniquifier.h eggNode.I eggNode.h \
eggNurbsCurve.I eggNurbsCurve.h eggNurbsSurface.I eggNurbsSurface.h \
eggObject.I eggObject.h eggParameters.h eggPoint.I eggPoint.h \
eggObject.I eggObject.h eggParameters.h \
eggPatch.I eggPatch.h \
eggPoint.I eggPoint.h \
eggPolygon.I eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h \
eggPrimitive.I eggPrimitive.h eggRenderMode.I eggRenderMode.h \
eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \

View File

@ -36,6 +36,7 @@
#include "eggNurbsCurve.h"
#include "eggNurbsSurface.h"
#include "eggObject.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggPolygon.h"
#include "eggPolysetMaker.h"
@ -199,6 +200,7 @@ init_libegg() {
EggNurbsCurve::init_type();
EggNurbsSurface::init_type();
EggObject::init_type();
EggPatch::init_type();
EggPoint::init_type();
EggPolygon::init_type();
EggPolysetMaker::init_type();

43
panda/src/egg/eggPatch.I Executable file
View File

@ -0,0 +1,43 @@
// Filename: eggPatch.I
// Created by: drose (27Apr12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: EggPatch::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggPatch::
EggPatch(const string &name) : EggPrimitive(name) {
}
////////////////////////////////////////////////////////////////////
// Function: EggPatch::Copy constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggPatch::
EggPatch(const EggPatch &copy) : EggPrimitive(copy) {
}
////////////////////////////////////////////////////////////////////
// Function: EggPatch::Copy assignment operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE EggPatch &EggPatch::
operator = (const EggPatch &copy) {
EggPrimitive::operator = (copy);
return *this;
}

37
panda/src/egg/eggPatch.cxx Executable file
View File

@ -0,0 +1,37 @@
// Filename: eggPatch.cxx
// Created by: drose (27Apr12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "eggPatch.h"
#include "eggGroupNode.h"
#include "plane.h"
#include "indent.h"
#include <algorithm>
TypeHandle EggPatch::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggPatch::write
// Access: Published, Virtual
// Description: Writes the patch to the indicated output stream in
// Egg format.
////////////////////////////////////////////////////////////////////
void EggPatch::
write(ostream &out, int indent_level) const {
write_header(out, indent_level, "<Patch>");
write_body(out, indent_level+2);
indent(out, indent_level) << "}\n";
}

56
panda/src/egg/eggPatch.h Executable file
View File

@ -0,0 +1,56 @@
// Filename: eggPatch.h
// Created by: drose (27Apr12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef EGGPATCH_H
#define EGGPATCH_H
#include "pandabase.h"
#include "eggPrimitive.h"
////////////////////////////////////////////////////////////////////
// Class : EggPatch
// Description : A single "patch", a special primitive to be rendered
// only with a tessellation shader.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDAEGG EggPatch : public EggPrimitive {
PUBLISHED:
INLINE EggPatch(const string &name = "");
INLINE EggPatch(const EggPatch &copy);
INLINE EggPatch &operator = (const EggPatch &copy);
virtual void write(ostream &out, int indent_level) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EggPrimitive::init_type();
register_type(_type_handle, "EggPatch",
EggPrimitive::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "eggPatch.I"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -523,6 +523,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
accept();
return OUTTANGENT;
}
"<PATCH>" {
accept();
return PATCH;
}
"<POINTLIGHT>" {
accept();
return POINTLIGHT;

View File

@ -1,5 +1,6 @@
#include "eggObject.cxx"
#include "eggParameters.cxx"
#include "eggPatch.cxx"
#include "eggPoint.cxx"
#include "eggPolygon.cxx"
#include "eggPolysetMaker.cxx"

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,22 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* A Bison parser, made by GNU Bison 2.4.2. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -29,10 +27,11 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
@ -84,49 +83,50 @@
OBJECTTYPE = 300,
ORDER = 301,
OUTTANGENT = 302,
POINTLIGHT = 303,
POLYGON = 304,
REF = 305,
RGBA = 306,
ROTATE = 307,
ROTX = 308,
ROTY = 309,
ROTZ = 310,
SANIM = 311,
SCALAR = 312,
SCALE = 313,
SEQUENCE = 314,
SHADING = 315,
SWITCH = 316,
SWITCHCONDITION = 317,
TABLE = 318,
TABLE_V = 319,
TAG = 320,
TANGENT = 321,
TEXLIST = 322,
TEXTURE = 323,
TLENGTHS = 324,
TRANSFORM = 325,
TRANSLATE = 326,
TREF = 327,
TRIANGLEFAN = 328,
TRIANGLESTRIP = 329,
TRIM = 330,
TXT = 331,
UKNOTS = 332,
UV = 333,
AUX = 334,
VKNOTS = 335,
VERTEX = 336,
VERTEXANIM = 337,
VERTEXPOOL = 338,
VERTEXREF = 339,
XFMANIM = 340,
XFMSANIM = 341,
START_EGG = 342,
START_GROUP_BODY = 343,
START_TEXTURE_BODY = 344,
START_PRIMITIVE_BODY = 345
PATCH = 303,
POINTLIGHT = 304,
POLYGON = 305,
REF = 306,
RGBA = 307,
ROTATE = 308,
ROTX = 309,
ROTY = 310,
ROTZ = 311,
SANIM = 312,
SCALAR = 313,
SCALE = 314,
SEQUENCE = 315,
SHADING = 316,
SWITCH = 317,
SWITCHCONDITION = 318,
TABLE = 319,
TABLE_V = 320,
TAG = 321,
TANGENT = 322,
TEXLIST = 323,
TEXTURE = 324,
TLENGTHS = 325,
TRANSFORM = 326,
TRANSLATE = 327,
TREF = 328,
TRIANGLEFAN = 329,
TRIANGLESTRIP = 330,
TRIM = 331,
TXT = 332,
UKNOTS = 333,
UV = 334,
AUX = 335,
VKNOTS = 336,
VERTEX = 337,
VERTEXANIM = 338,
VERTEXPOOL = 339,
VERTEXREF = 340,
XFMANIM = 341,
XFMSANIM = 342,
START_EGG = 343,
START_GROUP_BODY = 344,
START_TEXTURE_BODY = 345,
START_PRIMITIVE_BODY = 346
};
#endif
/* Tokens. */
@ -175,59 +175,60 @@
#define OBJECTTYPE 300
#define ORDER 301
#define OUTTANGENT 302
#define POINTLIGHT 303
#define POLYGON 304
#define REF 305
#define RGBA 306
#define ROTATE 307
#define ROTX 308
#define ROTY 309
#define ROTZ 310
#define SANIM 311
#define SCALAR 312
#define SCALE 313
#define SEQUENCE 314
#define SHADING 315
#define SWITCH 316
#define SWITCHCONDITION 317
#define TABLE 318
#define TABLE_V 319
#define TAG 320
#define TANGENT 321
#define TEXLIST 322
#define TEXTURE 323
#define TLENGTHS 324
#define TRANSFORM 325
#define TRANSLATE 326
#define TREF 327
#define TRIANGLEFAN 328
#define TRIANGLESTRIP 329
#define TRIM 330
#define TXT 331
#define UKNOTS 332
#define UV 333
#define AUX 334
#define VKNOTS 335
#define VERTEX 336
#define VERTEXANIM 337
#define VERTEXPOOL 338
#define VERTEXREF 339
#define XFMANIM 340
#define XFMSANIM 341
#define START_EGG 342
#define START_GROUP_BODY 343
#define START_TEXTURE_BODY 344
#define START_PRIMITIVE_BODY 345
#define PATCH 303
#define POINTLIGHT 304
#define POLYGON 305
#define REF 306
#define RGBA 307
#define ROTATE 308
#define ROTX 309
#define ROTY 310
#define ROTZ 311
#define SANIM 312
#define SCALAR 313
#define SCALE 314
#define SEQUENCE 315
#define SHADING 316
#define SWITCH 317
#define SWITCHCONDITION 318
#define TABLE 319
#define TABLE_V 320
#define TAG 321
#define TANGENT 322
#define TEXLIST 323
#define TEXTURE 324
#define TLENGTHS 325
#define TRANSFORM 326
#define TRANSLATE 327
#define TREF 328
#define TRIANGLEFAN 329
#define TRIANGLESTRIP 330
#define TRIM 331
#define TXT 332
#define UKNOTS 333
#define UV 334
#define AUX 335
#define VKNOTS 336
#define VERTEX 337
#define VERTEXANIM 338
#define VERTEXPOOL 339
#define VERTEXREF 340
#define XFMANIM 341
#define XFMSANIM 342
#define START_EGG 343
#define START_GROUP_BODY 344
#define START_TEXTURE_BODY 345
#define START_PRIMITIVE_BODY 346
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE eggyylval;

View File

@ -19,6 +19,7 @@
#include "eggCompositePrimitive.h"
#include "eggTriangleFan.h"
#include "eggTriangleStrip.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggLine.h"
#include "eggNurbsSurface.h"
@ -169,7 +170,7 @@ egg_cleanup_parser() {
%token JOINT KNOTS INCLUDE
%token INSTANCE LINE LOOP MATERIAL MATRIX3 MATRIX4 MODEL MREF NORMAL
%token NURBSCURVE NURBSSURFACE OBJECTTYPE ORDER
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
%token OUTTANGENT PATCH POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
%token TABLE TABLE_V TAG TANGENT TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
%token TREF TRIANGLEFAN TRIANGLESTRIP
@ -199,6 +200,7 @@ egg_cleanup_parser() {
%type <_egg> polygon
%type <_egg> trianglefan
%type <_egg> trianglestrip
%type <_egg> patch
%type <_egg> point_light
%type <_egg> nurbs_surface
%type <_egg> nurbs_curve
@ -272,6 +274,7 @@ node:
| polygon
| trianglefan
| trianglestrip
| patch
| point_light
| line
| nurbs_surface
@ -1886,6 +1889,25 @@ trianglestrip:
}
;
/*
* patch
*
* enter:
* exit: returns a new EggPatch.
*
*/
patch:
PATCH optional_name
{
egg_stack.push_back(new EggPatch($2));
}
'{' primitive_body '}'
{
$$ = egg_stack.back();
egg_stack.pop_back();
}
;
/*
* point_light
*

View File

@ -17,6 +17,7 @@
#include "eggPrimitive.h"
#include "eggNurbsSurface.h"
#include "eggNurbsCurve.h"
#include "eggPatch.h"
#include "eggSwitchCondition.h"
#include "eggGroup.h"
#include "dcast.h"
@ -62,6 +63,9 @@ get_bin_number(const EggNode *node) {
} else if (node->is_of_type(EggNurbsCurve::get_class_type())) {
return (int)BN_nurbs_curve;
} else if (node->is_of_type(EggPatch::get_class_type())) {
return (int)BN_patches;
} else if (node->is_of_type(EggPrimitive::get_class_type())) {
return (int)BN_polyset;
@ -84,7 +88,7 @@ get_bin_number(const EggNode *node) {
////////////////////////////////////////////////////////////////////
string EggBinner::
get_bin_name(int bin_number, const EggNode *child) {
if (bin_number == BN_polyset) {
if (bin_number == BN_polyset || bin_number == BN_patches) {
return DCAST(EggPrimitive, child)->get_sort_name();
}
@ -100,6 +104,7 @@ bool EggBinner::
sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
switch (bin_number) {
case BN_polyset:
case BN_patches:
{
const EggPrimitive *pa, *pb;
DCAST_INTO_R(pa, a, false);
@ -114,6 +119,16 @@ sorts_less(int bin_number, const EggNode *a, const EggNode *b) {
return (compare < 0);
}
if (bin_number == BN_patches) {
// For patches only, we group together patches of similar size.
const EggPatch *patch_a, *patch_b;
DCAST_INTO_R(patch_a, a, false);
DCAST_INTO_R(patch_b, b, false);
if (patch_a->size() != patch_b->size()) {
return patch_a->size() < patch_b->size();
}
}
// Also, if the primitive was given a name (that does not begin
// with a digit), it gets binned with similar-named primitives.
return pa->get_sort_name() < pb->get_sort_name();

View File

@ -41,6 +41,7 @@ public:
BN_lod,
BN_nurbs_surface,
BN_nurbs_curve,
BN_patches,
};
EggBinner(EggLoader &loader);

View File

@ -40,6 +40,7 @@
#include "geomLines.h"
#include "geomLinestrips.h"
#include "geomPoints.h"
#include "geomPatches.h"
#include "sequenceNode.h"
#include "switchNode.h"
#include "portalNode.h"
@ -50,6 +51,7 @@
#include "modelRoot.h"
#include "string_utils.h"
#include "eggPrimitive.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggLine.h"
#include "eggTextureCollection.h"
@ -356,7 +358,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform,
egg_bin->apply_first_attribute(false);
egg_bin->post_apply_flat_attribute(false);
// egg_bin->write(cerr, 0);
//egg_bin->write(cerr, 0);
PT(GeomNode) geom_node;
@ -1742,6 +1744,7 @@ make_node(EggBin *egg_bin, PandaNode *parent) {
// node (a parent of one or more similar EggPrimitives).
switch (egg_bin->get_bin_number()) {
case EggBinner::BN_polyset:
case EggBinner::BN_patches:
make_polyset(egg_bin, parent, NULL, _dynamic_override, _dynamic_override_char_maker);
return NULL;
@ -2615,6 +2618,10 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim,
} else if (egg_prim->is_of_type(EggPoint::get_class_type())) {
primitive = new GeomPoints(Geom::UH_static);
} else if (egg_prim->is_of_type(EggPatch::get_class_type())) {
int num_vertices = egg_prim->size();
primitive = new GeomPatches(num_vertices, Geom::UH_static);
}
if (primitive == (GeomPrimitive *)NULL) {

View File

@ -401,7 +401,7 @@ setup_antialias_point() {
// Function: GLGraphicsStateGuardian::setup_antialias_polygon
// Access: Protected
// Description: Sets the appropriate antialiasing modes to render a
// series of point primitives, according to
// series of polygon primitives, according to
// _auto_antialias_mode.
////////////////////////////////////////////////////////////////////
INLINE void CLP(GraphicsStateGuardian)::

View File

@ -955,7 +955,9 @@ reset() {
#ifdef OPENGLES_1
_supports_glsl = false;
#else
_supports_glsl = is_at_least_gl_version(2, 0);
_supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100");
_supports_geometry_shaders = is_at_least_gl_version(3, 2) || has_extension("GL_ARB_geometry_shader4");
_supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
#endif
#endif
_shader_caps._supports_glsl = _supports_glsl;
@ -1034,15 +1036,10 @@ reset() {
get_extension_func(GLPREFIX_QUOTED, "ValidateProgram");
_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
get_extension_func(GLPREFIX_QUOTED, "VertexAttribPointer");
}
#endif
#ifndef OPENGLES
if (has_extension("GL_EXT_geometry_shader4")) {
_glProgramParameteri = (PFNGLPROGRAMPARAMETERIEXTPROC)
get_extension_func(GLPREFIX_QUOTED, "ProgramParameteriEXT");
} else {
_glProgramParameteri = NULL;
_glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
get_extension_func(GLPREFIX_QUOTED, "ProgramParameteri");
_glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
get_extension_func(GLPREFIX_QUOTED, "PatchParameteri");
}
#endif
@ -2314,6 +2311,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
if (_auto_antialias_mode) {
switch (geom_reader->get_primitive_type()) {
case GeomPrimitive::PT_polygons:
case GeomPrimitive::PT_patches:
setup_antialias_polygon();
break;
case GeomPrimitive::PT_points:
@ -3141,6 +3139,80 @@ draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::draw_patches
// Access: Public, Virtual
// Description: Draws a series of "patches", which can only be
// processed by a tessellation shader.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
//PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
if (!get_supports_tessellation_shaders()) {
return false;
}
_glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_simple_primitives(reader, GL_PATCHES);
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
int num_vertices = reader->get_num_vertices();
_vertices_patch_pcollector.add_level(num_vertices);
_primitive_batches_patch_pcollector.add_level(1);
if (reader->is_indexed()) {
const unsigned char *client_pointer;
if (!setup_primitive(client_pointer, reader, force)) {
return false;
}
#ifndef OPENGLES
if (_supports_geometry_instancing && _instance_count > 0) {
_glDrawElementsInstanced(GL_PATCHES, num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer, _instance_count);
} else
#endif
{
_glDrawRangeElements(GL_PATCHES,
reader->get_min_vertex(),
reader->get_max_vertex(),
num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer);
}
} else {
#ifndef OPENGLES
if (_supports_geometry_instancing && _instance_count > 0) {
_glDrawArraysInstanced(GL_PATCHES,
reader->get_first_vertex(),
num_vertices, _instance_count);
} else
#endif
{
GLP(DrawArrays)(GL_PATCHES,
reader->get_first_vertex(),
num_vertices);
}
}
}
report_my_gl_errors();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GLGraphicsStateGuardian::draw_lines
// Access: Public, Virtual

View File

@ -150,7 +150,7 @@ typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLin
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length);
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
@ -217,6 +217,8 @@ public:
bool force);
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader,
bool force);
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader,
@ -681,7 +683,8 @@ public:
PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer;
#endif // OPENGLES_1
#ifndef OPENGLES
PFNGLPROGRAMPARAMETERIEXTPROC _glProgramParameteri;
PFNGLPROGRAMPARAMETERIPROC _glProgramParameteri;
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
#endif // OPENGLES

View File

@ -59,6 +59,8 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
_glsl_vshader = 0;
_glsl_fshader = 0;
_glsl_gshader = 0;
_glsl_tcshader = 0;
_glsl_teshader = 0;
#if defined(HAVE_CG) && !defined(OPENGLES)
_cg_context = 0;
if (s->get_language() == Shader::SL_Cg) {
@ -116,6 +118,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
if (s->get_language() == Shader::SL_GLSL) {
// We compile and analyze the shader here, instead of in shader.cxx, to avoid gobj getting a dependency on GL stuff.
if (_glsl_program == 0) {
gsg->report_my_gl_errors();
if (!glsl_compile_shader(gsg)) {
release_resources(gsg);
s->_error_flag = true;
@ -130,19 +133,22 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
GLenum param_type;
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORMS, &param_count);
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &param_maxlength);
char* param_name = new char[param_maxlength];
char* param_name_cstr = (char *)alloca(param_maxlength);
for (int i = 0; i < param_count; ++i) {
gsg->_glGetActiveUniform(_glsl_program, i, param_maxlength, NULL, &param_size, &param_type, param_name);
GLint p = gsg->_glGetUniformLocation(_glsl_program, param_name);
gsg->_glGetActiveUniform(_glsl_program, i, param_maxlength, NULL, &param_size, &param_type, param_name_cstr);
string param_name(param_name_cstr);
GLint p = gsg->_glGetUniformLocation(_glsl_program, param_name_cstr);
if (p > -1) {
Shader::ShaderArgId arg_id;
arg_id._name = param_name;
arg_id._seqno = seqno++;
s->_glsl_parameter_map.push_back(p);
PT(InternalName) inputname = InternalName::make(param_name);
if (inputname->get_name().substr(0, 4) == "p3d_" || inputname->get_name().substr(0, 3) == "gl_") {
if (inputname->get_name().substr(0, 3) == "gl_") noprefix = inputname->get_name().substr(3);
else noprefix = inputname->get_name().substr(4);
if (param_name.substr(0, 4) == "p3d_" || param_name.substr(0, 3) == "gl_") {
if (param_name.substr(0, 3) == "gl_") {
noprefix = param_name.substr(3);
} else {
noprefix = param_name.substr(4);
}
if (noprefix == "ModelViewProjectionMatrix") {
Shader::ShaderMatSpec bind;
@ -151,8 +157,10 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._func = Shader::SMF_compose;
bind._part[0] = Shader::SMO_model_to_view;
bind._arg[0] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
bind._part[1] = Shader::SMO_view_to_apiclip;
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_general | Shader::SSD_transform;
s->_mat_spec.push_back(bind);
continue;
}
@ -163,6 +171,10 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_model_to_view;
bind._arg[0] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue;
}
@ -173,6 +185,10 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_view_to_apiclip;
bind._arg[0] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue;
}
@ -185,7 +201,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
s->_tex_spec.push_back(bind);
continue;
}
GLCAT.error() << "Unrecognized uniform name '" << param_name << "'!\n";
GLCAT.error() << "Unrecognized uniform name '" << param_name_cstr << "'!\n";
continue;
}
@ -196,7 +212,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
case GL_SAMPLER_1D: {
Shader::ShaderTexSpec bind;
bind._id = arg_id;
bind._name = inputname;
bind._name = InternalName::make(param_name);;
bind._desired_type = Texture::TT_1d_texture;
bind._stage = texunitno++;
s->_tex_spec.push_back(bind);
@ -206,7 +222,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
case GL_SAMPLER_2D: {
Shader::ShaderTexSpec bind;
bind._id = arg_id;
bind._name = inputname;
bind._name = InternalName::make(param_name);;
bind._desired_type = Texture::TT_2d_texture;
bind._stage = texunitno++;
s->_tex_spec.push_back(bind);
@ -214,7 +230,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
case GL_SAMPLER_3D: {
Shader::ShaderTexSpec bind;
bind._id = arg_id;
bind._name = inputname;
bind._name = InternalName::make(param_name);;
bind._desired_type = Texture::TT_3d_texture;
bind._stage = texunitno++;
s->_tex_spec.push_back(bind);
@ -222,7 +238,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
case GL_SAMPLER_CUBE: {
Shader::ShaderTexSpec bind;
bind._id = arg_id;
bind._name = inputname;
bind._name = InternalName::make(param_name);;
bind._desired_type = Texture::TT_cube_map;
bind._stage = texunitno++;
s->_tex_spec.push_back(bind);
@ -245,11 +261,12 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._piece = Shader::SMP_whole;
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_mat_constant_x;
bind._arg[0] = inputname;
bind._arg[0] = InternalName::make(param_name);;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._part[1] = Shader::SMO_identity;
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
bind._dep[1] = Shader::SSD_general | Shader::SSD_NONE;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue; }
case GL_BOOL:
@ -274,11 +291,11 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
}
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_vec_constant_x;
bind._arg[0] = inputname;
bind._arg[0] = InternalName::make(param_name);;
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = NULL;
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
bind._dep[1] = Shader::SSD_general | Shader::SSD_NONE;
bind._dep[1] = Shader::SSD_NONE;
s->_mat_spec.push_back(bind);
continue; }
case GL_INT:
@ -327,10 +344,10 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
case GL_BOOL_VEC4:
case GL_FLOAT_VEC4: bind._dim[1] = 4; break;
}
bind._arg = inputname;
bind._arg = InternalName::make(param_name);;
bind._dim[0] = param_size;
bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
bind._dep[1] = Shader::SSD_general | Shader::SSD_NONE;
bind._dep[1] = Shader::SSD_NONE;
s->_ptr_spec.push_back(bind);
continue; }
case GL_INT:
@ -345,39 +362,40 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
}
}
}
delete[] param_name;
// Now we've processed the uniforms, we'll process the attribs.
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTES, &param_count);
gsg->_glGetProgramiv(_glsl_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &param_maxlength);
param_name = new char[param_maxlength];
param_name_cstr = (char *)alloca(param_maxlength);
for (int i = 0; i < param_count; ++i) {
gsg->_glGetActiveAttrib(_glsl_program, i, param_maxlength, NULL, &param_size, &param_type, param_name);
PT(InternalName) inputname = InternalName::make(param_name);
gsg->_glGetActiveAttrib(_glsl_program, i, param_maxlength, NULL, &param_size, &param_type, param_name_cstr);
string param_name(param_name_cstr);
if (inputname->get_name().substr(0, 3) == "gl_") {
if (param_name.substr(0, 3) == "gl_") {
// We shouldn't bind anything to these.
} else if (inputname->get_name().substr(0, 4) == "p3d_") {
noprefix = inputname->get_name().substr(4);
} else if (param_name.substr(0, 4) == "p3d_") {
noprefix = param_name.substr(4);
Shader::ShaderVarSpec bind;
bind._append_uv = -1;
if (noprefix == "Vertex") {
bind._name = InternalName::get_vertex();
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
if (noprefix == "Normal") {
bind._name = InternalName::get_normal();
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
if (noprefix == "Color") {
bind._name = InternalName::get_color();
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
if (noprefix.substr(0, 7) == "Tangent") {
@ -386,7 +404,7 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._append_uv = atoi(noprefix.substr(7).c_str());
}
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
if (noprefix.substr(0, 8) == "Binormal") {
@ -395,27 +413,27 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
bind._append_uv = atoi(noprefix.substr(8).c_str());
}
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
if (noprefix.substr(0, 13) == "MultiTexCoord") {
bind._name = InternalName::get_texcoord();
bind._append_uv = atoi(inputname->get_name().substr(13).c_str());
bind._append_uv = atoi(noprefix.substr(13).c_str());
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
continue;
}
GLCAT.error() << "Unrecognized vertex attrib '" << param_name << "'!\n";
continue;
} else {
Shader::ShaderVarSpec bind;
bind._name = inputname;
bind._name = InternalName::make(param_name);
bind._append_uv = -1;
s->_var_spec.push_back(bind);
gsg->_glBindAttribLocation(_glsl_program, i, param_name);
gsg->_glBindAttribLocation(_glsl_program, i, param_name_cstr);
}
}
delete[] param_name;
}
// Finally, re-link the program, or otherwise the glBindAttribLocation
@ -485,6 +503,12 @@ release_resources(GSG *gsg) {
if (_glsl_gshader != 0) {
gsg->_glDetachShader(_glsl_program, _glsl_gshader);
}
if (_glsl_tcshader != 0) {
gsg->_glDetachShader(_glsl_program, _glsl_tcshader);
}
if (_glsl_teshader != 0) {
gsg->_glDetachShader(_glsl_program, _glsl_teshader);
}
gsg->_glDeleteProgram(_glsl_program);
_glsl_program = 0;
}
@ -500,6 +524,14 @@ release_resources(GSG *gsg) {
gsg->_glDeleteShader(_glsl_gshader);
_glsl_gshader = 0;
}
if (_glsl_tcshader != 0) {
gsg->_glDeleteShader(_glsl_tcshader);
_glsl_tcshader = 0;
}
if (_glsl_teshader != 0) {
gsg->_glDeleteShader(_glsl_teshader);
_glsl_teshader = 0;
}
gsg->report_my_gl_errors();
}
@ -1111,7 +1143,7 @@ glsl_report_program_errors(GSG *gsg, unsigned int program) {
////////////////////////////////////////////////////////////////////
unsigned int CLP(ShaderContext)::
glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type) {
unsigned int handle;
unsigned int handle = 0;
switch (type) {
case Shader::ST_vertex:
handle = gsg->_glCreateShader(GL_VERTEX_SHADER);
@ -1120,26 +1152,44 @@ glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type) {
handle = gsg->_glCreateShader(GL_FRAGMENT_SHADER);
break;
case Shader::ST_geometry:
handle = gsg->_glCreateShader(GL_GEOMETRY_SHADER_EXT);
if (gsg->get_supports_geometry_shaders()) {
handle = gsg->_glCreateShader(GL_GEOMETRY_SHADER);
}
break;
case Shader::ST_tess_control:
if (gsg->get_supports_tessellation_shaders()) {
handle = gsg->_glCreateShader(GL_TESS_CONTROL_SHADER);
}
break;
case Shader::ST_tess_evaluation:
if (gsg->get_supports_tessellation_shaders()) {
handle = gsg->_glCreateShader(GL_TESS_EVALUATION_SHADER);
}
break;
default:
return 0;
}
if (!handle) {
gsg->report_my_gl_errors();
return 0;
}
string text_str = _shader->get_text(type);
const char* text = text_str.c_str();
gsg->_glShaderSource(handle, 1, &text, NULL);
gsg->_glCompileShader(handle);
GLint status;
gsg->_glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
GLCAT.error() << "An error occurred while compiling shader!\n";
GLCAT.error()
<< "An error occurred while compiling shader "
<< _shader->get_filename(type) << "\n";
glsl_report_shader_errors(gsg, handle);
gsg->_glDeleteShader(handle);
gsg->report_my_gl_errors();
return 0;
}
gsg->report_my_gl_errors();
return handle;
}
@ -1169,16 +1219,29 @@ glsl_compile_shader(GSG *gsg) {
_glsl_gshader = glsl_compile_entry_point(gsg, Shader::ST_geometry);
if (!_glsl_gshader) return false;
gsg->_glAttachShader(_glsl_program, _glsl_gshader);
#ifdef OPENGLES
nassertr(false, false); // OpenGL ES has no geometry shaders.
#else
// Set the vertex output limit to the maximum
nassertr(gsg->_glProgramParameteri != NULL, false);
GLint max_vertices;
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &max_vertices);
gsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_EXT, max_vertices);
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_vertices);
gsg->_glProgramParameteri(_glsl_program, GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices);
#endif
gsg->report_my_gl_errors();
}
if (!_shader->get_text(Shader::ST_tess_control).empty()) {
_glsl_tcshader = glsl_compile_entry_point(gsg, Shader::ST_tess_control);
if (!_glsl_tcshader) return false;
gsg->_glAttachShader(_glsl_program, _glsl_tcshader);
}
if (!_shader->get_text(Shader::ST_tess_evaluation).empty()) {
_glsl_teshader = glsl_compile_entry_point(gsg, Shader::ST_tess_evaluation);
if (!_glsl_teshader) return false;
gsg->_glAttachShader(_glsl_program, _glsl_teshader);
}
// There might be warnings. Only report them for one shader program.
@ -1188,6 +1251,10 @@ glsl_compile_shader(GSG *gsg) {
glsl_report_shader_errors(gsg, _glsl_fshader);
} else if (_glsl_gshader != 0) {
glsl_report_shader_errors(gsg, _glsl_gshader);
} else if (_glsl_tcshader != 0) {
glsl_report_shader_errors(gsg, _glsl_tcshader);
} else if (_glsl_teshader != 0) {
glsl_report_shader_errors(gsg, _glsl_teshader);
}
gsg->_glLinkProgram(_glsl_program);

View File

@ -64,6 +64,8 @@ private:
GLuint _glsl_vshader;
GLuint _glsl_fshader;
GLuint _glsl_gshader;
GLuint _glsl_tcshader;
GLuint _glsl_teshader;
int _stage_offset;
// Avoid using this! It merely exists so the

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
geomEnums.h \
geomMunger.h geomMunger.I \
geomPrimitive.h geomPrimitive.I \
geomPatches.h \
geomTriangles.h \
geomTristrips.h \
geomTrifans.h \
@ -91,6 +92,7 @@
geomEnums.cxx \
geomMunger.cxx \
geomPrimitive.cxx \
geomPatches.cxx \
geomTriangles.cxx \
geomTristrips.cxx \
geomTrifans.cxx \
@ -162,6 +164,7 @@
geomEnums.h \
geomMunger.h geomMunger.I \
geomPrimitive.h geomPrimitive.I \
geomPatches.h \
geomTriangles.h \
geomTristrips.h \
geomTrifans.h \

View File

@ -23,6 +23,7 @@
#include "geomTriangles.h"
#include "geomTristrips.h"
#include "geomTrifans.h"
#include "geomPatches.h"
#include "geomLines.h"
#include "geomLinestrips.h"
#include "geomPoints.h"
@ -525,6 +526,7 @@ ConfigureFn(config_gobj) {
GeomTriangles::init_type();
GeomTrifans::init_type();
GeomTristrips::init_type();
GeomPatches::init_type();
GeomVertexArrayData::init_type();
GeomVertexArrayDataHandle::init_type();
GeomVertexArrayFormat::init_type();
@ -570,6 +572,7 @@ ConfigureFn(config_gobj) {
GeomTriangles::register_with_read_factory();
GeomTrifans::register_with_read_factory();
GeomTristrips::register_with_read_factory();
GeomPatches::register_with_read_factory();
GeomVertexArrayData::register_with_read_factory();
GeomVertexArrayFormat::register_with_read_factory();
GeomVertexData::register_with_read_factory();

View File

@ -170,7 +170,8 @@ PUBLISHED:
PT_none,
PT_polygons,
PT_lines,
PT_points
PT_points,
PT_patches
};
// The numeric type determines what physical representation is used

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomLines(UsageHint usage_hint);
GeomLines(const GeomLines &copy);
virtual ~GeomLines();
ALLOC_DELETED_CHAIN(GeomLines);
public:
virtual PT(GeomPrimitive) make_copy() const;

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomLinestrips(UsageHint usage_hint);
GeomLinestrips(const GeomLinestrips &copy);
virtual ~GeomLinestrips();
ALLOC_DELETED_CHAIN(GeomLinestrips);
public:
virtual PT(GeomPrimitive) make_copy() const;

172
panda/src/gobj/geomPatches.cxx Executable file
View File

@ -0,0 +1,172 @@
// Filename: geomPatches.cxx
// Created by: drose (27Apr12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "geomPatches.h"
#include "geomVertexRewriter.h"
#include "pStatTimer.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "graphicsStateGuardianBase.h"
TypeHandle GeomPatches::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::Constructor
// Access: Published
// Description: The number of vertices per patch must be specified to
// the GeomPatches constructor, and it may not be
// changed during the lifetime of the GeomPatches
// object. Create a new GeomPatches if you need to have
// a different value.
////////////////////////////////////////////////////////////////////
GeomPatches::
GeomPatches(int num_vertices_per_patch, GeomPatches::UsageHint usage_hint) :
GeomPrimitive(usage_hint),
_num_vertices_per_patch(num_vertices_per_patch)
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
GeomPatches::
GeomPatches(const GeomPatches &copy) :
GeomPrimitive(copy),
_num_vertices_per_patch(copy._num_vertices_per_patch)
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
GeomPatches::
~GeomPatches() {
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::make_copy
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
PT(GeomPrimitive) GeomPatches::
make_copy() const {
return new GeomPatches(*this);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::get_primitive_type
// Access: Public, Virtual
// Description: Returns the fundamental rendering type of this
// primitive: whether it is points, lines, or polygons.
//
// This is used to set up the appropriate antialiasing
// settings when AntialiasAttrib::M_auto is in effect;
// it also implies the type of primitive that will be
// produced when decompose() is called.
////////////////////////////////////////////////////////////////////
GeomPrimitive::PrimitiveType GeomPatches::
get_primitive_type() const {
return PT_patches;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::get_num_vertices_per_primitive
// Access: Public, Virtual
// Description: If the primitive type is a simple type in which all
// primitives have the same number of vertices, like
// patches, returns the number of vertices per
// primitive. If the primitive type is a more complex
// type in which different primitives might have
// different numbers of vertices, for instance a
// triangle strip, returns 0.
//
// In the case of GeomPatches, this returns the fixed
// number that was specified to the constructor.
////////////////////////////////////////////////////////////////////
int GeomPatches::
get_num_vertices_per_primitive() const {
return _num_vertices_per_patch;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::draw
// Access: Public, Virtual
// Description: Calls the appropriate method on the GSG to draw the
// primitive.
////////////////////////////////////////////////////////////////////
bool GeomPatches::
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader,
bool force) const {
return gsg->draw_patches(reader, force);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// Geom.
////////////////////////////////////////////////////////////////////
void GeomPatches::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void GeomPatches::
write_datagram(BamWriter *manager, Datagram &dg) {
GeomPrimitive::write_datagram(manager, dg);
dg.add_uint16(_num_vertices_per_patch);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new GeomPatches.
////////////////////////////////////////////////////////////////////
void GeomPatches::
fillin(DatagramIterator &scan, BamReader *manager) {
GeomPrimitive::fillin(scan, manager);
_num_vertices_per_patch = scan.get_uint16();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPatches::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type Geom is encountered
// in the Bam file. It should create the Geom
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *GeomPatches::
make_from_bam(const FactoryParams &params) {
GeomPatches *object = new GeomPatches(0, UH_unspecified);
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
object->fillin(scan, manager);
return object;
}

76
panda/src/gobj/geomPatches.h Executable file
View File

@ -0,0 +1,76 @@
// Filename: geomPatches.h
// Created by: drose (27Apr12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef GEOMPATCHES_H
#define GEOMPATCHES_H
#include "pandabase.h"
#include "geomPrimitive.h"
////////////////////////////////////////////////////////////////////
// Class : GeomPatches
// Description : Defines a series of "patches", fixed-size groupings
// of vertices that must be processed by a tessellation
// shader.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ GeomPatches : public GeomPrimitive {
PUBLISHED:
GeomPatches(int num_vertices_per_patch, UsageHint usage_hint);
GeomPatches(const GeomPatches &copy);
virtual ~GeomPatches();
ALLOC_DELETED_CHAIN(GeomPatches);
public:
virtual PT(GeomPrimitive) make_copy() const;
virtual PrimitiveType get_primitive_type() const;
virtual int get_num_vertices_per_primitive() const;
public:
virtual bool draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader,
bool force) const;
private:
int _num_vertices_per_patch;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
void fillin(DatagramIterator &scan, BamReader *manager);
static TypedWritable *make_from_bam(const FactoryParams &params);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GeomPrimitive::init_type();
register_type(_type_handle, "GeomPatches",
GeomPrimitive::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class Geom;
};
#endif

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomPoints(UsageHint usage_hint);
GeomPoints(const GeomPoints &copy);
virtual ~GeomPoints();
ALLOC_DELETED_CHAIN(GeomPoints);
public:
virtual PT(GeomPrimitive) make_copy() const;

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomTriangles(UsageHint usage_hint);
GeomTriangles(const GeomTriangles &copy);
virtual ~GeomTriangles();
ALLOC_DELETED_CHAIN(GeomTriangles);
public:
virtual PT(GeomPrimitive) make_copy() const;

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomTrifans(UsageHint usage_hint);
GeomTrifans(const GeomTrifans &copy);
virtual ~GeomTrifans();
ALLOC_DELETED_CHAIN(GeomTrifans);
public:
virtual PT(GeomPrimitive) make_copy() const;

View File

@ -27,6 +27,7 @@ PUBLISHED:
GeomTristrips(UsageHint usage_hint);
GeomTristrips(const GeomTristrips &copy);
virtual ~GeomTristrips();
ALLOC_DELETED_CHAIN(GeomTristrips);
public:
virtual PT(GeomPrimitive) make_copy() const;

View File

@ -12,6 +12,7 @@
#include "geomLines.cxx"
#include "geomLinestrips.cxx"
#include "geomMunger.cxx"
#include "geomPatches.cxx"
#include "geomPoints.cxx"
#include "geomPrimitive.cxx"
#include "geomTriangles.cxx"

View File

@ -59,6 +59,12 @@ get_text(const ShaderType &type) const {
case ST_geometry:
return _text->_geometry;
break;
case ST_tess_control:
return _text->_tess_control;
break;
case ST_tess_evaluation:
return _text->_tess_evaluation;
break;
default:
return _text->_shared;
}

View File

@ -1384,6 +1384,12 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, ShaderType typ
ultimate = caps._ultimate_gprofile;
break;
case ST_tess_evaluation:
case ST_tess_control:
active = caps._active_tprofile;
ultimate = caps._ultimate_tprofile;
break;
case ST_none:
default:
active = CG_PROFILE_UNKNOWN;
@ -1875,6 +1881,7 @@ Shader(CPT(ShaderFile) filename, CPT(ShaderFile) text, const ShaderLanguage &lan
if (_default_caps._ultimate_vprofile == 0 || _default_caps._ultimate_vprofile == CG_PROFILE_UNKNOWN) {
_default_caps._active_vprofile = CG_PROFILE_UNKNOWN;
_default_caps._active_fprofile = CG_PROFILE_UNKNOWN;
_default_caps._active_gprofile = CG_PROFILE_UNKNOWN;
_default_caps._ultimate_vprofile = cgGetProfile("glslv");
_default_caps._ultimate_fprofile = cgGetProfile("glslf");
_default_caps._ultimate_gprofile = cgGetProfile("glslg");
@ -2090,9 +2097,11 @@ load(const Filename &file, const ShaderLanguage &lang) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->read_file(file, sbody->_shared, true)) {
gobj_cat.error() << "Could not read shader file: " << file << "\n";
gobj_cat.error()
<< "Could not read shader file: " << file << "\n";
return NULL;
}
PT(Shader) result = new Shader(sfile, sbody, lang);
result->_loaded = true;
_load_table[sfile] = result;
@ -2106,26 +2115,43 @@ load(const Filename &file, const ShaderLanguage &lang) {
// programs separately.
////////////////////////////////////////////////////////////////////
PT(Shader) Shader::
load(const ShaderLanguage &lang, const Filename &vertex, const Filename &fragment, const Filename &geometry) {
PT(ShaderFile) sfile = new ShaderFile(vertex, fragment, geometry);
load(const ShaderLanguage &lang, const Filename &vertex,
const Filename &fragment, const Filename &geometry,
const Filename &tess_control, const Filename &tess_evaluation) {
PT(ShaderFile) sfile = new ShaderFile(vertex, fragment, geometry, tess_control, tess_evaluation);
ShaderTable::const_iterator i = _load_table.find(sfile);
if (i != _load_table.end() && (lang == SL_none || lang == i->second->_language)) {
return i->second;
}
PT(ShaderFile) sbody = new ShaderFile("", "", "");
PT(ShaderFile) sbody = new ShaderFile("", "", "", "", "");
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vertex.empty() && !vfs->read_file(vertex, sbody->_vertex, true)) {
gobj_cat.error() << "Could not read vertex shader file: " << vertex << "\n";
gobj_cat.error()
<< "Could not read vertex shader file: " << vertex << "\n";
return NULL;
}
if (!fragment.empty() && !vfs->read_file(fragment, sbody->_fragment, true)) {
gobj_cat.error() << "Could not read fragment shader file: " << vertex << "\n";
gobj_cat.error()
<< "Could not read fragment shader file: " << fragment << "\n";
return NULL;
}
if (!geometry.empty() && !vfs->read_file(geometry, sbody->_geometry, true)) {
gobj_cat.error() << "Could not read geometry shader file: " << vertex << "\n";
gobj_cat.error()
<< "Could not read geometry shader file: " << geometry << "\n";
return NULL;
}
if (!tess_control.empty() && !vfs->read_file(tess_control, sbody->_tess_control, true)) {
gobj_cat.error()
<< "Could not read tess_control shader file: " << tess_control << "\n";
return NULL;
}
if (!tess_evaluation.empty() && !vfs->read_file(tess_evaluation, sbody->_tess_evaluation, true)) {
gobj_cat.error()
<< "Could not read tess_evaluation shader file: " << tess_evaluation << "\n";
return NULL;
}
PT(Shader) result = new Shader(sfile, sbody, lang);
result->_loaded = true;
_load_table[sfile] = result;
@ -2167,12 +2193,16 @@ make(const string &body, const ShaderLanguage &lang) {
// Description: Loads the shader, using the strings as shader bodies.
//////////////////////////////////////////////////////////////////////
PT(Shader) Shader::
make(const ShaderLanguage &lang, const string &vertex, const string &fragment, const string &geometry) {
PT(ShaderFile) sbody = new ShaderFile(vertex, fragment, geometry);
make(const ShaderLanguage &lang, const string &vertex, const string &fragment,
const string &geometry, const string &tess_control,
const string &tess_evaluation) {
PT(ShaderFile) sbody = new ShaderFile(vertex, fragment, geometry, tess_control, tess_evaluation);
ShaderTable::const_iterator i = _make_table.find(sbody);
if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
return i->second;
}
PT(ShaderFile) sfile = new ShaderFile("created-shader");
PT(Shader) result = new Shader(sfile, sbody, lang);
_make_table[sbody] = result;
@ -2425,9 +2455,11 @@ clear() {
_active_vprofile = CG_PROFILE_UNKNOWN;
_active_fprofile = CG_PROFILE_UNKNOWN;
_active_gprofile = CG_PROFILE_UNKNOWN;
_active_fprofile = CG_PROFILE_UNKNOWN;
_ultimate_vprofile = CG_PROFILE_UNKNOWN;
_ultimate_fprofile = CG_PROFILE_UNKNOWN;
_ultimate_gprofile = CG_PROFILE_UNKNOWN;
_ultimate_fprofile = CG_PROFILE_UNKNOWN;
#endif
}

View File

@ -59,6 +59,8 @@ PUBLISHED:
ST_vertex,
ST_fragment,
ST_geometry,
ST_tess_control,
ST_tess_evaluation,
};
enum AutoShaderSwitch {
@ -79,8 +81,16 @@ PUBLISHED:
static PT(Shader) load(const Filename &file, const ShaderLanguage &lang = SL_none);
static PT(Shader) make(const string &body, const ShaderLanguage &lang = SL_none);
static PT(Shader) load(const ShaderLanguage &lang, const Filename &vertex, const Filename &fragment, const Filename &geometry = "");
static PT(Shader) make(const ShaderLanguage &lang, const string &vertex, const string &fragment, const string &geometry = "");
static PT(Shader) load(const ShaderLanguage &lang,
const Filename &vertex, const Filename &fragment,
const Filename &geometry = "",
const Filename &tess_control = "",
const Filename &tess_evaluation = "");
static PT(Shader) make(const ShaderLanguage &lang,
const string &vertex, const string &fragment,
const string &geometry = "",
const string &tess_control = "",
const string &tess_evaluation = "");
INLINE const Filename get_filename(const ShaderType &type = ST_none) const;
INLINE const string &get_text(const ShaderType &type = ST_none) const;
@ -336,36 +346,57 @@ public:
ShaderArgInfo _info;
};
struct ShaderCaps {
class ShaderCaps {
public:
void clear();
INLINE bool operator == (const ShaderCaps &other) const;
INLINE ShaderCaps();
public:
bool _supports_glsl;
#ifdef HAVE_CG
int _active_vprofile;
int _active_fprofile;
int _active_gprofile;
int _active_tprofile;
int _ultimate_vprofile;
int _ultimate_fprofile;
int _ultimate_gprofile;
int _ultimate_tprofile;
pset <ShaderBug> _bug_list;
#endif
void clear();
INLINE bool operator == (const ShaderCaps &other) const;
INLINE ShaderCaps();
};
struct ShaderFile : public ReferenceCount {
ShaderFile(string shared) { _separate = false; _shared = shared; }
ShaderFile(string vertex, string fragment, string geometry = "") {
_separate = true; _vertex = vertex;
_fragment = fragment; _geometry = geometry;
class ShaderFile : public ReferenceCount {
public:
ShaderFile(const string &shared) {
_separate = false;
_shared = shared;
}
ShaderFile(const string &vertex,
const string &fragment,
const string &geometry,
const string &tess_control,
const string &tess_evaluation) {
_separate = true;
_vertex = vertex;
_fragment = fragment;
_geometry = geometry;
_tess_control = tess_control;
_tess_evaluation = tess_evaluation;
}
public:
bool _separate;
string _shared;
string _vertex;
string _fragment;
string _geometry;
string _tess_control;
string _tess_evaluation;
};
private:

View File

@ -200,6 +200,7 @@ public:
virtual bool draw_triangles(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_trifans(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_patches(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_lines(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force)=0;
virtual bool draw_points(const GeomPrimitivePipelineReader *reader, bool force)=0;

View File

@ -204,6 +204,16 @@ get_num_points() const {
return _num_points;
}
////////////////////////////////////////////////////////////////////
// Function: SceneGraphAnalyzer::get_num_patches
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
int SceneGraphAnalyzer::
get_num_patches() const {
return _num_patches;
}
////////////////////////////////////////////////////////////////////
// Function: SceneGraphAnalyzer::get_num_individual_tris
@ -255,6 +265,16 @@ get_num_triangles_in_fans() const {
return _num_triangles_in_fans;
}
////////////////////////////////////////////////////////////////////
// Function: SceneGraphAnalyzer::get_num_vertices_in_patches
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
int SceneGraphAnalyzer::
get_num_vertices_in_patches() const {
return _num_vertices_in_patches;
}
////////////////////////////////////////////////////////////////////
// Function: SceneGraphAnalyzer::get_texture_bytes

View File

@ -27,6 +27,7 @@
#include "geomTriangles.h"
#include "geomTristrips.h"
#include "geomTrifans.h"
#include "geomPatches.h"
#include "transformState.h"
#include "textureAttrib.h"
#include "pta_ushort.h"
@ -88,12 +89,14 @@ clear() {
_num_tris = 0;
_num_lines = 0;
_num_points = 0;
_num_patches = 0;
_num_individual_tris = 0;
_num_tristrips = 0;
_num_triangles_in_strips = 0;
_num_trifans = 0;
_num_triangles_in_fans = 0;
_num_vertices_in_patches = 0;
_texture_bytes = 0;
@ -254,6 +257,13 @@ write(ostream &out, int indent_level) const {
<< _num_individual_tris
<< " of these are independent triangles.\n";
if (_num_patches != 0) {
indent(out, indent_level)
<< _num_patches << " patches ("
<< (double)_num_vertices_in_patches / (double)_num_patches
<< " average verts per patch).\n";
}
if (_num_lines != 0 || _num_points != 0) {
indent(out, indent_level)
<< _num_lines << " lines, " << _num_points << " points.\n";
@ -474,6 +484,10 @@ collect_statistics(const Geom *geom) {
_num_trifans += prim->get_num_primitives();
_num_triangles_in_fans += prim->get_num_faces();
} else if (prim->is_of_type(GeomPatches::get_class_type())) {
_num_patches += prim->get_num_primitives();
_num_vertices_in_patches += prim->get_num_vertices();
} else {
pgraph_cat.warning()
<< "Unknown GeomPrimitive type in SceneGraphAnalyzer: "

View File

@ -74,12 +74,14 @@ PUBLISHED:
INLINE int get_num_tris() const;
INLINE int get_num_lines() const;
INLINE int get_num_points() const;
INLINE int get_num_patches() const;
INLINE int get_num_individual_tris() const;
INLINE int get_num_tristrips() const;
INLINE int get_num_triangles_in_strips() const;
INLINE int get_num_trifans() const;
INLINE int get_num_triangles_in_fans() const;
INLINE int get_num_vertices_in_patches() const;
INLINE int get_texture_bytes() const;
@ -141,12 +143,14 @@ private:
int _num_tris;
int _num_lines;
int _num_points;
int _num_patches;
int _num_individual_tris;
int _num_tristrips;
int _num_triangles_in_strips;
int _num_trifans;
int _num_triangles_in_fans;
int _num_vertices_in_patches;
int _texture_bytes;

View File

@ -39,6 +39,7 @@
#include "geomNode.h"
#include "geom.h"
#include "geomTriangles.h"
#include "geomPatches.h"
#include "geomPoints.h"
#include "geomLines.h"
#include "geomVertexReader.h"
@ -59,6 +60,7 @@
#include "eggVertex.h"
#include "eggPrimitive.h"
#include "eggPolygon.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggLine.h"
#include "eggTexture.h"
@ -747,6 +749,8 @@ convert_primitive(const GeomVertexData *vertex_data,
if (primitive->is_of_type(GeomTriangles::get_class_type())) {
make_func = make_egg_polygon;
} else if (primitive->is_of_type(GeomPatches::get_class_type())) {
make_func = make_egg_patch;
} else if (primitive->is_of_type(GeomPoints::get_class_type())) {
make_func = make_egg_point;
} else if (primitive->is_of_type(GeomLines::get_class_type())) {
@ -1156,6 +1160,16 @@ make_egg_polygon() {
return new EggPolygon;
}
////////////////////////////////////////////////////////////////////
// Function: BamToEgg::make_egg_patch
// Access: Public, Static
// Description: A factory function to make a new EggPatch instance.
////////////////////////////////////////////////////////////////////
EggPrimitive *BamToEgg::
make_egg_patch() {
return new EggPatch;
}
////////////////////////////////////////////////////////////////////
// Function: BamToEgg::make_egg_point
// Access: Public, Static

View File

@ -92,6 +92,7 @@ private:
EggTexture *get_egg_texture(Texture *tex);
static EggPrimitive *make_egg_polygon();
static EggPrimitive *make_egg_patch();
static EggPrimitive *make_egg_point();
static EggPrimitive *make_egg_line();