Commit 7b0815fb authored by Jan Möbius's avatar Jan Möbius
Browse files

Updated DrawModes with properties by Christopher.

Updated Documentation.
Fixed Build errors on Linux due to collision with name xor
refs #901

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14801 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 45dc3fbf
...@@ -167,14 +167,19 @@ static VecDrawModes registeredDrawModes_; ...@@ -167,14 +167,19 @@ static VecDrawModes registeredDrawModes_;
static DrawMode firstFreeID_; static DrawMode firstFreeID_;
DrawModeProperties::DrawModeProperties(DrawModePrimitive _primitive,
DrawModeProperties::DrawModeProperties(): DrawModeLightStage _lightStage,
lighting_(true), DrawModeNormalSource _normalSource,
points_(false), DrawModeColorSource _colorSource,
lines_(false), DrawModeTexCoordSource _texcoordSource,
triangles_(true) bool _envMapping):
envMapped_(_envMapping),
primitive_(_primitive),
lightStage_(_lightStage),
colorSource_(_colorSource),
texcoordSource_(_texcoordSource),
normalSource_(_normalSource)
{ {
} }
...@@ -186,20 +191,22 @@ DrawMode::DrawMode(unsigned int _index) ...@@ -186,20 +191,22 @@ DrawMode::DrawMode(unsigned int _index)
} else { } else {
modeFlags_.set(_index); modeFlags_.set(_index);
} }
layers_.resize(1);
} }
DrawMode::DrawMode() { DrawMode::DrawMode() {
layers_.resize(1);
} }
DrawMode::DrawMode( ModeFlagSet _flags ) { DrawMode::DrawMode( ModeFlagSet _flags ) {
modeFlags_ = _flags; modeFlags_ = _flags;
layers_.resize(1);
} }
DrawMode::operator bool() const { DrawMode::operator bool() const {
return( modeFlags_ != NONE.modeFlags_ ); return( modeFlags_ != NONE.modeFlags_ );
} }
/*
bool DrawMode::propertyBased() const { bool DrawMode::propertyBased() const {
if ( isAtomic() ) { if ( isAtomic() ) {
return registeredDrawModes_[getIndex()].propertyBased(); return registeredDrawModes_[getIndex()].propertyBased();
...@@ -213,13 +220,16 @@ bool DrawMode::propertyBased() const { ...@@ -213,13 +220,16 @@ bool DrawMode::propertyBased() const {
return false; return false;
} }
} }
*/
DrawModeProperties* DrawMode::drawModeProperties() { void DrawMode::setDrawModeProperties(const DrawModeProperties* _props) {
if ( isAtomic() ) { if (!layers_.empty() && _props)
return &(registeredDrawModes_[getIndex()].properties()); layers_[0] = *_props;
} else { }
return 0;
} void DrawMode::setDrawModeProperties( const DrawModeProperties& _props )
{
setDrawModeProperties(&_props);
} }
bool DrawMode::operator==(const DrawMode& _mode) const { bool DrawMode::operator==(const DrawMode& _mode) const {
...@@ -247,6 +257,9 @@ DrawMode DrawMode::operator&(const DrawMode& _mode) const { ...@@ -247,6 +257,9 @@ DrawMode DrawMode::operator&(const DrawMode& _mode) const {
DrawMode& DrawMode::operator|=( const DrawMode& _mode2 ) { DrawMode& DrawMode::operator|=( const DrawMode& _mode2 ) {
modeFlags_ |= _mode2.modeFlags_; modeFlags_ |= _mode2.modeFlags_;
for (unsigned int i = 0; i < _mode2.getNumLayers(); ++i)
addLayer(_mode2.getLayer(i));
return (*this); return (*this);
} }
...@@ -257,11 +270,83 @@ DrawMode& DrawMode::operator&=( const DrawMode& _mode2 ) { ...@@ -257,11 +270,83 @@ DrawMode& DrawMode::operator&=( const DrawMode& _mode2 ) {
} }
DrawMode DrawMode::operator|( const DrawMode& _mode2 ) const { DrawMode DrawMode::operator|( const DrawMode& _mode2 ) const {
return( modeFlags_ | _mode2.modeFlags_ ); DrawMode combined = ( modeFlags_ | _mode2.modeFlags_ );
combined.setDrawModeProperties(getDrawModeProperties());
for (unsigned int i = 1; i < getNumLayers(); ++i)
combined.addLayer(getLayer(i));
for (unsigned int i = 0; i < _mode2.getNumLayers(); ++i)
combined.addLayer(_mode2.getLayer(i));
return combined;
} }
DrawMode DrawMode::operator^( const DrawMode& _mode2 ) const { DrawMode DrawMode::operator^( const DrawMode& _mode2 ) const {
return( modeFlags_ ^ _mode2.modeFlags_ );
DrawMode xorMode = ( modeFlags_ ^ _mode2.modeFlags_ );
// xor on properties
unsigned int curLayer = 0;
const DrawModeProperties* curProps = 0;
// do xor on new temporary DrawMode
// internal layers of this and _mode2 must stay the same
std::vector<const DrawModeProperties*> tmpLayers;
// initialize tmpLayers with my own layers
for (unsigned int i = 0; i < getNumLayers(); ++i)
{
curProps = getLayer(i);
if (curProps)
tmpLayers.push_back(curProps);
}
// xor on tmpLayers
for (unsigned int i = 0; i < _mode2.getNumLayers(); ++i)
{
curProps = _mode2.getLayer(i);
if (!curProps) continue;
int addToVec = 1;
// is the other layer already contained in my own list?
for (unsigned int k = 0; addToVec && k < tmpLayers.size(); ++k)
{
if (!memcmp(tmpLayers[k], curProps, sizeof(DrawModeProperties)))
{
// yes, remove it (layer exists in both drawmodes)
tmpLayers.erase(tmpLayers.begin() + k);
addToVec = 0;
}
}
if (addToVec) // no, add it
tmpLayers.push_back(curProps);
}
// DrawModes equal?
if (tmpLayers.empty())
return xorMode; // return default property set to not cause exceptions
// layers not empty,
// copy to temporary drawmode and return
xorMode.setDrawModeProperties(tmpLayers[0]);
for (unsigned int i = 0; i < tmpLayers.size(); ++i)
xorMode.addLayer(tmpLayers[i]);
return xorMode;
} }
DrawMode DrawMode::operator~( ) const { DrawMode DrawMode::operator~( ) const {
...@@ -335,7 +420,38 @@ DrawMode::containsAtomicDrawMode( DrawMode _atomicDrawMode) const ...@@ -335,7 +420,38 @@ DrawMode::containsAtomicDrawMode( DrawMode _atomicDrawMode) const
unsigned int DrawMode::maxModes() const { unsigned int DrawMode::maxModes() const {
return (modeFlags_.size() ); return (modeFlags_.size() );
} }
unsigned int DrawMode::getNumLayers() const {
return layers_.size();
}
const DrawModeProperties* DrawMode::getLayer( unsigned int i ) const {
return (i >= layers_.size() ? 0 : &layers_[i]);
}
void DrawMode::addLayer( const DrawModeProperties* _props )
{
for (unsigned int i = 0; i < layers_.size(); ++i)
{
if (!memcmp(&layers_[i], _props, sizeof(DrawModeProperties)))
return;
}
layers_.push_back(*_props);
}
bool DrawMode::removeLayer( unsigned int _i )
{
layers_.erase(layers_.begin() + _i);
return true;
}
const DrawModeProperties* DrawMode::getDrawModeProperties() const
{
return getLayer(0);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -349,6 +465,61 @@ void initializeDefaultDrawModes( void ) ...@@ -349,6 +465,61 @@ void initializeDefaultDrawModes( void )
registeredDrawModes_.clear(); registeredDrawModes_.clear();
NONE.removeLayer(0u);
DEFAULT.removeLayer(0u);
POINTS. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POINT));
POINTS_COLORED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POINT, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_VERTEX));
POINTS_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POINT, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX));
EDGES. setDrawModeProperties(DrawModeProperties(PRIMITIVE_EDGE));
EDGES_COLORED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_EDGE, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_VERTEX));
WIREFRAME. setDrawModeProperties(DrawModeProperties(PRIMITIVE_EDGE));
EDGES_COLORED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_EDGE, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_VERTEX));
WIREFRAME. setDrawModeProperties(DrawModeProperties(PRIMITIVE_WIREFRAME));
FACES. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON));
HIDDENLINE. setDrawModeProperties(DrawModeProperties(PRIMITIVE_HIDDENLINE));
SOLID_FLAT_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_FACE));
SOLID_SMOOTH_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX));
SOLID_PHONG_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_PHONG, NORMAL_PER_VERTEX));
SOLID_FACES_COLORED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_FACE, COLOR_PER_FACE));
SOLID_POINTS_COLORED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POINT, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_VERTEX));
SOLID_POINTS_COLORED_SHADED.setDrawModeProperties(DrawModeProperties(PRIMITIVE_POINT, LIGHTSTAGE_SMOOTH, NORMAL_PER_FACE, COLOR_PER_VERTEX));
SOLID_ENV_MAPPED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_NONE, TEXCOORD_PER_VERTEX, true));
SOLID_TEXTURED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_TEXTURED_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX,COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_1DTEXTURED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_1DTEXTURED_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX,COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_3DTEXTURED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_3DTEXTURED_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX,COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_FACES_COLORED_FLAT_SHADED. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_FACE, COLOR_PER_FACE));
SOLID_FACES_COLORED_SMOOTH_SHADED.setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_VERTEX, COLOR_PER_FACE));
SOLID_2DTEXTURED_FACE. setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_2DTEXTURED_FACE_SHADED.setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_FACE, COLOR_NONE, TEXCOORD_PER_VERTEX));
SOLID_SMOOTH_SHADED_FEATURES.setDrawModeProperties(DrawModeProperties(PRIMITIVE_POLYGON, LIGHTSTAGE_SMOOTH, NORMAL_PER_HALFEDGE));
CELLS.setDrawModeProperties(DrawModeProperties(PRIMITIVE_CELL));
CELLS_COLORED.setDrawModeProperties(DrawModeProperties(PRIMITIVE_CELL, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_VERTEX));
HALFEDGES.setDrawModeProperties(DrawModeProperties(PRIMITIVE_HALFEDGE));
HALFEDGES_COLORED.setDrawModeProperties(DrawModeProperties(PRIMITIVE_HALFEDGE, LIGHTSTAGE_UNLIT, NORMAL_NONE, COLOR_PER_HALFEDGE));
registeredDrawModes_.push_back( DrawModeInternal( "<invalid>", NONE ) ); registeredDrawModes_.push_back( DrawModeInternal( "<invalid>", NONE ) );
registeredDrawModes_.push_back( DrawModeInternal( "Default", DEFAULT ) ); registeredDrawModes_.push_back( DrawModeInternal( "Default", DEFAULT ) );
......
...@@ -88,34 +88,167 @@ namespace SceneGraph { ...@@ -88,34 +88,167 @@ namespace SceneGraph {
QPopupMenu. QPopupMenu.
*/ */
namespace DrawModes { namespace DrawModes {
/** \brief Lighting stage of a mesh: unlit, smooth, phong
*
* Don't confuse this with the interpolation mode of vertex attributes.
* This only says where to apply lighting, and nothing else.
*
* Instead the interpolation mode is customizable for each attribute,
* making DrawModeProperties more flexible.
*
* flat shading can be achieved by using LIGHTSTAGE_SMOOTH
* and setting the normal source to NORMAL_PER_FACE
*/
enum DrawModeLightStage
{
LIGHTSTAGE_UNLIT, /**< No lighting, normals may be used by user defined shaders */
LIGHTSTAGE_SMOOTH, /**< Perform lighting in vertex shader */
LIGHTSTAGE_PHONG /**< Perform lighting in fragment shader */
};
/** \brief Primitive mode of a mesh.
*
* Example: PRIMITIVE_EDGE on a polygon mesh renders only edges of the mesh.
*/
enum DrawModePrimitive
{
PRIMITIVE_POINT,
PRIMITIVE_EDGE,
PRIMITIVE_HALFEDGE,
PRIMITIVE_WIREFRAME,
PRIMITIVE_HIDDENLINE,
PRIMITIVE_POLYGON,
PRIMITIVE_CELL
};
/** \brief Source of Primitive Colors.
*
* This is interpreted as a per vertex diffuse and ambient color and multiplied with
* the material diffuse/ambient colors.
*/
enum DrawModeColorSource
{
COLOR_NONE, /**< Use material colors only */
COLOR_PER_VERTEX, /**< Load per vertex colors and modulate with material color */
COLOR_PER_HALFEDGE, /**< Load per halfedge colors and modulate with material color */
COLOR_PER_FACE /**< Load per face colors and modulate with material color */
};
/** \brief Source of Texture Coordinates.
*
* This must be specified for a textured draw.
*/
enum DrawModeTexCoordSource
{
TEXCOORD_NONE, /**< Disable texture mapping */
TEXCOORD_PER_VERTEX, /**< Use per vertex texcoords for texture mapping */
TEXCOORD_PER_HALFEDGE, /**< Use per halfedge texcoords for texture mapping */
// TEXCOORD_PER_FACE // TODO: discuss texcoords per face? is it useful?
};
/** \brief Source of Normals.
*
* This must be specified if lighting is enabled.
*/
enum DrawModeNormalSource
{
NORMAL_NONE, /**< Disable lighting */
NORMAL_PER_VERTEX, /**< Use per vertex normals */
NORMAL_PER_HALFEDGE, /**< Use per halfedge normals */
NORMAL_PER_FACE /**< Use per face normals \note per face is implicitly used in SHADE_FLAT mode */
};
typedef std::bitset<64> ModeFlagSet; typedef std::bitset<64> ModeFlagSet;
/** \brief This class will be used for property based draw modes. /** \brief DrawModeProperties stores a set of properties that defines, how to render an object.
* *
* TODO: This class has to be implemented * A property may be the primitive type, normal source, color source ...
* Each property is atomic, i.e. it can not be combined with other properties of the same type.
* Example: primitive may be PRIMITIVE_POLYGON or PRIMITIVE_POINTS, but not both at the same time.
* This restriction makes a property set well defined; it is always a valid set of properties.
* To have combined DrawModes i.e. flat + wireframe you have to use the layer approach of DrawMode.
*/ */
class ACGDLLEXPORT DrawModeProperties { class ACGDLLEXPORT DrawModeProperties {
public: public:
DrawModeProperties(); DrawModeProperties(
DrawModePrimitive _primitive = PRIMITIVE_POLYGON,
DrawModeLightStage _lightStage = LIGHTSTAGE_UNLIT,
DrawModeNormalSource _normalSource = NORMAL_NONE,
DrawModeColorSource _colorSource = COLOR_NONE,
DrawModeTexCoordSource _texcoordSource = TEXCOORD_NONE,
bool _envMapping = false);
//===========================================================================
/** @name Getter/Setter of all properties
* @{ */
//===========================================================================
DrawModePrimitive primitive() const { return primitive_; }
void primitive(DrawModePrimitive _val) { primitive_ = _val; }
DrawModeLightStage lightStage() const { return lightStage_; }
void lightStage(DrawModeLightStage _val) { lightStage_ = _val; }
DrawModeColorSource colorSource() const { return colorSource_; }
void colorSource(DrawModeColorSource _val) { colorSource_ = _val; }
DrawModeNormalSource normalSource() const { return normalSource_; }
void normalSource(DrawModeNormalSource _val) { normalSource_ = _val; }
DrawModeTexCoordSource texcoordSource() const { return texcoordSource_; }
void texcoordSource(DrawModeTexCoordSource _val) { texcoordSource_ = _val; }
/** @} */
//===========================================================================
/** @name Helper functions for more convenient use in renderer
* @{ */
//===========================================================================
/// Is lighting enabled?
bool lighting() const { return lightStage_ != LIGHTSTAGE_UNLIT && normalSource_ != NORMAL_NONE; }
/// Is texturing enabled?
bool textured() const { return texcoordSource_ != TEXCOORD_NONE; }
/// Are colors used?
bool colored() const { return colorSource_ != COLOR_NONE; }
/// Is flat shading used (Normals per face)?
bool flatShaded() const { return normalSource_ == NORMAL_PER_FACE; }
/** @} */
private: private:
// Specify lighting settings bool envMapped_;
bool lighting_;
/// Specify which type of primitives will get uploaded to the graphics card
DrawModePrimitive primitive_;
// Specify which primitives will get uploaded to the graphics card DrawModeLightStage lightStage_;
bool points_;
bool lines_; DrawModeColorSource colorSource_;
bool triangles_;
DrawModeTexCoordSource texcoordSource_;
DrawModeNormalSource normalSource_;
// TODO: Shade model
// TODO: colors per?
// TODO: Shaders // TODO: Shaders
}; };
/** \brief Specifies a DrawMode
*
* This class specifies a DrawMode. It can contain several properties and layers
* that define, how objects will be rendered.
*
*/
class ACGDLLEXPORT DrawMode { class ACGDLLEXPORT DrawMode {
public: public:
...@@ -129,6 +262,8 @@ namespace DrawModes { ...@@ -129,6 +262,8 @@ namespace DrawModes {
* See the list of draw modes below to check for the right numbers. * See the list of draw modes below to check for the right numbers.
* You should use the predefined drawModes or create new ones using the other functions * You should use the predefined drawModes or create new ones using the other functions
* and ignore this constructor! * and ignore this constructor!
*
* @param _index Index of the new DrawMode
*/ */
DrawMode(unsigned int _index); DrawMode(unsigned int _index);
...@@ -136,6 +271,8 @@ namespace DrawModes { ...@@ -136,6 +271,8 @@ namespace DrawModes {
* *
* This constructor creates a DrawMode from a bitset. * This constructor creates a DrawMode from a bitset.
* This makes it easier to predefine draw modes using a bitset. * This makes it easier to predefine draw modes using a bitset.
*
* @param _flags Flags for the new drawmode defined by a bitset
*/ */
DrawMode( ModeFlagSet _flags ); DrawMode( ModeFlagSet _flags );
...@@ -188,34 +325,89 @@ namespace DrawModes { ...@@ -188,34 +325,89 @@ namespace DrawModes {
std::vector< DrawMode > getAtomicDrawModes() const; std::vector< DrawMode > getAtomicDrawModes() const;
/** \brief Get the number of maximum Modes which could be handled by the current implementation /** \brief Get the number of maximum Modes which could be handled by the current implementation
*
*/ */
unsigned int maxModes() const; unsigned int maxModes() const;
operator bool() const; operator bool() const;
/** \brief returns, if this DrawMode is property based /** \brief returns the base properties of this draw mode
*
* Base properties are the original properties that defined the DrawMode before any merge operation.
* They are located at layer 0, so actually this function has the same effect as getLayer(0).
*
* Every DrawMode is property based with only two exceptions:
* - NONE
* - DEFAULT
*
* getDrawModeProperties returns 0 for these.
*/
const DrawModeProperties* getDrawModeProperties() const;
/** \brief set the base properties of this draw mode
* *
* This function checks if the current drawmode is property based. If it is not * @param _props Properties to be set
* an atomic draw mode, this function returns true if one of the drawmodes
* is property based.
*/ */
bool propertyBased() const; void setDrawModeProperties(const DrawModeProperties* _props);
/** \brief returns the properties of this draw mode /** \brief set the base properties of this draw mode
* *
* This function will return the properties of this DrawMode. * @param _props Properties to be set
* This is only valid, if the DrawMode is atomic and has been declared as
* property based when it was added. Otherwise a 0 pointer is returned!
*/ */
DrawModeProperties* drawModeProperties(); void setDrawModeProperties(const DrawModeProperties& _props);
/** \brief add another layer on top of this drawmode
*
* This allows for combinations of DrawModes.
* The renderer will iterator over all layers of the drawmode
* and issue a new draw call for each layer.
* Example:
* layer 0 : flat shading properties
* layer 1 : edge drawing properties
*
* The result will be a flat shaded object with it's wireframe on top of it.
* Does duplicate check, in case the property set is already in the layer list.
*
* addLayer is also called in bitwise | operator for backwards compatibility with bitset DrawModes
*
* @param _props Property that should be added
*/
void addLayer(const DrawModeProperties* _props); // same as bitwise or operator
/** \brief returns the layer count
*/
unsigned int getNumLayers() const;
/** \brief returns the property set at layer i
*
* @param _i Layer that is requested
*/
const DrawModeProperties* getLayer(unsigned int _i) const;
/** \brief remove layer at index i
*
* @param _i Layer that is requested
*/
bool removeLayer(unsigned int _i);