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