mesh with triangle adjacency

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

mesh with triangle adjacency

Post by bishopnator »

Hello everyone,
it's already longer time for me to use Ogre and in meantime used some other rendering engines - now I would like to port one rendering technique involving geometry shaders to Ogre, but it seems that Ogre has some design failures with adjacency information with geometry shaders.

Let's consider a mesh which has adjacency information and you would like to render the same mesh with different set of shaders - in DX and also in OpenGL it is not a problem to render mesh with adjacency information also without geometry shader - the rendering system interpret the index buffer correctly (it just skips the adjacent vertices if geometry shader is not present). However in Ogre it seems impossible to do that - the RenderOperation needs to be set to triangle list (there is no other value for triangle list with adj.) and rendering system just setup correctly the data only if GS is also set through material and has the flag 'uses_adjacency_information' set to true - so such mesh is not possible to render correctly without GS.

To clarify just why something like this is useful - you have a single mesh and want to render it with different render modes - shaded, wireframe, etc. - some of them uses GS, some of them not (for example for rendering a cylinder I want to display only contour edges - here the adjacency info comes handy, but for phong shading it is not needed. Of course it is possible to create 2 meshes - but is it really a good way to go as with DX/GL it is possible to use a single mesh?

So I think it would be better to extend the render operation enum which reflects the mesh format directly - the 'uses_adjacency_information' is not important and makes the evil. With extending the RenderOperation it is direct description of the mesh - now also comments don't match - for example:
/// A list of triangles, 3 vertices per triangle
OT_TRIANGLE_LIST = 4,
If geometry shader with 'uses_adjacency_information true' is present in mateiral, 6 vertices per triangle are required.

I hope I didn't miss something important - now I am looking in source codes directly (I don't have some working example to prove the above).

note: also the computation of primCount in D3D11RenderSystem::_render is not correct - with adjacency it is just half of the value compute there. However it doesn't make huge problems as the value is not use (except for a check that there is something to render (so != 0), but why not to compute correct value?
paroj
OGRE Team Member
OGRE Team Member
Posts: 2106
Joined: Sun Mar 30, 2014 2:51 pm
x 1132

Re: mesh with triangle adjacency

Post by paroj »

This Sounds indeed Like a Design failure on the ogre Side. Can you provide a pull request With your proposed Changes?
User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Re: mesh with triangle adjacency

Post by bishopnator »

Hello, below I copy/pasted the patch content. I only compiled the changes (didn't test them) - take it only as suggestions/directions what I meant in my initial post. I don't know Ogre well enough now to make deeper integration and testing.

Code: Select all

# HG changeset patch
# User bishopnator
# Date 1533247009 -7200
#      Thu Aug 02 23:56:49 2018 +0200
# Node ID fcf64f383a6b8376883cf5d487172f6e0880ac4f
# Parent  f57d6657fbd6d8807e2edc8b99992701d0943a23
Added RenderOperation::OT_xxx_ADJ types to reflect the format of vertex buffer
(or index buffer if indices are used) if it contains adjacency information. The
render system interprets the data correctly also if geometry shader is not used.

diff -r f57d6657fbd6 -r fcf64f383a6b OgreMain/include/OgreGpuProgram.h
--- a/OgreMain/include/OgreGpuProgram.h	Sat Jun 09 00:02:47 2018 +0200
+++ b/OgreMain/include/OgreGpuProgram.h	Thu Aug 02 23:56:49 2018 +0200
@@ -113,12 +113,6 @@
         String doGet(const void* target) const;
         void doSet(void* target, const String& val);
     };
-    class _OgreExport CmdAdjacency : public ParamCommand
-    {
-    public:
-        String doGet(const void* target) const;
-        void doSet(void* target, const String& val);
-    };
     class _OgreExport CmdComputeGroupDims : public ParamCommand
     {
     public:
@@ -133,7 +127,6 @@
     static CmdPose msPoseCmd;
     static CmdVTF msVTFCmd;
     static CmdManualNamedConstsFile msManNamedConstsFileCmd;
-    static CmdAdjacency msAdjacencyCmd;
     static CmdComputeGroupDims msComputeGroupDimsCmd;
     /// The type of the program
     GpuProgramType mType;
@@ -153,8 +146,6 @@
     ushort mPoseAnimation;
     /// Does this (vertex) program require support for vertex texture fetch?
     bool mVertexTextureFetch;
-    /// Does this (geometry) program require adjacency information?
-    bool mNeedsAdjacencyInfo;
     /// The number of process groups dispatched by this (compute) program.
     Vector3 mComputeGroupDimensions;
     /// The default parameters for use with this object
@@ -326,15 +317,7 @@
     */
     virtual bool isVertexTextureFetchRequired(void) const { return mVertexTextureFetch; }
 
-    /** Sets whether this geometry program requires adjacency information
-        from the input primitives.
-    */
-    virtual void setAdjacencyInfoRequired(bool r) { mNeedsAdjacencyInfo = r; }
-    /** Returns whether this geometry program requires adjacency information
-        from the input primitives.
-    */
-    virtual bool isAdjacencyInfoRequired(void) const { return mNeedsAdjacencyInfo; }
-    /** Sets the number of process groups dispatched by this compute
+	/** Sets the number of process groups dispatched by this compute
         program.
      */
     virtual void setComputeGroupDimensions(Vector3 dimensions) { mComputeGroupDimensions = dimensions; }
diff -r f57d6657fbd6 -r fcf64f383a6b OgreMain/include/OgreRenderOperation.h
--- a/OgreMain/include/OgreRenderOperation.h	Sat Jun 09 00:02:47 2018 +0200
+++ b/OgreMain/include/OgreRenderOperation.h	Thu Aug 02 23:56:49 2018 +0200
@@ -50,47 +50,55 @@
             OT_POINT_LIST = 1,
             /// A list of lines, 2 vertices per line
             OT_LINE_LIST = 2,
+            /// A list of lines with adjacency, 4 vertices per line (p0-p1-p2-p3 .. p1-p2 is the line, p0 is adjacenct vertex befor the line and p3 after the line)
+            OT_LINE_LIST_ADJ = 3,
             /// A strip of connected lines, 1 vertex per line plus 1 start vertex
-            OT_LINE_STRIP = 3,
+            OT_LINE_STRIP = 4,
+            /// A strip of connected lines with adjacency, 1 vertex per line plus 1 start vertex + 2 vertices (one before 1st in strip and one after the last in strip)
+            OT_LINE_STRIP_ADJ = 5,
             /// A list of triangles, 3 vertices per triangle
-            OT_TRIANGLE_LIST = 4,
+            OT_TRIANGLE_LIST = 6,
+            /// A list of triangles with adjacency, 6 vertices per triangle (p0-p1-p2-p3-p4-p5 .. p0-p2-p4 is the triangle and p1, p3 and p5 are the vertices od adjacent triangles)
+            OT_TRIANGLE_LIST_ADJ = 7,
             /// A strip of triangles, 3 vertices for the first triangle, and 1 per triangle after that
-            OT_TRIANGLE_STRIP = 5,
+            OT_TRIANGLE_STRIP = 8,
+            /// A strip of triangles with adjacency (see https://docs.microsoft.com/en-us/windows/desktop/direct3d11/d3d10-graphics-programming-guide-primitive-topologies)
+            OT_TRIANGLE_STRIP_ADJ = 9,
             /// A fan of triangles, 3 vertices for the first triangle, and 1 per triangle after that
-            OT_TRIANGLE_FAN = 6,
+            OT_TRIANGLE_FAN = 10,
             /// Patch control point operations, used with tessellation stages
-            OT_PATCH_1_CONTROL_POINT    = 7,
-            OT_PATCH_2_CONTROL_POINT    = 8,
-            OT_PATCH_3_CONTROL_POINT    = 9,
-            OT_PATCH_4_CONTROL_POINT    = 10,
-            OT_PATCH_5_CONTROL_POINT    = 11,
-            OT_PATCH_6_CONTROL_POINT    = 12,
-            OT_PATCH_7_CONTROL_POINT    = 13,
-            OT_PATCH_8_CONTROL_POINT    = 14,
-            OT_PATCH_9_CONTROL_POINT    = 15,
-            OT_PATCH_10_CONTROL_POINT   = 16,
-            OT_PATCH_11_CONTROL_POINT   = 17,
-            OT_PATCH_12_CONTROL_POINT   = 18,
-            OT_PATCH_13_CONTROL_POINT   = 19,
-            OT_PATCH_14_CONTROL_POINT   = 20,
-            OT_PATCH_15_CONTROL_POINT   = 21,
-            OT_PATCH_16_CONTROL_POINT   = 22,
-            OT_PATCH_17_CONTROL_POINT   = 23,
-            OT_PATCH_18_CONTROL_POINT   = 24,
-            OT_PATCH_19_CONTROL_POINT   = 25,
-            OT_PATCH_20_CONTROL_POINT   = 26,
-            OT_PATCH_21_CONTROL_POINT   = 27,
-            OT_PATCH_22_CONTROL_POINT   = 28,
-            OT_PATCH_23_CONTROL_POINT   = 29,
-            OT_PATCH_24_CONTROL_POINT   = 30,
-            OT_PATCH_25_CONTROL_POINT   = 31,
-            OT_PATCH_26_CONTROL_POINT   = 32,
-            OT_PATCH_27_CONTROL_POINT   = 33,
-            OT_PATCH_28_CONTROL_POINT   = 34,
-            OT_PATCH_29_CONTROL_POINT   = 35,
-            OT_PATCH_30_CONTROL_POINT   = 36,
-            OT_PATCH_31_CONTROL_POINT   = 37,
-            OT_PATCH_32_CONTROL_POINT   = 38
+            OT_PATCH_1_CONTROL_POINT    = 11,
+            OT_PATCH_2_CONTROL_POINT    = 12,
+            OT_PATCH_3_CONTROL_POINT    = 13,
+            OT_PATCH_4_CONTROL_POINT    = 14,
+            OT_PATCH_5_CONTROL_POINT    = 15,
+            OT_PATCH_6_CONTROL_POINT    = 16,
+            OT_PATCH_7_CONTROL_POINT    = 17,
+            OT_PATCH_8_CONTROL_POINT    = 18,
+            OT_PATCH_9_CONTROL_POINT    = 19,
+            OT_PATCH_10_CONTROL_POINT   = 20,
+            OT_PATCH_11_CONTROL_POINT   = 21,
+            OT_PATCH_12_CONTROL_POINT   = 22,
+            OT_PATCH_13_CONTROL_POINT   = 23,
+            OT_PATCH_14_CONTROL_POINT   = 24,
+            OT_PATCH_15_CONTROL_POINT   = 25,
+            OT_PATCH_16_CONTROL_POINT   = 26,
+            OT_PATCH_17_CONTROL_POINT   = 27,
+            OT_PATCH_18_CONTROL_POINT   = 28,
+            OT_PATCH_19_CONTROL_POINT   = 29,
+            OT_PATCH_20_CONTROL_POINT   = 30,
+            OT_PATCH_21_CONTROL_POINT   = 31,
+            OT_PATCH_22_CONTROL_POINT   = 32,
+            OT_PATCH_23_CONTROL_POINT   = 33,
+            OT_PATCH_24_CONTROL_POINT   = 34,
+            OT_PATCH_25_CONTROL_POINT   = 35,
+            OT_PATCH_26_CONTROL_POINT   = 36,
+            OT_PATCH_27_CONTROL_POINT   = 37,
+            OT_PATCH_28_CONTROL_POINT   = 38,
+            OT_PATCH_29_CONTROL_POINT   = 39,
+            OT_PATCH_30_CONTROL_POINT   = 40,
+            OT_PATCH_31_CONTROL_POINT   = 41,
+            OT_PATCH_32_CONTROL_POINT   = 42
         };
 
         /// Vertex source data
diff -r f57d6657fbd6 -r fcf64f383a6b OgreMain/src/OgreGpuProgram.cpp
--- a/OgreMain/src/OgreGpuProgram.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/OgreMain/src/OgreGpuProgram.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -40,7 +40,6 @@
     GpuProgram::CmdPose GpuProgram::msPoseCmd;
     GpuProgram::CmdVTF GpuProgram::msVTFCmd;
     GpuProgram::CmdManualNamedConstsFile GpuProgram::msManNamedConstsFileCmd;
-    GpuProgram::CmdAdjacency GpuProgram::msAdjacencyCmd;
     GpuProgram::CmdComputeGroupDims GpuProgram::msComputeGroupDimsCmd;
     
 
@@ -50,7 +49,7 @@
         :Resource(creator, name, handle, group, isManual, loader),
         mType(GPT_VERTEX_PROGRAM), mLoadFromFile(true), mSkeletalAnimation(false),
         mMorphAnimation(false), mPoseAnimation(0),
-        mVertexTextureFetch(false), mNeedsAdjacencyInfo(false),
+        mVertexTextureFetch(false),
         mCompileError(false), mLoadedManualNamedConstants(false)
     {
         createParameterMappingStructures();
@@ -360,10 +359,6 @@
                          "File containing named parameter mappings for low-level programs.", PT_BOOL), 
             &msManNamedConstsFileCmd);
         dict->addParameter(
-            ParameterDef("uses_adjacency_information",
-                         "Whether this geometry program requires adjacency information from the input primitives.", PT_BOOL),
-            &msAdjacencyCmd);
-        dict->addParameter(
             ParameterDef("compute_group_dimensions",
                          "The number of process groups created by this compute program.", PT_VECTOR3),
             &msComputeGroupDimsCmd);
@@ -502,17 +497,6 @@
         t->setManualNamedConstantsFile(val);
     }
     //-----------------------------------------------------------------------
-    String GpuProgram::CmdAdjacency::doGet(const void* target) const
-    {
-        const GpuProgram* t = static_cast<const GpuProgram*>(target);
-        return StringConverter::toString(t->isAdjacencyInfoRequired());
-    }
-    void GpuProgram::CmdAdjacency::doSet(void* target, const String& val)
-    {
-        GpuProgram* t = static_cast<GpuProgram*>(target);
-        t->setAdjacencyInfoRequired(StringConverter::parseBool(val));
-    }
-    //-----------------------------------------------------------------------
     String GpuProgram::CmdComputeGroupDims::doGet(const void* target) const
     {
         const GpuProgram* t = static_cast<const GpuProgram*>(target);
diff -r f57d6657fbd6 -r fcf64f383a6b OgreMain/src/OgreRenderSystem.cpp
--- a/OgreMain/src/OgreRenderSystem.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/OgreMain/src/OgreRenderSystem.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -626,6 +626,12 @@
         case RenderOperation::OT_TRIANGLE_LIST:
             mFaceCount += (val / 3);
             break;
+        case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+            mFaceCount += (val / 6);
+            break;
+        case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+            mFaceCount += (val / 2 - 2);
+            break;
         case RenderOperation::OT_TRIANGLE_STRIP:
         case RenderOperation::OT_TRIANGLE_FAN:
             mFaceCount += (val - 2);
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp
--- a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -2717,7 +2717,6 @@
         else
         {
             //rendering without tessellation.
-            bool useAdjacency = (mGeometryProgramBound && mBoundGeometryProgram && mBoundGeometryProgram->isAdjacencyInfoRequired());
             switch( op.operationType )
             {
             case RenderOperation::OT_POINT_LIST:
@@ -2726,25 +2725,45 @@
                 break;
 
             case RenderOperation::OT_LINE_LIST:
-                primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
+                primType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
                 primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2;
                 break;
 
+            case RenderOperation::OT_LINE_LIST_ADJ:
+                primType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
+                primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 4;
+                break;
+
             case RenderOperation::OT_LINE_STRIP:
-                primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
+                primType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
                 primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1;
                 break;
 
+            case RenderOperation::OT_LINE_STRIP_ADJ:
+                primType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;
+                primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2;
+                break;
+
             case RenderOperation::OT_TRIANGLE_LIST:
-                primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+                primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
                 primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3;
                 break;
 
+            case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+                primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;
+                primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 6;
+                break;
+
             case RenderOperation::OT_TRIANGLE_STRIP:
-                primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+                primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
                 primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2;
                 break;
 
+            case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+                primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;
+                primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2 - 2;
+                break;
+
             case RenderOperation::OT_TRIANGLE_FAN:
                 OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error - DX11 render - no support for triangle fan (OT_TRIANGLE_FAN)", "D3D11RenderSystem::_render");
                 primType = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; // todo - no TRIANGLE_FAN in DX 11
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp
--- a/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -39,7 +39,7 @@
 namespace Ogre {
     namespace GLSL {
 
-    static GLint getGLGeometryInputPrimitiveType(RenderOperation::OperationType operationType, bool requiresAdjacency)
+    static GLint getGLGeometryInputPrimitiveType(RenderOperation::OperationType operationType)
     {
         switch (operationType)
         {
@@ -47,13 +47,19 @@
             return GL_POINTS;
         case RenderOperation::OT_LINE_LIST:
         case RenderOperation::OT_LINE_STRIP:
-            return requiresAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES;
+			return GL_LINES;
+        case RenderOperation::OT_LINE_LIST_ADJ:
+        case RenderOperation::OT_LINE_STRIP_ADJ:
+			return GL_LINES_ADJACENCY_EXT;
+        case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+        case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+            return GL_TRIANGLES_ADJACENCY_EXT;
         default:
         case RenderOperation::OT_TRIANGLE_LIST:
         case RenderOperation::OT_TRIANGLE_STRIP:
         case RenderOperation::OT_TRIANGLE_FAN:
-            return requiresAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES;
-        }
+            return GL_TRIANGLES;
+		}
     }
     //-----------------------------------------------------------------------
     static GLint getGLGeometryOutputPrimitiveType(RenderOperation::OperationType operationType)
@@ -498,7 +504,7 @@
 
             RenderOperation::OperationType inputOperationType = mGeometryProgram->getInputOperationType();
             glProgramParameteriEXT(mGLProgramHandle, GL_GEOMETRY_INPUT_TYPE_EXT,
-                getGLGeometryInputPrimitiveType(inputOperationType, mGeometryProgram->isAdjacencyInfoRequired()));
+                getGLGeometryInputPrimitiveType(inputOperationType));
 
             RenderOperation::OperationType outputOperationType = mGeometryProgram->getOutputOperationType();
 
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp
--- a/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -114,8 +114,6 @@
     void GLSLProgram::createLowLevelImpl(void)
     {
         mAssemblerProgram = GpuProgramPtr(OGRE_NEW GLSLGpuProgram( this ));
-        // Shader params need to be forwarded to low level implementation
-        mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired());
     }
     //-----------------------------------------------------------------------
     void GLSLProgram::unloadHighLevelImpl(void)
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/GL/src/OgreGLRenderSystem.cpp
--- a/RenderSystems/GL/src/OgreGLRenderSystem.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/GL/src/OgreGLRenderSystem.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -2623,25 +2623,35 @@
 
         // Find the correct type to render
         GLint primType;
-        //Use adjacency if there is a geometry program and it requested adjacency info
-        bool useAdjacency = (mGeometryProgramBound && mCurrentGeometryProgram && mCurrentGeometryProgram->isAdjacencyInfoRequired());
         switch (op.operationType)
         {
         case RenderOperation::OT_POINT_LIST:
             primType = GL_POINTS;
             break;
         case RenderOperation::OT_LINE_LIST:
-            primType = useAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES;
+            primType = GL_LINES;
+            break;
+        case RenderOperation::OT_LINE_LIST_ADJ:
+            primType = GL_LINES_ADJACENCY_EXT;
             break;
         case RenderOperation::OT_LINE_STRIP:
-            primType = useAdjacency ? GL_LINE_STRIP_ADJACENCY_EXT : GL_LINE_STRIP;
+            primType = GL_LINE_STRIP;
+            break;
+        case RenderOperation::OT_LINE_STRIP_ADJ:
+            primType = GL_LINE_STRIP_ADJACENCY_EXT;
             break;
         default:
         case RenderOperation::OT_TRIANGLE_LIST:
-            primType = useAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES;
+            primType = GL_TRIANGLES;
+            break;
+        case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+            primType = GL_TRIANGLES_ADJACENCY_EXT;
             break;
         case RenderOperation::OT_TRIANGLE_STRIP:
-            primType = useAdjacency ? GL_TRIANGLE_STRIP_ADJACENCY_EXT : GL_TRIANGLE_STRIP;
+            primType = GL_TRIANGLE_STRIP;
+            break;
+        case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+            primType = GL_TRIANGLE_STRIP_ADJACENCY_EXT;
             break;
         case RenderOperation::OT_TRIANGLE_FAN:
             primType = GL_TRIANGLE_FAN;
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
--- a/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -1479,25 +1479,35 @@
 
         // Determine the correct primitive type to render.
         GLint primType;
-        // Use adjacency if there is a geometry program and it requested adjacency info.
-        bool useAdjacency = (mGeometryProgramBound && mCurrentGeometryShader && mCurrentGeometryShader->isAdjacencyInfoRequired());
         switch (op.operationType)
         {
         case RenderOperation::OT_POINT_LIST:
             primType = GL_POINTS;
             break;
         case RenderOperation::OT_LINE_LIST:
-            primType = useAdjacency ? GL_LINES_ADJACENCY : GL_LINES;
+            primType = GL_LINES;
+            break;
+        case RenderOperation::OT_LINE_LIST_ADJ:
+            primType =  GL_LINES_ADJACENCY;
             break;
         case RenderOperation::OT_LINE_STRIP:
-            primType = useAdjacency ? GL_LINE_STRIP_ADJACENCY : GL_LINE_STRIP;
+            primType = GL_LINE_STRIP;
+            break;
+        case RenderOperation::OT_LINE_STRIP_ADJ:
+            primType = GL_LINE_STRIP_ADJACENCY;
             break;
         default:
         case RenderOperation::OT_TRIANGLE_LIST:
-            primType = useAdjacency ? GL_TRIANGLES_ADJACENCY : GL_TRIANGLES;
+            primType = GL_TRIANGLES;
+            break;
+        case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+            primType = GL_TRIANGLES_ADJACENCY;
             break;
         case RenderOperation::OT_TRIANGLE_STRIP:
-            primType = useAdjacency ? GL_TRIANGLE_STRIP_ADJACENCY : GL_TRIANGLE_STRIP;
+            primType = GL_TRIANGLE_STRIP;
+            break;
+        case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+            primType = GL_TRIANGLE_STRIP_ADJACENCY;
             break;
         case RenderOperation::OT_TRIANGLE_FAN:
             primType = GL_TRIANGLE_FAN;
diff -r f57d6657fbd6 -r fcf64f383a6b RenderSystems/GLSupport/src/GLSL/OgreGLSLShaderCommon.cpp
--- a/RenderSystems/GLSupport/src/GLSL/OgreGLSLShaderCommon.cpp	Sat Jun 09 00:02:47 2018 +0200
+++ b/RenderSystems/GLSupport/src/GLSL/OgreGLSLShaderCommon.cpp	Thu Aug 02 23:56:49 2018 +0200
@@ -229,18 +229,34 @@
         {
             return RenderOperation::OT_LINE_LIST;
         }
+        else if (val == "line_list_adj")
+        {
+            return RenderOperation::OT_LINE_LIST_ADJ;
+        }
         else if (val == "line_strip")
         {
             return RenderOperation::OT_LINE_STRIP;
         }
+        else if (val == "line_strip_adj")
+        {
+            return RenderOperation::OT_LINE_STRIP_ADJ;
+        }
         else if (val == "triangle_strip")
         {
             return RenderOperation::OT_TRIANGLE_STRIP;
         }
+        else if (val == "triangle_strip_ADJ")
+        {
+            return RenderOperation::OT_TRIANGLE_STRIP_ADJ;
+        }
         else if (val == "triangle_fan")
         {
             return RenderOperation::OT_TRIANGLE_FAN;
         }
+        else if (val == "triangle_list_adj")
+        {
+            return RenderOperation::OT_TRIANGLE_LIST_ADJ;
+        }
         else 
         {
             //Triangle list is the default fallback. Keep it this way?
@@ -258,15 +274,27 @@
         case RenderOperation::OT_LINE_LIST:
             return "line_list";
             break;
+        case RenderOperation::OT_LINE_LIST_ADJ:
+            return "line_list_adj";
+            break;
         case RenderOperation::OT_LINE_STRIP:
             return "line_strip";
             break;
+        case RenderOperation::OT_LINE_STRIP_ADJ:
+            return "line_strip_adj";
+            break;
         case RenderOperation::OT_TRIANGLE_STRIP:
             return "triangle_strip";
             break;
+        case RenderOperation::OT_TRIANGLE_STRIP_ADJ:
+            return "triangle_strip_adj";
+            break;
         case RenderOperation::OT_TRIANGLE_FAN:
             return "triangle_fan";
             break;
+        case RenderOperation::OT_TRIANGLE_LIST_ADJ:
+            return "triangle_list_adj";
+            break;
         case RenderOperation::OT_TRIANGLE_LIST:
         default:
             return "triangle_list";
paroj
OGRE Team Member
OGRE Team Member
Posts: 2106
Joined: Sun Mar 30, 2014 2:51 pm
x 1132

Re: mesh with triangle adjacency

Post by paroj »

your patch was actually quite complete already. I just had to add some minor tweaks to finish it. Most notably, we do not straight drop API mid-cycle (1.11 that is), but instead just generate a warning:

https://github.com/OGRECave/ogre/pull/830
User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Re: mesh with triangle adjacency

Post by bishopnator »

Are there any plans to port the change also to 2.x version? It seems like it is forgotten. In 14.2.5 the change is there. I am playing with 2.x version and found that this one is missing there.

User avatar
bishopnator
Goblin
Posts: 299
Joined: Thu Apr 26, 2007 11:43 am
Location: Slovakia / Switzerland
x 11

Re: mesh with triangle adjacency

Post by bishopnator »

I created a pull request for 2.3 branch: https://github.com/OGRECave/ogre-next/pull/448
I based the changes on the https://github.com/OGRECave/ogre/pull/830 - please review it carefully as I didn't verify the changes - I just went file by file from the pull request targeted ogre 1.x and ported the changes which were possible to port so the OGRE is compiling.

I compiled it using MSVC on Windows. Locally I had to update also OgreString.h same as it is changed in vcpkg - replaced the line 255 from "#elif !defined( _STLP_HASH_FUN_H )" to "#elif 0" - is it a known problem on Windows? (that change is not part of the pull request).