diff --git a/ACG/GL/DrawMesh.hh b/ACG/GL/DrawMesh.hh index a46ff7543ff344c71e3d8bdae962b6c6b3728009..80e9656c51532906230dd060653b3652b0536730 100644 --- a/ACG/GL/DrawMesh.hh +++ b/ACG/GL/DrawMesh.hh @@ -227,19 +227,20 @@ public: /** \brief binds index and vertex buffer and executes draw calls * - * @param _textureMap maps from internally texture-id to OpenGL texture id - * may be null to disable textured rendering + * @param _textureMap maps from internally texture-id to OpenGL texture id, may be null to disable textured rendering + * @param _nonindexed use unoptimized non-indexed vbo for rendering, not as efficient in terms of memory usage and performance as an indexed draw call. */ - void draw(std::map< int, GLuint>* _textureMap); + void draw(std::map< int, GLuint>* _textureMap, bool _nonindexed = false); /** \brief adds RenderObjects to a deferred draw call renderer * * @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 + * @param _nonindexed use non-indexed vbo instead of optimized indexed vbo (should be avoided if possible) * may be null to disable textured rendering */ - void addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap); + void addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap, bool _nonindexed = false); /** \brief render the mesh in wireframe mode */ @@ -936,6 +937,46 @@ private: void writeVertexProperty(unsigned int _vertex, const VertexElement* _elementDesc, const ACG::Vec4d& _propd); + /** \brief Read one vertex from the rendering vbo. + * + * @param _vertex vertex id from the rendering vbo (not the original input id from openmesh!) + * @param _dst [out] pointer to address that will store the vertex. Must have enough space allocated, see vertex declaration stride to get the number of bytes + */ + void readVertexFromVBO(unsigned int _vertex, void* _dst); + + +public: + + //=========================================================================== + // fully expanded vbo + //=========================================================================== + + + /** \brief the mesh has been changed + * + * call this function if you changed anything of the mesh. + */ + void invalidateFullVBO(); + + /** \brief update the full mesh vbo + * + * the full vbo is the non-indexed version for drawing. + * it's not optimized for rendering at all and it uses lots of memory, so should only be used as last resort. + */ + void updateFullVBO(); + + +private: + // fully expanded mesh vbo (not indexed) + // this is only used for drawmodes with incompatible combinations of interpolation modes (ex. smooth gouraud lighting with flat face colors) + GeometryBuffer vboFull_; + + // full vbo has been invalidated + bool updateFullVBO_; + + + + public: //======================================================================== // per edge buffers diff --git a/ACG/GL/DrawMeshT.cc b/ACG/GL/DrawMeshT.cc index 7d75e3b30c392b12525f89b306a8dde14b30cb82..148bd37640aa8f69683d3375949a1e7d78a5c5e6 100644 --- a/ACG/GL/DrawMeshT.cc +++ b/ACG/GL/DrawMeshT.cc @@ -82,6 +82,7 @@ DrawMeshT::DrawMeshT(Mesh& _mesh) halfedgeNormalMode_(0), bVBOinHalfedgeNormalMode_(0), invVertexMap_(0), offsetPos_(0), offsetNormal_(20), offsetTexc_(12), offsetColor_(32), + updateFullVBO_(true), textureIndexPropertyName_("Not Set"), perFaceTextureCoordinatePropertyName_("Not Set"), updatePerEdgeBuffers_(1), @@ -455,6 +456,7 @@ DrawMeshT::rebuild() return; } + invalidateFullVBO(); unsigned int maxFaceVertCount = 0; @@ -1088,6 +1090,9 @@ DrawMeshT::createVBO() fillVertexBuffer(); ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + // non indexed vbo needs updating now + invalidateFullVBO(); } template @@ -1117,7 +1122,7 @@ DrawMeshT::createIBO() // line index buffer: if (mesh_.n_edges()) { - unsigned int* pLineBuffer = new unsigned int[mesh_.n_edges() * 2]; + std::vector lineBuffer(mesh_.n_edges() * 2); for (unsigned int i = 0; i < mesh_.n_edges(); ++i) { @@ -1125,22 +1130,20 @@ DrawMeshT::createIBO() if (indexType_ == GL_UNSIGNED_SHORT) { - ((unsigned short*)pLineBuffer)[2*i] = (unsigned short)invVertexMap_[mesh_.from_vertex_handle(hh).idx()]; - ((unsigned short*)pLineBuffer)[2*i+1] = (unsigned short)invVertexMap_[mesh_.to_vertex_handle(hh).idx()]; + // put two words in a dword + unsigned int combinedIdx = invVertexMap_[mesh_.from_vertex_handle(hh).idx()] | (invVertexMap_[mesh_.to_vertex_handle(hh).idx()] << 16); + lineBuffer[i] = combinedIdx; } else { - pLineBuffer[2*i] = invVertexMap_[mesh_.from_vertex_handle(hh).idx()]; - pLineBuffer[2*i+1] = invVertexMap_[mesh_.to_vertex_handle(hh).idx()]; + lineBuffer[2 * i] = invVertexMap_[mesh_.from_vertex_handle(hh).idx()]; + lineBuffer[2 * i + 1] = invVertexMap_[mesh_.to_vertex_handle(hh).idx()]; } } bindLineIbo(); - fillLineBuffer(mesh_.n_edges(), pLineBuffer); - - // FIXME: This is not exception safe and may lead to memory leaks. - delete [] pLineBuffer; + fillLineBuffer(mesh_.n_edges(), &lineBuffer[0]); } ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); @@ -1346,9 +1349,16 @@ void DrawMeshT::unbindBuffers() } template -void DrawMeshT::draw(std::map< int, GLuint>* _textureMap) +void DrawMeshT::draw(std::map< int, GLuint>* _textureMap, bool _nonindexed) { - bindBuffers(); + if (!_nonindexed) + bindBuffers(); + else + { + updateFullVBO(); + vboFull_.bind(); + vertexDecl_->activateFixedFunction(); + } #ifdef DEBUG_MEM_USAGE getMemoryUsage(true); @@ -1371,12 +1381,20 @@ void DrawMeshT::draw(std::map< int, GLuint>* _textureMap) else ACG::GLState::bindTexture(GL_TEXTURE_2D, (*_textureMap)[sub->id]); - glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_, - (GLvoid*)( (size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes + if (!_nonindexed) + glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_, + (GLvoid*)( (size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes + else + glDrawArrays(GL_TRIANGLES, sub->startIndex, sub->numTris * 3); } } else - glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0); + { + if (!_nonindexed) + glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0); + else + glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3); + } } unbindBuffers(); @@ -1384,12 +1402,20 @@ void DrawMeshT::draw(std::map< int, GLuint>* _textureMap) template -void ACG::DrawMeshT::addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap) +void ACG::DrawMeshT::addTriRenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, std::map< int, GLuint>* _textureMap, bool _nonindexed) { if (numTris_) { RenderObject ro = *_baseObj; - bindBuffersToRenderObject(&ro); + if (!_nonindexed) + bindBuffersToRenderObject(&ro); + else + { + updateFullVBO(); + + ro.vertexBuffer = vboFull_.id(); + ro.vertexDecl = vertexDecl_; + } if (_baseObj->shaderDesc.textured()) { @@ -1426,15 +1452,21 @@ void ACG::DrawMeshT::addTriRenderObjects(IRenderer* _renderer, const Rende - ro.glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_, - (GLvoid*)( (size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes + if (!_nonindexed) + ro.glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_, + (GLvoid*)((size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2))); // offset in bytes + else + ro.glDrawArrays(GL_TRIANGLES, sub->startIndex, sub->numTris * 3); _renderer->addRenderObject(&ro); } } else { - ro.glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0); + if (!_nonindexed) + ro.glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0); + else + ro.glDrawArrays(GL_TRIANGLES,0, numTris_ * 3); _renderer->addRenderObject(&ro); } } @@ -2681,4 +2713,84 @@ void DrawMeshT::dumpObj(const char* _filename) const +template +void ACG::DrawMeshT::readVertexFromVBO(unsigned int _vertex, void* _dst) +{ + assert(_dst != 0); + + unsigned int stride = vertexDecl_->getVertexStride(); + + // byte offset + unsigned int offset = _vertex * stride; + + // copy + memcpy(_dst, &vertices_[offset], stride); +} + + + + + +template +void ACG::DrawMeshT::invalidateFullVBO() +{ + updateFullVBO_ = true; +} + + +template +void ACG::DrawMeshT::updateFullVBO() +{ + // update indexed vbo first, in the next step this vbo is resolved into non-indexed + updateGPUBuffers(); + + if (updateFullVBO_) + { + MeshCompiler* mc = getMeshCompiler(); + + if (mc) + { + int numTris = mc->getNumTriangles(); + + // alloc buffer + int numVerts = 3 * numTris; + int stride = mc->getVertexDeclaration()->getVertexStride(); + std::vector fullBuf(numVerts * stride); + + // fill buffer + for (int i = 0; i < numTris; ++i) + { + for (int k = 0; k < 3; ++k) + { + int idx = i * 3 + k; + int vertexID = mc->getIndex(idx); + readVertexFromVBO(vertexID, &fullBuf[idx * stride]); + + if (colorMode_ == 2) + { + // read face color + + int faceId = meshComp_->mapToOriginalFaceID(i); + unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId)); + + // store face color + writeVertexElement(&fullBuf[0], idx, vertexDecl_->getVertexStride(), offsetColor_, 4, &fcolor); + } + + } + } + + if (!fullBuf.empty()) + vboFull_.upload(fullBuf.size(), &fullBuf[0], GL_STATIC_DRAW); + + // clean update flag + updateFullVBO_ = false; + } + } +} + + + + + } diff --git a/ACG/GL/ShaderCache.cc b/ACG/GL/ShaderCache.cc index 085825a1ea9a709dac2c827b45201076e4bbda28..6d8bebbd1be265148ca7fe8e2eaf81ccc2558f6f 100644 --- a/ACG/GL/ShaderCache.cc +++ b/ACG/GL/ShaderCache.cc @@ -266,7 +266,7 @@ GLSL::Program* ACG::ShaderCache::getProgram( const ShaderGenDesc* _desc, const s if (oldCache != cache_.end()) { - if (!prog || !prog->isLinked()) + if (!prog->isLinked()) { delete prog; return oldCache->second; @@ -574,18 +574,6 @@ int ACG::ShaderCache::compareShaderGenDescs( const CacheEntry* _a, const CacheEn const ShaderGenDesc* a = &_a->desc; const ShaderGenDesc* b = &_b->desc; - if (a->numLights != b->numLights) - return -1; - - if (a->shadeMode != b->shadeMode) - return -1; - - if (a->vertexColors != b->vertexColors) - return -1; - - if (a->textured() != b->textured()) - return -1; - if (_a->strFragmentTemplate != _b->strFragmentTemplate) return -1; @@ -605,10 +593,7 @@ int ACG::ShaderCache::compareShaderGenDescs( const CacheEntry* _a, const CacheEn return -1; - if (a->numLights) - return memcmp(a->lightTypes, b->lightTypes, a->numLights * sizeof(ShaderGenLightType)); - - return 0; // false + return *a == *b ? 0 : -1; } diff --git a/ACG/GL/ShaderGenerator.cc b/ACG/GL/ShaderGenerator.cc index 1a4fd5e42cdfc931ee993d38fb0ecb217924b0e1..a072ccc9bc4dac7e8d0267a85f7f3400b8771ce0 100644 --- a/ACG/GL/ShaderGenerator.cc +++ b/ACG/GL/ShaderGenerator.cc @@ -154,23 +154,29 @@ void ShaderGenerator::initVertexShaderIO(const ShaderGenDesc* _desc, const Defau - std::string strColorOut = ""; + // vertex color output - - if (_desc->shadeMode == SG_SHADE_FLAT) - if (!_desc->geometryTemplateFile.isEmpty()) - strColorOut = "vec4 outVertexColor"; + if (_desc->vertexColorsInterpolator.isEmpty()) + { + std::string strColorOut = ""; + if (_desc->shadeMode == SG_SHADE_FLAT) + if (!_desc->geometryTemplateFile.isEmpty()) + strColorOut = "vec4 outVertexColor"; + else { + // Bypass the output setter, as we have to set that directly with the flat. + addStringToList("vec4 outVertexColor", &outputs_, "flat out ", ";"); + } else { - // Bypass the output setter, as we have to set that directly with the flat. - addStringToList("vec4 outVertexColor", &outputs_, "flat out ", ";"); + if (_desc->shadeMode == SG_SHADE_GOURAUD || _desc->vertexColors || _iodesc->inputColor_) + strColorOut = "vec4 outVertexColor"; } - else { - if (_desc->shadeMode == SG_SHADE_GOURAUD || _desc->vertexColors || _iodesc->inputColor_) - strColorOut = "vec4 outVertexColor"; + + if (strColorOut.size()) + addOutput(strColorOut.c_str()); } + else + addStringToList("vec4 outVertexColor", &outputs_, _desc->vertexColorsInterpolator + " out ", ";"); - if (strColorOut.size()) - addOutput(strColorOut.c_str()); // handle other requests: normals, positions, texcoords @@ -311,7 +317,7 @@ void ShaderGenerator::defineIOAbstraction( const DefaultIODesc* _iodesc, bool _v addDefine(SG_INPUT_NORMALOS " inNormal"); if (_iodesc->inputColor_) - addDefine(SG_INPUT_VERTEXCOLOR "inColor"); + addDefine(SG_INPUT_VERTEXCOLOR " inColor"); @@ -1156,8 +1162,8 @@ void ShaderProgGenerator::addVertexBeginCode(QStringList* _code) _code->push_back("sg_vNormalOS = normalize(inNormal);"); } - if (ioDesc_.inputColor_) - _code->push_back("sg_cColor = inColor;"); + if (ioDesc_.inputColor_ && (desc_.shadeMode == SG_SHADE_UNLIT || desc_.colorMaterialMode == GL_EMISSION)) + _code->push_back("sg_cColor = " SG_INPUT_VERTEXCOLOR ";"); // apply modifiers @@ -1761,12 +1767,9 @@ void ShaderProgGenerator::addFragmentBeginCode(QStringList* _code) _code->push_back("vec4 sg_cColor = vec4(g_cEmissive, SG_ALPHA);"); if (desc_.shadeMode == SG_SHADE_GOURAUD || - desc_.shadeMode == SG_SHADE_FLAT || - desc_.vertexColors) - { - _code->push_back("sg_cColor = out" + inputShader + "Color;"); - } - + desc_.shadeMode == SG_SHADE_FLAT || + (ioDesc_.passColor_ && (desc_.shadeMode == SG_SHADE_UNLIT || desc_.colorMaterialMode == GL_EMISSION))) + _code->push_back("sg_cColor = " SG_INPUT_VERTEXCOLOR ";"); if (desc_.shadeMode == SG_SHADE_PHONG) addLightingCode(_code); @@ -1823,6 +1826,11 @@ void ShaderProgGenerator::addLightingCode(QStringList* _code) QString buf; + const char* vertexColorString = (ioDesc_.inputColor_ && ioDesc_.passColor_) ? SG_INPUT_VERTEXCOLOR ".xyz * " : ""; + const char* diffuseVertexColor = (desc_.colorMaterialMode == GL_DIFFUSE || desc_.colorMaterialMode == GL_AMBIENT_AND_DIFFUSE) ? vertexColorString : ""; + const char* ambientVertexColor = (desc_.colorMaterialMode == GL_AMBIENT || desc_.colorMaterialMode == GL_AMBIENT_AND_DIFFUSE) ? vertexColorString : ""; + const char* specularVertexColor = (desc_.colorMaterialMode == GL_SPECULAR) ? vertexColorString : ""; + for (int i = 0; i < desc_.numLights; ++i) { ShaderGenLightType lgt = desc_.lightTypes[i]; @@ -1830,15 +1838,15 @@ void ShaderProgGenerator::addLightingCode(QStringList* _code) switch (lgt) { case SG_LIGHT_DIRECTIONAL: - buf.sprintf("sg_cColor.xyz += LitDirLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightDir_%d, g_cLightAmbient_%d, g_cLightDiffuse_%d, g_cLightSpecular_%d);", i, i, i, i); + buf.sprintf("sg_cColor.xyz += LitDirLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightDir_%d, %s g_cLightAmbient_%d, %s g_cLightDiffuse_%d, %s g_cLightSpecular_%d);", i, ambientVertexColor, i, diffuseVertexColor, i, specularVertexColor, i); break; case SG_LIGHT_POINT: - buf.sprintf("sg_cColor.xyz += LitPointLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightPos_%d, g_cLightAmbient_%d, g_cLightDiffuse_%d, g_cLightSpecular_%d, g_vLightAtten_%d);", i, i, i, i, i); + buf.sprintf("sg_cColor.xyz += LitPointLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightPos_%d, %s g_cLightAmbient_%d, %s g_cLightDiffuse_%d, %s g_cLightSpecular_%d, g_vLightAtten_%d);", i, ambientVertexColor, i, diffuseVertexColor, i, specularVertexColor, i, i); break; case SG_LIGHT_SPOT: - buf.sprintf("sg_cColor.xyz += LitSpotLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightPos_%d, g_vLightDir_%d, g_cLightAmbient_%d, g_cLightDiffuse_%d, g_cLightSpecular_%d, g_vLightAtten_%d, g_vLightAngleExp_%d);", i, i, i, i, i, i, i); + buf.sprintf("sg_cColor.xyz += LitSpotLight(sg_vPosVS.xyz, sg_vNormalVS, g_vLightPos_%d, g_vLightDir_%d, %s g_cLightAmbient_%d, %s g_cLightDiffuse_%d, %s g_cLightSpecular_%d, g_vLightAtten_%d, g_vLightAngleExp_%d);", i, i, ambientVertexColor, i, diffuseVertexColor, i, specularVertexColor, i, i, i); break; default: break; diff --git a/ACG/GL/ShaderGenerator.hh b/ACG/GL/ShaderGenerator.hh index fdd64392b040c84c95fb180f58733859e13be489..847fce440e792c53a8db6563f28eea16b720e25c 100644 --- a/ACG/GL/ShaderGenerator.hh +++ b/ACG/GL/ShaderGenerator.hh @@ -94,6 +94,7 @@ public: geometryTemplateFile(""), fragmentTemplateFile(""), normalizeTexColors(true), + colorMaterialMode(GL_AMBIENT_AND_DIFFUSE), textureTypes_() { for ( unsigned int i = 0 ; i < SG_MAX_SHADER_LIGHTS ; ++i) @@ -150,7 +151,13 @@ public: /// Defines if the textureVariable is normalized or not, if multiple textures are used bool normalizeTexColors; + /// interpolation qualifier for input vertex colors: "flat", "smooth", "noperspective" + QString vertexColorsInterpolator; + // color material for input vertex colors: GL_EMISSION, GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_AMBIENT_AND_DIFFUSE + // Usage of vertex colors in lighting function, as diffuse, emission, ambient color .. see glColorMaterial() + // default: GL_AMBIENT_AND_DIFFUSE + GLenum colorMaterialMode; struct TextureType { @@ -158,6 +165,7 @@ public: bool shadow; }; private: + // TODO: remove this, multitexturing always requires some customization! should be done via custom shader templates or mods. only allow one diffuse texture, as this is something commonly used and intentions are clear /// holds the texture types (second) and the stage id (first). if empty, shader does not support textures std::map textureTypes_; @@ -180,6 +188,52 @@ public: bool textured()const {return !textureTypes_.empty();} + + + // comparison operator + bool operator == (const ShaderGenDesc& _rhs) const + { + if (numLights != _rhs.numLights) + return false; + + if (shadeMode != _rhs.shadeMode) + return false; + + if (vertexColors != _rhs.vertexColors) + return false; + + if (textured() != _rhs.textured()) + return false; + + if (vertexColors) + { + if (vertexColorsInterpolator != _rhs.vertexColorsInterpolator) + return false; + + if (colorMaterialMode != _rhs.colorMaterialMode) + return false; + } + + if (fragmentTemplateFile != _rhs.fragmentTemplateFile) + return false; + + if (geometryTemplateFile != _rhs.geometryTemplateFile) + return false; + + if (vertexTemplateFile != _rhs.vertexTemplateFile) + return false; + + if (tessControlTemplateFile != _rhs.tessControlTemplateFile) + return false; + + if (_rhs.tessEvaluationTemplateFile != _rhs.tessEvaluationTemplateFile) + return false; + + if (numLights) + return memcmp(lightTypes, _rhs.lightTypes, numLights * sizeof(ShaderGenLightType)) == 0; + + return true; + } }; diff --git a/ACG/Scenegraph/MeshNode2T.cc b/ACG/Scenegraph/MeshNode2T.cc index 5b707a5eccff7deb01a82c795e15d7d00febbe97..9e17d9de2da684308e02f67868bfedb08650d117 100644 --- a/ACG/Scenegraph/MeshNode2T.cc +++ b/ACG/Scenegraph/MeshNode2T.cc @@ -503,7 +503,8 @@ draw(GLState& _state, const DrawModes::DrawMode& _drawMode) { drawMesh_->usePerVertexNormals(); drawMesh_->usePerFaceColors(); - draw_faces(); + + drawMesh_->draw(textureMap_, true); ACG::GLState::depthRange(0.0, 1.0); _state.set_base_color(base_color_backup); @@ -640,6 +641,8 @@ void ACG::SceneGraph::MeshNodeT::getRenderObjects( IRenderer* _renderer, G ro.shaderDesc.geometryTemplateFile = ""; //QString(props->geometryShader().c_str()); ro.shaderDesc.fragmentTemplateFile = ""; //QString(props->fragmentShader().c_str()); + ro.shaderDesc.vertexColorsInterpolator = ""; + // ------------------------ // 1. setup drawMesh based on property source @@ -854,7 +857,13 @@ void ACG::SceneGraph::MeshNodeT::getRenderObjects( IRenderer* _renderer, G if (!ro.shaderDesc.vertexTemplateFile.isEmpty()) drawMesh_->scanVertexShaderForInput(ro.shaderDesc.vertexTemplateFile.toStdString()); - add_face_RenderObjects(_renderer, &ro); + bool useNonIndexed = (props->colorSource() == DrawModes::COLOR_PER_FACE) && (props->lightStage() == DrawModes::LIGHTSTAGE_SMOOTH) && !props->flatShaded(); + if (!useNonIndexed && props->colorSource() == DrawModes::COLOR_PER_FACE) + ro.shaderDesc.vertexColorsInterpolator = "flat"; + + add_face_RenderObjects(_renderer, &ro, useNonIndexed); + + ro.shaderDesc.vertexColorsInterpolator = ""; } break; default: break; } @@ -927,8 +936,8 @@ draw_faces() { template void MeshNodeT:: -add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) { - drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_); +add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, bool _nonindexed) { + drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_, _nonindexed); } template @@ -1228,7 +1237,7 @@ pick_edges(GLState& _state, bool _front) enable_arrays(0); } - if (_state.color_picking () ) { + if (_state.color_picking () && drawMesh_ ) { // picking implementations: // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 32 bytes per openmesh edge) @@ -1411,7 +1420,7 @@ pick_any(GLState& _state) return; } - if (_state.color_picking()) { + if (_state.color_picking() && drawMesh_) { // picking implementations: // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 48 bytes per triangle + 32 bytes per edge + 16 bytes per vertex) @@ -1513,6 +1522,7 @@ update_geometry() { drawMesh_->updateGeometry(); + drawMesh_->invalidateFullVBO(); // First of all, we update the bounding box: bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX); @@ -1616,6 +1626,8 @@ MeshNodeT::getDrawMesh() } + + //============================================================================= } // namespace SceneGraph } // namespace ACG diff --git a/ACG/Scenegraph/MeshNode2T.hh b/ACG/Scenegraph/MeshNode2T.hh index 439b471b2457612f1ff7e37044e613ecb2886ed2..3b94aa73b047f79af2dff2cae765f732fd2863b6 100644 --- a/ACG/Scenegraph/MeshNode2T.hh +++ b/ACG/Scenegraph/MeshNode2T.hh @@ -185,17 +185,16 @@ private: /** @} */ //=========================================================================== -/** @name Strip generation and handling +/** @name Draw-mesh handling * @{ */ //=========================================================================== -public: -// void update_strips(); - private: DrawMeshT* drawMesh_; /** @} */ + + //=========================================================================== /** @name Bounding Box * @{ */ @@ -342,7 +341,7 @@ private: */ void draw_faces(); - void add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj); + void add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, bool _nonindexed = false); private: