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

Update for the new renderers by Christopher

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14918 383ad7c9-94d9-4d36-a494-682f7c89f535
parent dae306bf
......@@ -145,22 +145,11 @@ DrawMeshT<Mesh>::DrawMeshT(Mesh& _mesh)
vertexDeclVCol_ = new VertexDeclaration;
vertexDeclFCol_ = new VertexDeclaration;
VertexElement elemArrayV[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD, 0, {0} },
{GL_FLOAT, 3, VERTEX_USAGE_NORMAL, 0, {0} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {0} } };
VertexElement elemArrayF[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD, 0, {12} },
{GL_FLOAT, 3, VERTEX_USAGE_NORMAL, 0, {20} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {36} } };
vertexDeclEdgeCol_ = new VertexDeclaration;
vertexDeclHalfedgeCol_ = new VertexDeclaration;
vertexDeclHalfedgePos_ = new VertexDeclaration;
vertexDeclVCol_->addElements(4, elemArrayV);
vertexDeclFCol_->addElements(4, elemArrayF);
// VertexDeclaration computes a stride of 36 automatically
// force 40 bytes instead!
vertexDeclVCol_->setVertexStride(sizeof(Vertex)); // pad for Vertex::fcol
createVertexDeclarations();
}
......@@ -945,6 +934,9 @@ DrawMeshT<Mesh>::~DrawMeshT(void)
delete vertexDeclFCol_;
delete vertexDeclVCol_;
delete vertexDeclEdgeCol_;
delete vertexDeclHalfedgeCol_;
delete vertexDeclHalfedgePos_;
if (vbo_) glDeleteBuffersARB(1, &vbo_);
if (ibo_) glDeleteBuffersARB(1, &ibo_);
......@@ -1187,20 +1179,17 @@ void DrawMeshT<Mesh>::draw(std::map< int, GLuint>* _textureMap)
template <class Mesh>
void ACG::DrawMeshT<Mesh>::getTriRenderObjects( RenderObject* _objOut, std::map< int, GLuint>* _textureMap )
void ACG::DrawMeshT<Mesh>::addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap)
{
// binding buffers to opengl is obsolute here, but it keeps the vbo up to date for now
bindBuffersToRenderObject(_objOut);
_objOut->glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0);
if (numTris_)
{
if (_textureMap)
RenderObject ro = *_baseObj;
bindBuffersToRenderObject(&ro);
if (_textureMap && _baseObj->shaderDesc.textured)
{
// textured mode
// subsets not supported yet
for (unsigned int i = 0; i < numSubsets_; ++i)
{
Subset* pSubset = subsets_ + i;
......@@ -1211,12 +1200,21 @@ void ACG::DrawMeshT<Mesh>::getTriRenderObjects( RenderObject* _objOut, std::map<
else
{
// ACG::GLState::bindTexture(GL_TEXTURE_2D, (*_textureMap)[pSubset->materialID]);
_objOut->texture = (*_textureMap)[pSubset->materialID];
ro.texture = (*_textureMap)[pSubset->materialID];
}
ro.glDrawElements(GL_TRIANGLES, pSubset->numTris * 3, indexType_,
(GLvoid*)( pSubset->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes
_renderer->addRenderObject(&ro);
}
//
// glDrawElements(GL_TRIANGLES, pSubset->numTris * 3, indexType_,
// (GLvoid*)( pSubset->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes
}
else
{
ro.glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0);
_renderer->addRenderObject(&ro);
}
}
}
......@@ -1239,14 +1237,17 @@ void DrawMeshT<Mesh>::drawLines()
template <class Mesh>
void DrawMeshT<Mesh>::getLineRenderObjects(RenderObject* _objOut)
void DrawMeshT<Mesh>::addLineRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj)
{
bindBuffersToRenderObject(_objOut);
RenderObject ro = *_baseObj;
bindBuffersToRenderObject(&ro);
if (mesh_.n_edges())
{
_objOut->indexBuffer = lineIBO_;
_objOut->glDrawElements(GL_LINES, mesh_.n_edges() * 2, indexType_, 0);
ro.indexBuffer = lineIBO_;
ro.glDrawElements(GL_LINES, mesh_.n_edges() * 2, indexType_, 0);
_renderer->addRenderObject(&ro);
}
}
......@@ -1263,13 +1264,17 @@ void DrawMeshT<Mesh>::drawVertices()
}
template <class Mesh>
void DrawMeshT<Mesh>::getPointRenderObjects(RenderObject* _objOut)
void DrawMeshT<Mesh>::addPointRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj)
{
bindBuffersToRenderObject(_objOut);
RenderObject ro = *_baseObj;
bindBuffersToRenderObject(&ro);
if (numVerts_)
_objOut->glDrawArrays(GL_POINTS, 0, numVerts_);
{
ro.glDrawArrays(GL_POINTS, 0, numVerts_);
_renderer->addRenderObject(&ro);
}
}
template <class Mesh>
......@@ -1357,7 +1362,7 @@ ACG::Vec3f* DrawMeshT<Mesh>::perEdgeVertexBuffer()
// Force update of the buffers if required
if (updatePerEdgeBuffers_)
updatePerEdgeBuffers();
return &(perEdgeVertexBuf_)[0];
return perEdgeVertexBuf_.empty() ? 0 : &(perEdgeVertexBuf_[0]);
}
template <class Mesh>
......@@ -1366,7 +1371,7 @@ ACG::Vec4f* DrawMeshT<Mesh>::perEdgeColorBuffer()
// Force update of the buffers if required
if (updatePerEdgeBuffers_)
updatePerEdgeBuffers();
return &(perEdgeColorBuf_[0]);
return perEdgeColorBuf_.empty() ? 0 : &(perEdgeColorBuf_[0]);
}
......@@ -1422,7 +1427,10 @@ void DrawMeshT<Mesh>::updatePerEdgeBuffers()
idx += 2;
}
updatePerEdgeBuffers_ = 0;
updateEdgeHalfedgeVertexDeclarations();
}
template <class Mesh>
......@@ -1456,7 +1464,9 @@ void DrawMeshT<Mesh>::updatePerHalfedgeBuffers()
idx += 2;
}
updatePerHalfedgeBuffers_ = 1;
updatePerHalfedgeBuffers_ = 0;
updateEdgeHalfedgeVertexDeclarations();
}
template <class Mesh>
......@@ -1494,7 +1504,7 @@ ACG::Vec3f* DrawMeshT<Mesh>::perHalfedgeVertexBuffer()
// Force update of the buffers if required
if (updatePerHalfedgeBuffers_)
updatePerHalfedgeBuffers();
return &(perHalfedgeVertexBuf_)[0];
return perHalfedgeVertexBuf_.empty() ? 0 : &(perHalfedgeVertexBuf_[0]);
}
template <class Mesh>
......@@ -1503,7 +1513,7 @@ ACG::Vec4f* DrawMeshT<Mesh>::perHalfedgeColorBuffer()
// Force update of the buffers if required
if (updatePerHalfedgeBuffers_)
updatePerHalfedgeBuffers();
return &(perHalfedgeColorBuf_)[0];
return perHalfedgeColorBuf_.empty() ? 0 : &(perHalfedgeColorBuf_[0]);
}
......@@ -1722,4 +1732,62 @@ DrawMeshT<Mesh>::perFaceTextureIndexAvailable() {
return true;
}
template <class Mesh>
void ACG::DrawMeshT<Mesh>::createVertexDeclarations()
{
VertexElement elemArrayV[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD, 0, {0} },
{GL_FLOAT, 3, VERTEX_USAGE_NORMAL, 0, {0} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {0} } };
VertexElement elemArrayF[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD, 0, {12} },
{GL_FLOAT, 3, VERTEX_USAGE_NORMAL, 0, {20} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {36} } };
vertexDeclVCol_->addElements(4, elemArrayV);
vertexDeclFCol_->addElements(4, elemArrayF);
// VertexDeclaration computes a stride of 36 automatically
// force 40 bytes instead!
vertexDeclVCol_->setVertexStride(sizeof(Vertex)); // pad for Vertex::fcol
}
template <class Mesh>
void ACG::DrawMeshT<Mesh>::updateEdgeHalfedgeVertexDeclarations()
{
VertexElement elemArrayEC[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {0} } };
elemArrayEC[0].pDataSrc_ = perEdgeVertexBuffer();
elemArrayEC[1].pDataSrc_ = perEdgeColorBuffer();
VertexElement elemArrayH = {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} };
elemArrayH.pDataSrc_ = perHalfedgeVertexBuffer();
VertexElement elemArrayHC[] = { {GL_FLOAT, 3, VERTEX_USAGE_POSITION, 0, {0} },
{GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, 0, {0} } };
elemArrayHC[0].pDataSrc_ = perHalfedgeVertexBuffer();
elemArrayHC[1].pDataSrc_ = perHalfedgeColorBuffer();
vertexDeclEdgeCol_->clear();
vertexDeclHalfedgeCol_->clear();
vertexDeclHalfedgePos_->clear();
vertexDeclEdgeCol_->addElements(2, elemArrayEC);
vertexDeclHalfedgeCol_->addElements(2, elemArrayHC);
vertexDeclHalfedgePos_->addElement(&elemArrayH);
vertexDeclEdgeCol_->setVertexStride(0);
vertexDeclHalfedgeCol_->setVertexStride(0);
vertexDeclHalfedgePos_->setVertexStride(0);
}
}
......@@ -181,13 +181,14 @@ public:
*/
void draw(std::map< int, GLuint>* _textureMap);
/** \brief initializes a RenderObject for a deferred draw call
/** \brief adds RenderObjects to a deferred draw call renderer
*
* @param _objOut address of the renderobject
* @param _renderer renderobjects are added to this renderer
* @param _baseObj address of the base renderobject with information about shader generation, gl states, matrices ..
* @param _textureMap maps from internally texture-id to OpenGL texture id
* may be null to disable textured rendering
*/
void getTriRenderObjects(RenderObject* _objOut, std::map< int, GLuint>* _textureMap);
void addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap);
/** \brief render the mesh in wireframe mode
*/
......@@ -195,7 +196,7 @@ public:
/** \brief render the mesh in wireframe mode, deferred draw call
*/
void getLineRenderObjects(RenderObject* _objOut);
void addLineRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj);
/** \brief render vertices only
......@@ -204,7 +205,7 @@ public:
/** \brief render vertices only, deferred draw call
*/
void getPointRenderObjects(RenderObject* _objOut);
void addPointRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj);
unsigned int getNumTris() const {return numTris_;}
......@@ -399,6 +400,11 @@ private:
*/
void createIBO();
/** \brief creates all vertex declarations needed for deferred draw call renderer
*
*/
void createVertexDeclarations();
public:
// color picking
......@@ -706,6 +712,15 @@ private:
/// vertex buffer layout declaration with per face colors
VertexDeclaration* vertexDeclFCol_;
/// vertex buffer layout declaration with per edge colors
VertexDeclaration* vertexDeclEdgeCol_;
/// vertex buffer layout declaration with per halfedge colors
VertexDeclaration* vertexDeclHalfedgeCol_;
/// vertex buffer layout declaration with halfedge positions only
VertexDeclaration* vertexDeclHalfedgePos_;
//========================================================================
// internal processing
......@@ -791,6 +806,24 @@ public:
ACG::Vec4f* perHalfedgeColorBuffer();
/** \brief updates per edge and halfedge vertex declarations
*/
void updateEdgeHalfedgeVertexDeclarations();
/** \brief getter for vertex declarations
*/
const VertexDeclaration* getEdgeColoredVertexDeclaration() const {return vertexDeclEdgeCol_;}
/** \brief getter for vertex declarations
*/
const VertexDeclaration* getHalfedgeVertexDeclaration() const {return vertexDeclHalfedgePos_;}
/** \brief getter for vertex declarations
*/
const VertexDeclaration* getHalfedgeColoredVertexDeclaration() const {return vertexDeclHalfedgeCol_;}
private:
int updatePerEdgeBuffers_;
std::vector<ACG::Vec3f> perEdgeVertexBuf_;
......
......@@ -63,7 +63,7 @@ namespace ACG {
//#define GLSTATE_AVOID_REDUNDANT_GLCALLS
const Vec4f GLState::default_clear_color(0.0, 0.0, 0.0, 1.0);
const Vec4f GLState::default_base_color(1.0, 1.0, 1.0, 1.0);
const Vec4f GLState::default_base_color(0.0, 0.0, 0.0, 1.0);
const Vec4f GLState::default_ambient_color(0.2, 0.2, 0.2, 1.0);
const Vec4f GLState::default_diffuse_color(0.50, 0.53, 0.6, 1.0);
const Vec4f GLState::default_specular_color(0.75, 0.8, 0.85, 1.0);
......
......@@ -62,6 +62,10 @@ void ACG::RenderObject::initFromState( GLState* _glState )
depthWrite = true;
alphaTest = false;
colorWriteMask[0] = colorWriteMask[1] = colorWriteMask[2] = colorWriteMask[3] = 1;
fillMode = GL_FILL;
depthRange = Vec2f(0.0f, 1.0f);
depthFunc = GL_LESS;
......
......@@ -165,6 +165,10 @@ struct ACGDLLEXPORT RenderObject
bool depthTest;
bool depthWrite;
GLenum fillMode; // GL_POINT, GL_LINE, GL_FILL, default: GL_FILL
GLboolean colorWriteMask[4]; // {r,g,b,a}, default: all true
// GLenum shadeModel; // GL_FACE, GL_SMOOTH obsolute in shader pipeline
GLenum depthFunc; //!< GL_LESS, GL_LEQUAL, GL_GREATER ..
......@@ -227,7 +231,10 @@ struct ACGDLLEXPORT RenderObject
sysmemIndexBuffer = indices;
}
void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
colorWriteMask[0] = r; colorWriteMask[1] = g; colorWriteMask[2] = b; colorWriteMask[3] = a;
}
/** \brief Initializes a RenderObject instance.
*
......
......@@ -309,7 +309,7 @@ const VertexElement* VertexDeclaration::getElement(unsigned int i)
unsigned int VertexDeclaration::getVertexStride()
{
if (!vertexStride_)
if (!strideUserDefined_ && !vertexStride_)
{
// compute vertex stride from declaration
......@@ -333,6 +333,14 @@ void VertexDeclaration::setVertexStride(unsigned int _stride)
vertexStride_ = _stride;
}
void VertexDeclaration::clear()
{
strideUserDefined_ = 0;
vertexStride_ = 0;
elements_.clear();
}
//=============================================================================
} // namespace ACG
//=============================================================================
......@@ -197,6 +197,9 @@ public:
*/
void addElements(unsigned int _numElements, const VertexElement* _pElements);
/*! remove all vertex elements, also clears the user defined stride flag
*/
void clear();
/*! prepare OpenGL to use a vertex buffer with this declaration
-> uses the fixed function pointers (glVertexPointer, glColorPointer...)
......
......@@ -251,7 +251,23 @@ DrawMode& DrawMode::operator++() {
}
DrawMode DrawMode::operator&(const DrawMode& _mode) const {
return (modeFlags_ & _mode.modeFlags_);
DrawMode andMode = (modeFlags_ & _mode.modeFlags_);
andMode.setDrawModeProperties(getDrawModeProperties());
for (unsigned int i = 1; i < getNumLayers(); ++i)
andMode.addLayer(getLayer(i));
// remove all distinct layers
for (int i = (int)andMode.getNumLayers() - 1; i >= 0; --i)
{
int layerIndex = _mode.getLayerIndex(andMode.getLayer(i));
if (layerIndex < 0)
andMode.removeLayer(i);
}
return andMode;
}
DrawMode& DrawMode::operator|=( const DrawMode& _mode2 ) {
......@@ -266,6 +282,15 @@ DrawMode& DrawMode::operator|=( const DrawMode& _mode2 ) {
DrawMode& DrawMode::operator&=( const DrawMode& _mode2 ) {
modeFlags_ &= _mode2.modeFlags_;
// remove all distinct layers
for (int i = (int)getNumLayers() - 1; i >= 0; --i)
{
int layerIndex2 = _mode2.getLayerIndex(getLayer(i));
if (layerIndex2 < 0)
removeLayer(i);
}
return (*this);
}
......@@ -336,7 +361,10 @@ DrawMode DrawMode::operator^( const DrawMode& _mode2 ) const {
// DrawModes equal?
if (tmpLayers.empty())
{
xorMode.removeLayer(0u);
return xorMode; // return default property set to not cause exceptions
}
// layers not empty,
// copy to temporary drawmode and return
......@@ -431,11 +459,8 @@ const DrawModeProperties* DrawMode::getLayer( unsigned int i ) const {
void DrawMode::addLayer( const DrawModeProperties* _props )
{
for (unsigned int i = 0; i < layers_.size(); ++i)
{
if (!memcmp(&layers_[i], _props, sizeof(DrawModeProperties)))
if (getLayerIndex(_props) < 0)
return;
}
layers_.push_back(*_props);
}
......@@ -452,6 +477,27 @@ const DrawModeProperties* DrawMode::getDrawModeProperties() const
}
bool DrawMode::checkConsistency() const
{
// PRIMITIVE_CELL is the last primitive count (currently)
int count[PRIMITIVE_CELL+1] = {0};
return true;
}
int DrawMode::getLayerIndex( const DrawModeProperties* _prop ) const
{
for (unsigned int i = 0; i < layers_.size(); ++i)
{
if (!memcmp(&layers_[i], _prop, sizeof(DrawModeProperties)))
return (int)i;
}
return -1;
}
//----------------------------------------------------------------------------
......
......@@ -348,6 +348,13 @@ namespace DrawModes {
*/
bool removeLayer(const DrawModeProperties* _prop);
/** \brief returns layer index of a property, -1 if not in list
*
* @param _prop Property to be searched for
*/
int getLayerIndex(const DrawModeProperties* _prop) const;
/** @} */
......@@ -412,6 +419,12 @@ namespace DrawModes {
void setDrawModeProperties(const DrawModeProperties& _props);
/** \brief checks consistency of property layers
*
* There should only be at most one layer for each primitive type for example
*/
bool checkConsistency() const;
private:
ModeFlagSet modeFlags_;
......
......@@ -570,6 +570,190 @@ draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
glPopAttrib();
}
template <class Mesh>
void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode )
{
RenderObject ro = {0}; // zeromem
ro.initFromState(&_state);
// shader gen setup (lighting, shademode, vertex-colors..)
for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
{
const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
// reset renderobject
ro.priority = 0;
ro.depthRange = Vec2f(0.0f, 1.0f);
ro.depthTest = true; // some previous node disabled depth testing
ro.depthWrite = true;
ro.depthFunc = GL_LESS;
// ------------------------
// 1. setup drawMesh based on property source
if (props->flatShaded())
drawMesh_->setFlatShading();
else
drawMesh_->setSmoothShading();
ro.shaderDesc.vertexColors = true;
switch (props->colorSource())
{
case DrawModes::COLOR_PER_VERTEX: drawMesh_->usePerVertexColors(); break;
case DrawModes::COLOR_PER_FACE: drawMesh_->usePerFaceColors(); break;
default:
{
drawMesh_->disableColors();
ro.shaderDesc.vertexColors = false;
} break;
}
switch (props->normalSource())
{
case DrawModes::NORMAL_PER_VERTEX: drawMesh_->usePerVertexNormals(); break;
case DrawModes::NORMAL_PER_HALFEDGE: drawMesh_->usePerHalfedgeNormals(); break;
default: break;
}
ro.shaderDesc.textured = true;
switch (props->texcoordSource())
{
case DrawModes::TEXCOORD_PER_VERTEX: drawMesh_->usePerVertexTexcoords(); break;
case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
default:
{
ro.shaderDesc.textured = false;
}break;
}
// ------------------------
// 2. prepare renderobject
// enable / disable lighting
ro.shaderDesc.numLights = props->lighting() ? 0 : -1;
// TODO: better handling of attribute sources in shader gen
if (props->flatShaded())
ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
switch (props->lightStage())
{
case DrawModes::LIGHTSTAGE_SMOOTH: ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD; break;;
case DrawModes::LIGHTSTAGE_PHONG: ro.shaderDesc.shadeMode = SG_SHADE_PHONG; break;;
case DrawModes::LIGHTSTAGE_UNLIT: ro.shaderDesc.shadeMode = SG_SHADE_UNLIT; break;;
}
// handle 'special' primitives (wireframe, hiddenline, primitives in sysmem buffers)..