Rewrite ShaderGeometry to use display lists and OSG primitives.
Based on a patch from Yon Uriarte. Eliminate _trees list from ShaderGeometry Use the position and scale values that are already available.
This commit is contained in:
@@ -25,35 +25,52 @@
|
|||||||
|
|
||||||
#include "ShaderGeometry.hxx"
|
#include "ShaderGeometry.hxx"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
using namespace osgDB;
|
using namespace osgDB;
|
||||||
|
|
||||||
namespace simgear
|
namespace simgear
|
||||||
{
|
{
|
||||||
void ShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
|
void ShaderGeometry::addTree(const TreeBin::Tree& t)
|
||||||
{
|
{
|
||||||
osg::State& state = *renderInfo.getState();
|
if (!getVertexArray()) {
|
||||||
const Extensions* extensions = getExtensions(state.getContextID(),true);
|
setVertexData(_geometry->getVertexData());
|
||||||
|
setNormalData(_geometry->getNormalData());
|
||||||
for(TreeBin::TreeList::const_iterator t = _trees.begin(); t != _trees.end(); ++t)
|
setTexCoordData(0, _geometry->getTexCoordData(0));
|
||||||
{
|
setColorArray(new Vec4Array());
|
||||||
extensions->glVertexAttrib1f(1, (float) t->texture_index/varieties);
|
setColorBinding(Geometry::BIND_PER_PRIMITIVE_SET);
|
||||||
glColor4f(t->position.x(), t->position.y(), t->position.z(), t->scale);
|
setVertexAttribArray(1, new FloatArray());
|
||||||
_geometry->draw(renderInfo);
|
setVertexAttribBinding(1, Geometry::BIND_PER_PRIMITIVE_SET);
|
||||||
}
|
}
|
||||||
|
Geometry::PrimitiveSetList& modelSets = _geometry->getPrimitiveSetList();
|
||||||
|
size_t numSets = modelSets.size();
|
||||||
|
Vec4Array *colors = static_cast<Vec4Array*>(getColorArray());
|
||||||
|
FloatArray *vertexAttribs
|
||||||
|
= static_cast<FloatArray*>(getVertexAttribArray(1));
|
||||||
|
colors->insert(colors->end(), numSets, Vec4(t.position.osg(), t.scale));
|
||||||
|
vertexAttribs->insert(vertexAttribs->end(), numSets,
|
||||||
|
(float)t.texture_index / varieties);
|
||||||
|
_primitives.insert(_primitives.end(), modelSets.begin(), modelSets.end());
|
||||||
|
dirtyDisplayList();
|
||||||
|
dirtyBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBox ShaderGeometry::computeBound() const
|
BoundingBox ShaderGeometry::computeBound() const
|
||||||
{
|
{
|
||||||
BoundingBox geom_box = _geometry->getBound();
|
BoundingBox geom_box = _geometry->getBound();
|
||||||
BoundingBox bb;
|
BoundingBox bb;
|
||||||
for(TreeBin::TreeList::const_iterator itr = _trees.begin();
|
unsigned numSets = _geometry->getNumPrimitiveSets();
|
||||||
itr != _trees.end();
|
const Vec4Array* posScales = static_cast<const Vec4Array*>(getColorArray());
|
||||||
++itr) {
|
if (!posScales)
|
||||||
bb.expandBy(geom_box.corner(0)*itr->scale +
|
return bb;
|
||||||
osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() ));
|
size_t numPosScales = posScales->size();
|
||||||
bb.expandBy(geom_box.corner(7)*itr->scale +
|
for (int i = 0; i < numPosScales; i += numSets) {
|
||||||
osg::Vec3( itr->position.x(), itr->position.y(), itr->position.z() ));
|
const Vec4& posScale((*posScales)[i]);
|
||||||
|
const float scale = posScale.w();
|
||||||
|
const Vec3 pos(posScale.x(), posScale.y(), posScale.z());
|
||||||
|
for (unsigned j = 0; j < 7; ++j)
|
||||||
|
bb.expandBy(geom_box.corner(j) * scale + pos);
|
||||||
}
|
}
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
@@ -67,34 +84,11 @@ bool ShaderGeometry_readLocalData(Object& obj, Input& fr)
|
|||||||
if ((fr[0].matchWord("geometry"))) {
|
if ((fr[0].matchWord("geometry"))) {
|
||||||
++fr;
|
++fr;
|
||||||
iteratorAdvanced = true;
|
iteratorAdvanced = true;
|
||||||
osg::Drawable* drawable = fr.readDrawable();
|
osg::Geometry* drawable = dynamic_cast<osg::Geometry*>(fr.readDrawable());
|
||||||
if (drawable) {
|
if (drawable) {
|
||||||
geom._geometry = drawable;
|
geom._geometry = drawable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((fr.matchSequence("instances %i"))) {
|
|
||||||
int entry = fr[0].getNoNestedBrackets();
|
|
||||||
int capacity;
|
|
||||||
fr[1].getInt(capacity);
|
|
||||||
geom._trees.reserve(capacity);
|
|
||||||
fr += 3;
|
|
||||||
iteratorAdvanced = true;
|
|
||||||
// skip {
|
|
||||||
while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
|
|
||||||
SGVec3f v;
|
|
||||||
int t;
|
|
||||||
float s;
|
|
||||||
if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())
|
|
||||||
&& fr[2].getFloat(v.z()) && fr[3].getInt(t) && fr[4].getFloat(s)) {
|
|
||||||
fr += 4;
|
|
||||||
//SGVec3f* v = new SGVec3f(v.x(), v.y(), v.z());
|
|
||||||
//TreeBin::Tree tree = new TreeBin::Tree(v, t, s);
|
|
||||||
geom._trees.push_back(TreeBin::Tree(v, t, s));
|
|
||||||
} else {
|
|
||||||
++fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return iteratorAdvanced;
|
return iteratorAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,18 +98,6 @@ bool ShaderGeometry_writeLocalData(const Object& obj, Output& fw)
|
|||||||
|
|
||||||
fw.indent() << "geometry" << std::endl;
|
fw.indent() << "geometry" << std::endl;
|
||||||
fw.writeObject(*geom._geometry);
|
fw.writeObject(*geom._geometry);
|
||||||
fw.indent() << "instances " << geom._trees.size() << std::endl;
|
|
||||||
fw.indent() << "{" << std::endl;
|
|
||||||
fw.moveIn();
|
|
||||||
for (TreeBin::TreeList::const_iterator iter
|
|
||||||
= geom._trees.begin();
|
|
||||||
iter != geom._trees.end();
|
|
||||||
++iter) {
|
|
||||||
fw.indent() << iter->position.x() << " " << iter->position.y() << " " << iter->position.z() << " "
|
|
||||||
<< iter->texture_index << " " << iter->scale << std::endl;
|
|
||||||
}
|
|
||||||
fw.moveOut();
|
|
||||||
fw.indent() << "}" << std::endl;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,8 +105,9 @@ osgDB::RegisterDotOsgWrapperProxy shaderGeometryProxy
|
|||||||
(
|
(
|
||||||
new ShaderGeometry,
|
new ShaderGeometry,
|
||||||
"ShaderGeometry",
|
"ShaderGeometry",
|
||||||
"Object Drawable ShaderGeometry",
|
"Object Drawable Geometry ShaderGeometry",
|
||||||
&ShaderGeometry_readLocalData,
|
&ShaderGeometry_readLocalData,
|
||||||
&ShaderGeometry_writeLocalData
|
&ShaderGeometry_writeLocalData
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,45 +37,36 @@
|
|||||||
namespace simgear
|
namespace simgear
|
||||||
{
|
{
|
||||||
|
|
||||||
class ShaderGeometry : public osg::Drawable
|
class ShaderGeometry : public osg::Geometry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShaderGeometry()
|
ShaderGeometry() :
|
||||||
|
varieties(1)
|
||||||
{
|
{
|
||||||
setUseDisplayList(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderGeometry(int v) :
|
ShaderGeometry(int v) :
|
||||||
varieties(v)
|
varieties(v)
|
||||||
{
|
{
|
||||||
setUseDisplayList(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||||
ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
ShaderGeometry(const ShaderGeometry& ShaderGeometry,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
|
||||||
osg::Drawable(ShaderGeometry,copyop) {}
|
osg::Geometry(ShaderGeometry,copyop) {}
|
||||||
|
|
||||||
META_Object(flightgear, ShaderGeometry);
|
META_Object(flightgear, ShaderGeometry);
|
||||||
|
|
||||||
typedef std::vector<osg::Vec4> PositionSizeList;
|
|
||||||
|
|
||||||
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
|
|
||||||
virtual osg::BoundingBox computeBound() const;
|
virtual osg::BoundingBox computeBound() const;
|
||||||
|
|
||||||
|
|
||||||
void setGeometry(osg::Drawable* geometry)
|
void setGeometry(osg::Geometry* geometry)
|
||||||
{
|
{
|
||||||
_geometry = geometry;
|
_geometry = geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTree(TreeBin::Tree tree)
|
void addTree(const TreeBin::Tree& tree);
|
||||||
{
|
|
||||||
_trees.push_back(tree);
|
osg::ref_ptr<osg::Geometry> _geometry;
|
||||||
}
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Drawable> _geometry;
|
|
||||||
|
|
||||||
TreeBin::TreeList _trees;
|
|
||||||
int varieties;
|
int varieties;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -128,11 +128,17 @@ osg::Geometry* createOrthQuads(float w, float h, int varieties, const osg::Matri
|
|||||||
|
|
||||||
static char vertexShaderSource[] =
|
static char vertexShaderSource[] =
|
||||||
"varying float fogFactor;\n"
|
"varying float fogFactor;\n"
|
||||||
|
#ifndef TSG_PACKED_ATTRIBUTES
|
||||||
"attribute float textureIndex;\n"
|
"attribute float textureIndex;\n"
|
||||||
|
#endif
|
||||||
"\n"
|
"\n"
|
||||||
"void main(void)\n"
|
"void main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
#ifdef TSG_PACKED_ATTRIBUTES
|
||||||
|
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
|
||||||
|
#else
|
||||||
" gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndex, 0.0, 0.0, 0.0);\n"
|
" gl_TexCoord[0] = gl_MultiTexCoord0 + vec4(textureIndex, 0.0, 0.0, 0.0);\n"
|
||||||
|
#endif
|
||||||
" vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz;\n"
|
" vec3 position = gl_Vertex.xyz * gl_Color.w + gl_Color.xyz;\n"
|
||||||
" gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
|
" gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
|
||||||
" vec3 ecPosition = vec3(gl_ModelViewMatrix * vec4(position, 1.0));\n"
|
" vec3 ecPosition = vec3(gl_ModelViewMatrix * vec4(position, 1.0));\n"
|
||||||
@@ -247,7 +253,9 @@ osg::Group* createForest(TreeBin& forest, const osg::Matrix& transform)
|
|||||||
baseTextureSampler = new osg::Uniform("baseTexture", 0);
|
baseTextureSampler = new osg::Uniform("baseTexture", 0);
|
||||||
Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource);
|
Shader* vertex_shader = new Shader(Shader::VERTEX, vertexShaderSource);
|
||||||
program->addShader(vertex_shader);
|
program->addShader(vertex_shader);
|
||||||
|
#ifndef TSG_PACKED_ATTRIBUTES
|
||||||
program->addBindAttribLocation("textureIndex", 1);
|
program->addBindAttribLocation("textureIndex", 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
Shader* fragment_shader = new Shader(Shader::FRAGMENT,
|
Shader* fragment_shader = new Shader(Shader::FRAGMENT,
|
||||||
fragmentShaderSource);
|
fragmentShaderSource);
|
||||||
|
|||||||
Reference in New Issue
Block a user