Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ opengl-三角形带的三角形邻接_C++_Opengl_Glsl_Shader - Fatal编程技术网

C++ opengl-三角形带的三角形邻接

C++ opengl-三角形带的三角形邻接,c++,opengl,glsl,shader,C++,Opengl,Glsl,Shader,假设我有我的几何图形,并创建了一个包含三角形邻接信息的索引缓冲区。然后,将绘制模式从GL_三角形更改为GL_三角形。 问题是,我可以使用几何体着色器将几何体从三角形邻接转换为三角形带吗 大概是这样的: layout(triangles_adjacency) in; layout(triangle_strip, max_vertices = 3) out; in Vertex { vec3 normal; } vertex[]; out FragmentVertexData { v

假设我有我的几何图形,并创建了一个包含三角形邻接信息的索引缓冲区。然后,将绘制模式从
GL_三角形
更改为
GL_三角形
。 问题是,我可以使用几何体着色器将几何体从三角形邻接转换为三角形带吗

大概是这样的:

layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 3) out;

in Vertex
{
    vec3 normal;
} vertex[];

out FragmentVertexData
{
  vec3 normal;
  vec3 fragpos;
} VertexOut;


void main()
{
    for(int i = 0 ; i < gl_in.length(); i+=2)
    {
        gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * gl_in[i].gl_Position;
        VertexOut.normal = vertex[i].normal;
        VertexOut.fragpos =  vec3(ModelMatrix * gl_in[i].gl_Position);
        VertexOut.fragpos = gl_Position; 
        EmitVertex();
    }
    EndPrimitive();
}
layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 3) out;

in Vertex
{
    vec3 normal;
} vertex[];

out FragmentVertexData
{
    vec3 normal;
    vec3 fragpos;
} VertexOut;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main()
{
    for (int i = 0; i < 6; i += 2)
    {
        vec4 fragPos      = ModelMatrix * gl_in[i].gl_Position;
        VertexOut.normal  = mat3(ModelMatrix) * vertex[i].normal;
        VertexOut.fragpos = fragPos.xyz;
        gl_Position       = ProjectionMatrix * ViewMatrix * fragPos;
        EmitVertex();
    } 
    EndPrimitive();
}
#include <array>
#include <vector>
#include <map>

using TIndices  = std::vector<int>;
using TFace     = std::array<int, 3>;
using TFaces    = std::vector<TFace>;
using TVertex   = std::array<float, 3>;
using TVertices = std::vector<TVertex>;

void GenerateAdjacencies( const TVertices &vertices, const TFaces &faces, TIndices &adj )
{
    // associate each geometric vertex position with an unique ID
    std::vector<int>      uniqueMap;
    std::map<TVertex,int> tempUniqueVertices;
    int uniqueIndex = 0;
    for ( size_t vI = 0; vI < vertices.size(); ++ vI )
    {
        auto vIt = tempUniqueVertices.find( vertices[vI] );
        if ( vIt == tempUniqueVertices.end() )
        {
            tempUniqueVertices[ vertices[vI] ] = uniqueIndex;
            uniqueMap.push_back( uniqueIndex );
            uniqueIndex ++;
        }
        else
            uniqueMap.push_back( vIt->second );
    }
    tempUniqueVertices.clear();

    // find all edges and associate the edge with all the points, which form a triangle with it. 
    std::map< std::tuple<int, int>, std::vector<int> > edges;
    for ( auto & f : faces )
    {
      for ( int pI = 0; pI < 3; ++ pI )
      {
        int edgeU[2]{ uniqueMap[f[pI]], uniqueMap[f[(pI+1) % 3]] };
        int i0 = edgeU[0] < edgeU[1] ? 0 : 1;
        edges[{ edgeU[i0], edgeU[1-i0] }].push_back( f[(pI+2) % 3] );
      }
    }

    // create the adjacencies
    for ( auto & f : faces )
    {
        for ( int pI = 0; pI < 3; ++ pI )
        {
            int edgeU[2]{ uniqueMap[f[pI]], uniqueMap[f[(pI+1) % 3]] };
            int   i0   = edgeU[0] < edgeU[1] ? 0 : 1;
            auto &adjs = edges[{ edgeU[i0], edgeU[1 - i0] }];
            int   adjI = adjs.size() > 1 && adjs[0] == f[(pI+2) % 3] ? 1 : 0;
            adj.push_back( f[pI] );
            adj.push_back( adjs[adjI] );
        }
    }
}
这是我编写三角形邻接索引缓冲区的算法:

void Loader::FindAdjacencies(const aiMesh * paiMesh, vector<int>& indices)
{
    // Step 1 - find the two triangles that share every edge
    for (uint i = 0; i < paiMesh->mNumFaces; i++) 
    {
        const aiFace& face = paiMesh->mFaces[i];

        Face Unique;

        // If a position vector is duplicated in the VB we fetch the 
        // index of the first occurrence.
        for (uint j = 0; j < 3; j++)
        {
            uint Index = face.mIndices[j];
            aiVector3D& v = paiMesh->mVertices[Index];

            if (m_posMap.find(v) == m_posMap.end()) 
            {
                m_posMap[v] = Index;
            }
            else 
            {
                Index = m_posMap[v];
            }

            Unique.Indices[j] = Index;
        }

        m_uniqueFaces.push_back(Unique);

        Edge e1(Unique.Indices[0], Unique.Indices[1]);
        Edge e2(Unique.Indices[1], Unique.Indices[2]);
        Edge e3(Unique.Indices[2], Unique.Indices[0]);

        m_indexMap[e1].AddNeigbor(i);
        m_indexMap[e2].AddNeigbor(i);
        m_indexMap[e3].AddNeigbor(i);

    }

    // Step 2 - build the index buffer with the adjacency info
    for (uint i = 0; i < paiMesh->mNumFaces; i++) 
    {
        const Face& face = m_uniqueFaces[i];

        for (uint j = 0; j < 3; j++) 
        {
            Edge e(face.Indices[j], face.Indices[(j + 1) % 3]);
            assert(m_indexMap.find(e) != m_indexMap.end());
            Neighbors n = m_indexMap[e];
            uint OtherTri = n.GetOther(i);
            uint minus1 = (uint)-1;
            bool comp = (OtherTri != minus1);
            assert(comp);

            const Face& OtherFace = m_uniqueFaces[OtherTri];
            uint OppositeIndex = OtherFace.GetOppositeIndex(e);

            indices.push_back(face.Indices[j]);
            indices.push_back(OppositeIndex);
        }
    }

}
多谢各位

这是我的顶点着色器:

#version 430 core
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normal;

out VertexData
{
    vec3 normal;
    vec2 textCoord;
} vertex;

// Values that stay constant for the whole mesh.

void main(){
  gl_Position =  vec4(vertexPosition,1.0f);
  vertex.textCoord = texCoord;
  vertex.normal = normal;
}
和我的片段着色器:

#version 430 core

struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 

struct Light {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform Material material;
uniform Light light;

out vec4 color;

uniform float LightIntensity;
uniform vec3 LightPos;
uniform vec3 ViewPos;

in FragmentVertexData
{
    vec3 normal;
    vec3 fragpos;
    vec2 texCoord;
} VertexOut;


void main(){


  // color of the object
  vec3 objectColor = vec3(1.0f, 0.5f, 0.31f);


  // Ambient

  vec3 ambient = light.ambient * material.ambient ;

  vec3 normal = normalize(VertexOut.normal);
  vec3 lightDir = normalize(light.position - VertexOut.fragpos);  

  float diff = max(dot(lightDir,normal), 0.0);
  vec3 diffuse = light.diffuse * diff * material.diffuse ;

  vec3 viewDir = normalize(ViewPos - VertexOut.fragpos);
  vec3 reflectDir = reflect(-lightDir, normal);  

  vec3 halfwayDir = normalize(lightDir + viewDir );

  float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);


  vec3 specular = light.specular * spec * material.specular ; 

  color = vec4((ambient + diffuse + specular) * objectColor, 1);

}

三角形邻接,包含三角形的邻接数据,以便可以访问相邻三角形。舞台可以访问6个顶点和属性,它们形成4个三角形。3个顶点构成当前渲染的三角形。其他3个顶点与当前渲染三角形的3条边一起形成相邻(相邻)三角形。(见和)

如果a应将渲染的三角形传递到下一个着色器阶段,则它必须仅处理形成三角形的三个点,而不是其邻接点

其他问题:

  • 模型的世界空间位置由
    VertexOut.fragpos=gl\u位置覆盖
  • 法向量必须转换到世界空间:
    VertexOut.normal=mat3(ModelMatrix)*顶点[i]。normal
几何体着色器的外观应如下所示:

layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 3) out;

in Vertex
{
    vec3 normal;
} vertex[];

out FragmentVertexData
{
  vec3 normal;
  vec3 fragpos;
} VertexOut;


void main()
{
    for(int i = 0 ; i < gl_in.length(); i+=2)
    {
        gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * gl_in[i].gl_Position;
        VertexOut.normal = vertex[i].normal;
        VertexOut.fragpos =  vec3(ModelMatrix * gl_in[i].gl_Position);
        VertexOut.fragpos = gl_Position; 
        EmitVertex();
    }
    EndPrimitive();
}
layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 3) out;

in Vertex
{
    vec3 normal;
} vertex[];

out FragmentVertexData
{
    vec3 normal;
    vec3 fragpos;
} VertexOut;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main()
{
    for (int i = 0; i < 6; i += 2)
    {
        vec4 fragPos      = ModelMatrix * gl_in[i].gl_Position;
        VertexOut.normal  = mat3(ModelMatrix) * vertex[i].normal;
        VertexOut.fragpos = fragPos.xyz;
        gl_Position       = ProjectionMatrix * ViewMatrix * fragPos;
        EmitVertex();
    } 
    EndPrimitive();
}
#include <array>
#include <vector>
#include <map>

using TIndices  = std::vector<int>;
using TFace     = std::array<int, 3>;
using TFaces    = std::vector<TFace>;
using TVertex   = std::array<float, 3>;
using TVertices = std::vector<TVertex>;

void GenerateAdjacencies( const TVertices &vertices, const TFaces &faces, TIndices &adj )
{
    // associate each geometric vertex position with an unique ID
    std::vector<int>      uniqueMap;
    std::map<TVertex,int> tempUniqueVertices;
    int uniqueIndex = 0;
    for ( size_t vI = 0; vI < vertices.size(); ++ vI )
    {
        auto vIt = tempUniqueVertices.find( vertices[vI] );
        if ( vIt == tempUniqueVertices.end() )
        {
            tempUniqueVertices[ vertices[vI] ] = uniqueIndex;
            uniqueMap.push_back( uniqueIndex );
            uniqueIndex ++;
        }
        else
            uniqueMap.push_back( vIt->second );
    }
    tempUniqueVertices.clear();

    // find all edges and associate the edge with all the points, which form a triangle with it. 
    std::map< std::tuple<int, int>, std::vector<int> > edges;
    for ( auto & f : faces )
    {
      for ( int pI = 0; pI < 3; ++ pI )
      {
        int edgeU[2]{ uniqueMap[f[pI]], uniqueMap[f[(pI+1) % 3]] };
        int i0 = edgeU[0] < edgeU[1] ? 0 : 1;
        edges[{ edgeU[i0], edgeU[1-i0] }].push_back( f[(pI+2) % 3] );
      }
    }

    // create the adjacencies
    for ( auto & f : faces )
    {
        for ( int pI = 0; pI < 3; ++ pI )
        {
            int edgeU[2]{ uniqueMap[f[pI]], uniqueMap[f[(pI+1) % 3]] };
            int   i0   = edgeU[0] < edgeU[1] ? 0 : 1;
            auto &adjs = edges[{ edgeU[i0], edgeU[1 - i0] }];
            int   adjI = adjs.size() > 1 && adjs[0] == f[(pI+2) % 3] ? 1 : 0;
            adj.push_back( f[pI] );
            adj.push_back( adjs[adjI] );
        }
    }
}

请参见

Hi,是的,这就是我在循环中为(int I=0;I