303 lines
14 KiB
C++
303 lines
14 KiB
C++
|
/**************************************************************************************/
|
|||
|
/* */
|
|||
|
/* Visualization Library */
|
|||
|
/* http://visualizationlibrary.org */
|
|||
|
/* */
|
|||
|
/* Copyright (c) 2005-2020, Michele Bosi */
|
|||
|
/* All rights reserved. */
|
|||
|
/* */
|
|||
|
/* Redistribution and use in source and binary forms, with or without modification, */
|
|||
|
/* are permitted provided that the following conditions are met: */
|
|||
|
/* */
|
|||
|
/* - Redistributions of source code must retain the above copyright notice, this */
|
|||
|
/* list of conditions and the following disclaimer. */
|
|||
|
/* */
|
|||
|
/* - Redistributions in binary form must reproduce the above copyright notice, this */
|
|||
|
/* list of conditions and the following disclaimer in the documentation and/or */
|
|||
|
/* other materials provided with the distribution. */
|
|||
|
/* */
|
|||
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
|
|||
|
/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
|||
|
/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
|
|||
|
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
|
|||
|
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
|
|||
|
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
|
|||
|
/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|||
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|||
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
|
|||
|
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|||
|
/* */
|
|||
|
/**************************************************************************************/
|
|||
|
|
|||
|
#ifndef Geometry_INCLUDE_ONCE
|
|||
|
#define Geometry_INCLUDE_ONCE
|
|||
|
|
|||
|
#include <vlGraphics/IVertexAttribSet.hpp>
|
|||
|
#include <vlGraphics/BufferObject.hpp>
|
|||
|
#include <vlCore/Vector2.hpp>
|
|||
|
#include <vlCore/Vector4.hpp>
|
|||
|
#include <vlGraphics/Renderable.hpp>
|
|||
|
#include <vlCore/vlnamespace.hpp>
|
|||
|
#include <vlCore/Log.hpp>
|
|||
|
#include <vlCore/Say.hpp>
|
|||
|
#include <vlCore/Colors.hpp>
|
|||
|
#include <vlGraphics/DrawElements.hpp>
|
|||
|
#include <vlGraphics/DrawArrays.hpp>
|
|||
|
#include <vlCore/Collection.hpp>
|
|||
|
|
|||
|
namespace vl
|
|||
|
{
|
|||
|
class OpenGLContext;
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
// Geometry
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
/**
|
|||
|
* The Geometry class is a Renderable that implements a polygonal mesh made of
|
|||
|
* polygons, lines and points.
|
|||
|
*
|
|||
|
* @sa
|
|||
|
* - ArrayAbstract
|
|||
|
* - Renderable
|
|||
|
* - Actor
|
|||
|
* - Transform
|
|||
|
* - Effect
|
|||
|
*/
|
|||
|
class VLGRAPHICS_EXPORT Geometry: public Renderable, public IVertexAttribSet
|
|||
|
{
|
|||
|
VL_INSTRUMENT_CLASS(vl::Geometry, Renderable)
|
|||
|
|
|||
|
// use deepCopy() and shallowCopy() instead
|
|||
|
// Geometry(const Geometry& other): Renderable(other) { }
|
|||
|
Geometry& operator=(const Geometry&) { return *this; }
|
|||
|
|
|||
|
public:
|
|||
|
/** Constructor. */
|
|||
|
Geometry();
|
|||
|
|
|||
|
/** Destructor. */
|
|||
|
virtual ~Geometry();
|
|||
|
|
|||
|
/**
|
|||
|
* Performs a shallow copy of a Geometry.
|
|||
|
* @sa deepCopy() */
|
|||
|
ref<Geometry> shallowCopy() const;
|
|||
|
|
|||
|
/**
|
|||
|
* Performs a shallow copy of the specified Geometry.
|
|||
|
* @sa deepCopy() */
|
|||
|
Geometry& shallowCopyFrom(const Geometry&);
|
|||
|
|
|||
|
/**
|
|||
|
* Performs a deep copy of a Geometry.
|
|||
|
* @sa shallowCopy() */
|
|||
|
ref<Geometry> deepCopy() const;
|
|||
|
|
|||
|
/**
|
|||
|
* Performs a deep copy of the specified Geometry.
|
|||
|
* @sa shallowCopy() */
|
|||
|
Geometry& deepCopyFrom(const Geometry&);
|
|||
|
|
|||
|
//! Returns the list of DrawCall objects bound to a Geometry
|
|||
|
Collection<DrawCall>& drawCalls() { return mDrawCalls; }
|
|||
|
|
|||
|
//! Returns the list of DrawCall objects bound to a Geometry
|
|||
|
const Collection<DrawCall>& drawCalls() const { return mDrawCalls; }
|
|||
|
|
|||
|
//! Fills the color array with the given color
|
|||
|
void setColorArray(const fvec4& color)
|
|||
|
{
|
|||
|
u32 vert_count = (u32)(vertexArray() ? vertexArray()->size() : 0);
|
|||
|
VL_CHECK( vert_count )
|
|||
|
|
|||
|
// try to minimize reallocations
|
|||
|
ref<ArrayFloat4> color_array = colorArray()->as<ArrayFloat4>();
|
|||
|
if ( ! color_array ) {
|
|||
|
color_array = new ArrayFloat4;
|
|||
|
}
|
|||
|
if ( color_array->size() != vert_count ) {
|
|||
|
color_array->resize(vert_count);
|
|||
|
}
|
|||
|
for( u32 i = 0; i < color_array->size(); ++i ) {
|
|||
|
color_array->at( i ) = color;
|
|||
|
}
|
|||
|
color_array->setBufferObjectDirty();
|
|||
|
setBufferObjectDirty();
|
|||
|
|
|||
|
setColorArray(color_array.get());
|
|||
|
}
|
|||
|
|
|||
|
/** Removes all the previously installed arrays. */
|
|||
|
virtual void clearArrays(bool clear_draw_calls=true);
|
|||
|
|
|||
|
// --- Renderable interface implementation ---
|
|||
|
|
|||
|
/** Updates all the vertex buffer objects of both vertex arrays and draw calls that are marked as dirty. */
|
|||
|
virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode);
|
|||
|
|
|||
|
/** Deletes all the vertex buffer objects of both vertex arrays and draw calls. */
|
|||
|
virtual void deleteBufferObject();
|
|||
|
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
// Geometry Tools
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
|
|||
|
/**
|
|||
|
* Computes the normals in a "smooth" way, i.e. averaging the normals of those
|
|||
|
* polygons that share one or more vertices.
|
|||
|
*
|
|||
|
* This function computes smoothed normals for triangle primitives and leaves
|
|||
|
* unchanged the normals of line and point primitives when possible, i.e. when
|
|||
|
* they don't share vertices with the polygonal primitives.
|
|||
|
*
|
|||
|
* \note
|
|||
|
* This function modifies the local buffers. After calling this you might want
|
|||
|
* to update the buffers allocated on the GPU.
|
|||
|
*/
|
|||
|
void computeNormals(bool verbose=false);
|
|||
|
|
|||
|
/** Inverts the orientation of the normals.
|
|||
|
* Returns \p true if the normals could be flipped. The function fails if the normals
|
|||
|
* are defined in a format other than ArrayFloat3. */
|
|||
|
bool flipNormals();
|
|||
|
|
|||
|
//! Converts all draw calls to triangles and fixes their winding according to the Geometry's normals.
|
|||
|
void fixTriangleWinding();
|
|||
|
|
|||
|
/**
|
|||
|
* Transforms vertices and normals belonging to this geometry.
|
|||
|
* If 'normalize' == true the normals are normalized after being transformed
|
|||
|
* \note This functions supports every possible vertex format, type and layout.
|
|||
|
* \sa
|
|||
|
* - ArrayAbstract::transform()
|
|||
|
* - ArrayAbstract::normalize()
|
|||
|
* - ArrayAbstract::computeBoundingSphere()
|
|||
|
* - ArrayAbstract::computeBoundingBox()
|
|||
|
*/
|
|||
|
void transform(const mat4&matr, bool normalize = true);
|
|||
|
|
|||
|
//! Converts all the DrawCall objects bound to a Geometry into DrawArrays.
|
|||
|
void convertDrawCallToDrawArrays();
|
|||
|
|
|||
|
//! Merges all the PT_TRIANGLE_STRIP DrawElementsUInt objects into one single PT_TRIANGLE_STRIP DrawElementsUInt.
|
|||
|
//! @return The DrawCall containing the merged strips or NULL of none was merged.
|
|||
|
DrawCall* mergeTriangleStrips();
|
|||
|
|
|||
|
//! Merges all the draw calls that use the given primitive type into one single draw call using primitive restart.
|
|||
|
void mergeDrawCallsWithPrimitiveRestart(EPrimitiveType primitive_type);
|
|||
|
|
|||
|
//! Merges all the draw calls that use the given primitive type into one single MultiDrawElements draw call.
|
|||
|
void mergeDrawCallsWithMultiDrawElements(EPrimitiveType primitive_type);
|
|||
|
|
|||
|
//! Merges all the draw calls that use the given primitive type or PT_TRIANGLES into one single PT_TRIANGLES draw call.
|
|||
|
//! Use primitive_type = PT_UNKNOWN to merge all primitive types (with the obvious exclusion of lines, points and adjacency ones).
|
|||
|
void mergeDrawCallsWithTriangles(EPrimitiveType primitive_type);
|
|||
|
|
|||
|
//! Converts PT_QUADS, PT_QUADS_STRIP and PT_POLYGON into PT_TRIANGLE primitives.
|
|||
|
//! @note Eventual base vertex and primitive restart are baked into the resulting triangle soup.
|
|||
|
void triangulateDrawCalls();
|
|||
|
|
|||
|
//! Shrinks DrawElements*/DrawRangeElements*/MultiDrawElements* to the best fitting of *UInt/UShort/UByte
|
|||
|
//! taking into account: primitive restart, instancing and base vertex.
|
|||
|
//! @note Primitive type can be any.
|
|||
|
void shrinkDrawCalls();
|
|||
|
|
|||
|
//! Calls triangulateDrawCalls() and shrinkDrawCalls().
|
|||
|
//! @note At the moment this method does support MultiDrawElements nor DrawRangeElements but only DrawElements.
|
|||
|
void makeGLESFriendly();
|
|||
|
|
|||
|
//! Sorts the vertices of the geometry (position, normals, textures, colors etc.) to maximize vertex-cache coherency.
|
|||
|
//! This function will work only if all the DrawCalls are DrawElements* and will generate a new set of DrawElementsUInt.
|
|||
|
//! This function will fail if any of the DrawCalls is using primitive restart functionality.
|
|||
|
//! \returns true if all the DrawCall are DrawElements* and none of the DrawCalls is using primitive restart.
|
|||
|
bool sortVertices();
|
|||
|
|
|||
|
//! Regenerates the vertex position and attributes using the given new-to-old map.
|
|||
|
//! Where 'map_new_to_old[i] == j' means that the i-th new vertex attribute should take it's value from the old j-th vertex attribute.
|
|||
|
void regenerateVertices(const std::vector<u32>& map_new_to_old);
|
|||
|
|
|||
|
//! Assigns a random color to each vertex of each DrawCall object. If a vertex is shared among more than one DrawCall object its color is undefined.
|
|||
|
void colorizePrimitives();
|
|||
|
|
|||
|
//! Computes the tangent (and optionally bitangent) vectors used to form a TBN matrix to be used for bumpmapping.
|
|||
|
//! @param vert_count The number of elements stored in @a vertex, @a normal, @a texcoord, @a tangent and @a bitangent.
|
|||
|
//! @param vertex Array containing the vertex positions.
|
|||
|
//! @param normal Array containing the normals of the vertices.
|
|||
|
//! @param texcoord Array containing the 2d texture coordinates of the bumpmap.
|
|||
|
//! @param primitives The triangles, quads etc. defining the geometry of the object.
|
|||
|
//! @param tangent [out] Returns the tangent vector of the vertices. This parameter is mandatory.
|
|||
|
//! @param bitangent [out] Returns the bitangent vector of the vertics. This parameter can be NULL.
|
|||
|
// Based on:
|
|||
|
// Lengyel, Eric. <20>Computing Tangent Space Basis Vectors for an Arbitrary Mesh<73>. Terathon Software 3D Graphics Library, 2001.
|
|||
|
// http://www.terathon.com/code/tangent.html
|
|||
|
static void computeTangentSpace(
|
|||
|
u32 vert_count,
|
|||
|
const vl::fvec3 *vertex,
|
|||
|
const vl::fvec3* normal,
|
|||
|
const vl::fvec2 *texcoord,
|
|||
|
const vl::DrawCall* primitives,
|
|||
|
vl::fvec3 *tangent,
|
|||
|
vl::fvec3 *bitangent );
|
|||
|
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
// IVertexAttribSet Interface Implementation
|
|||
|
// ------------------------------------------------------------------------
|
|||
|
|
|||
|
void setVertexArray(ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* vertexArray() const { return mVertexAttribArrays[VA_Position].get(); }
|
|||
|
|
|||
|
ArrayAbstract* vertexArray() { return mVertexAttribArrays[VA_Position].get(); }
|
|||
|
|
|||
|
void setNormalArray(ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* normalArray() const { return mVertexAttribArrays[VA_Normal].get(); }
|
|||
|
|
|||
|
ArrayAbstract* normalArray() { return mVertexAttribArrays[VA_Normal].get(); }
|
|||
|
|
|||
|
void setColorArray(ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* colorArray() const { return mVertexAttribArrays[VA_Color].get(); }
|
|||
|
|
|||
|
ArrayAbstract* colorArray() { return mVertexAttribArrays[VA_Color].get(); }
|
|||
|
|
|||
|
void setSecondaryColorArray(ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* secondaryColorArray() const { return mVertexAttribArrays[VA_SecondaryColor].get(); }
|
|||
|
|
|||
|
ArrayAbstract* secondaryColorArray() { return mVertexAttribArrays[VA_SecondaryColor].get(); }
|
|||
|
|
|||
|
void setFogCoordArray(ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* fogCoordArray() const { return mVertexAttribArrays[VA_FogCoord].get(); }
|
|||
|
|
|||
|
ArrayAbstract* fogCoordArray() { return mVertexAttribArrays[VA_FogCoord].get(); }
|
|||
|
|
|||
|
void setTexCoordArray(int tex_unit, ArrayAbstract* data);
|
|||
|
|
|||
|
const ArrayAbstract* texCoordArray(int tex_unit) const { return mVertexAttribArrays[VA_TexCoord0 + tex_unit].get(); }
|
|||
|
|
|||
|
ArrayAbstract* texCoordArray(int tex_unit) { return mVertexAttribArrays[VA_TexCoord0 + tex_unit].get(); }
|
|||
|
|
|||
|
void setVertexAttribArray(int attrib_location, const ArrayAbstract* info);
|
|||
|
|
|||
|
const ArrayAbstract* vertexAttribArray(int attrib_location) const;
|
|||
|
|
|||
|
ArrayAbstract* vertexAttribArray(int attrib_location);
|
|||
|
|
|||
|
protected:
|
|||
|
virtual void computeBounds_Implementation();
|
|||
|
|
|||
|
virtual void render_Implementation(const Actor* actor, const Shader* shader, const Camera* camera, OpenGLContext* gl_context) const;
|
|||
|
|
|||
|
// render calls
|
|||
|
Collection<DrawCall> mDrawCalls;
|
|||
|
|
|||
|
// vertex attributes
|
|||
|
ref<ArrayAbstract> mVertexAttribArrays[VA_MaxAttribCount];
|
|||
|
};
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
}
|
|||
|
|
|||
|
#endif
|