繁体   English   中英

如何在 opengl 中正常显示顶点

[英]How to display vertices normal in opengl

我试图在我 select 时显示网格的某些顶点的法线,但根据凸轮的 position,这些法线是否显示,最大的问题是它们在不应该显示的时候显示(即当我select 胫骨的顶点,但我正在看小腿,所以它们应该被腿隐藏)并且在应该显示时不显示。 我可能是错的,但这就像 model 的某些几何图形绘制在线条上方。 此外,如果在调用绘图调用之前我禁用了深度测试它可以工作(即使在不应该显示的时候显示的问题没有明显解决)。 这是一些图像,可以让您了解我的意思。

深度测试关闭:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

部门测试:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

那是代码:

void StatusManager::Render() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!animatedModel)
    return;
Update();

// draw wireframe if enabled
if (wireframeEnabled)
    DrawWireframe();
if (visualMode == Mode_Texture) {
    // draw model
    if (lightingMode == Mode_Flat)
        DrawModel(modelFlatShader);
    else if (lightingMode == Mode_Smooth)
        DrawModel(modelSmoothShader);
    else
        DrawModel(modelNoLightShader);
}
else if (visualMode == Mode_CurrentBoneIDInfluence) {
    DrawModel(currentBoneShader);
}
else if (visualMode == Mode_NumBones)
{
    DrawModel(numBonesShader);
}
else
{
    DrawModel(modelGreyShader);
}

// render selected vertices
DrawSelectedVertices();

if (!info.hitPoint)
    return;

//DrawHotPoint();
if (selectionMode == Mode_Vertex)
    DrawHoveredPoint();
if (selectionMode == Mode_Edge)
    DrawHoveredLine();
if (selectionMode == Mode_Face)
    DrawHoveredFace();
}

void StatusManager::DrawWireframe() {
    wireframeShader.use();
    glLineWidth(1.0f);
    // model/view/projection transformations
    glm::mat4 modelView = camera.viewMatrix;
    wireframeShader.setMat4("modelView", modelView);
    wireframeShader.setMat4("projection", projection);

    // pass bones matrices to the shader
    auto transforms = animator.GetFinalBoneMatrices();
    for (int i = 0; i < transforms.size(); ++i)
        wireframeShader.setMat4("finalBonesMatrices[" + std::to_string(i) + "]", transforms[i]);

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    animatedModel.value().Draw(wireframeShader);
}

void StatusManager::DrawModel(Shader& modelShader) {
    modelShader.use();
    // model/view/projection transformations
    modelShader.setMat4("modelView", camera.viewMatrix);
    modelShader.setMat4("projection", projection);
    if (visualMode == Mode_Texture)
        modelShader.setVec3("light_pos", lightPos);
    else if (visualMode == Mode_CurrentBoneIDInfluence)
        modelShader.setInt("currentBoneID", currentBoneID);

    // pass bones matrices to the shader
    auto transforms = animator.GetFinalBoneMatrices();
    for (int i = 0; i < transforms.size(); ++i)
        modelShader.setMat4("finalBonesMatrices[" + std::to_string(i) + "]", transforms[i]);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(1.0, 1.0);
    /*if (pause)
        bakedModel.value().Draw(modelShader);
    else*/
    animatedModel.value().Draw(modelShader);
}

void StatusManager::DrawHoveredFace() {
    assert(bakedModel.has_value());
    assert(info.hitPoint.has_value());
    Mesh& m = bakedModel.value().meshes[info.meshIndex];
    Face& f = info.face.value();

    //vertex
    float hoveredVertices[9] = {
        m.vertices[f.indices[0]].Position.x, m.vertices[f.indices[0]].Position.y, m.vertices[f.indices[0]].Position.z,
        m.vertices[f.indices[1]].Position.x, m.vertices[f.indices[1]].Position.y, m.vertices[f.indices[1]].Position.z,
        m.vertices[f.indices[2]].Position.x, m.vertices[f.indices[2]].Position.y, m.vertices[f.indices[2]].Position.z,
    };
    hoverShader.use();
    glBindVertexArray(HVAO);
    glBindBuffer(GL_ARRAY_BUFFER, HVBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(hoveredVertices), &hoveredVertices);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0.0, 0.0);

    // model/view/projection transformations
    glm::mat4 modelView = camera.viewMatrix;
    hoverShader.setMat4("modelView", modelView);
    hoverShader.setMat4("projection", projection);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    //unbind
    glBindVertexArray(0);
}

void StatusManager::DrawHoveredPoint() {
    assert(bakedModel.has_value());
    assert(info.hitPoint.has_value());
    Mesh& m = bakedModel.value().meshes[info.meshIndex];
    Face& f = info.face.value();
    int index = getClosestVertexIndex(info.hitPoint.value(), m, f);

    //vertex
    float hoveredVertices[3] = { m.vertices[index].Position.x, m.vertices[index].Position.y, m.vertices[index].Position.z };

    hoverShader.use();
    glBindVertexArray(HVAO);
    glBindBuffer(GL_ARRAY_BUFFER, HVBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(float), &hoveredVertices);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0.0, 0.0);

    // model/view/projection transformations
    glm::mat4 modelView = camera.viewMatrix;
    hoverShader.setMat4("modelView", modelView);
    hoverShader.setMat4("projection", projection);

    glPointSize(8.0f);
    glDrawArrays(GL_POINTS, 0, 1);

    //unbind
    glBindVertexArray(0);
}

void StatusManager::DrawHotPoint()
{
    float hotVertices[3] = { hotPoint.x, hotPoint.y, hotPoint.z };

    hoverShader.use();
    glBindVertexArray(HVAO);
    glBindBuffer(GL_ARRAY_BUFFER, HVBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(float), &hotVertices);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0.0, 0.0);

    // model/view/projection transformations
    glm::mat4 modelView = camera.viewMatrix;
    hoverShader.setMat4("modelView", modelView);
    hoverShader.setMat4("projection", projection);

    glPointSize(8.0f);
    glDrawArrays(GL_POINTS, 0, 1);

    //unbind
    glBindVertexArray(0);
}

void StatusManager::UpdateSelectedVertices()
{
    selectedVertices.clear();
    for (Vertex* v : selectedVerticesPointers)
        selectedVertices.push_back(*v);
}



void StatusManager::DrawHoveredLine() {
    assert(bakedModel.has_value());
    assert(info.hitPoint.has_value());
    Mesh& m = bakedModel.value().meshes[info.meshIndex];
    Face& f = info.face.value();
    auto line = getClosestLineIndex(info.hitPoint.value(), m, f);

    //vertex
    float hoveredVertices[6] = {
        m.vertices[line.v1].Position.x, m.vertices[line.v1].Position.y, m.vertices[line.v1].Position.z,
        m.vertices[line.v2].Position.x, m.vertices[line.v2].Position.y, m.vertices[line.v2].Position.z
    };

    hoverShader.use();
    glBindVertexArray(HVAO);
    glBindBuffer(GL_ARRAY_BUFFER, HVBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(hoveredVertices), &hoveredVertices);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(0.0, 0.0);

    // model/view/projection transformations
    glm::mat4 modelView = camera.viewMatrix;
    hoverShader.setMat4("modelView", modelView);
    hoverShader.setMat4("projection", projection);

    glLineWidth(3.0f);
    glDrawArrays(GL_LINES, 0, 2);
    glLineWidth(1.0f);

    //unbind
    glBindVertexArray(0);
}

normalShader 只是为了完整性 VERTEX SHADER:

#version 330 core

layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 norm;
layout(location = 2) in ivec4 boneIds; 
layout(location = 3) in vec4 weights;
layout(location = 4) in int numBones;
    
uniform mat4 projection;
uniform mat4 modelView;
uniform mat4 finalBonesMatrices[100];

out VS_OUT {
    vec4 normal;
} vs_out;
    
void main()
{
    mat4 cumulativeMatrix = mat4(1.0);
    if (numBones>0)
        cumulativeMatrix = mat4(0.0);
    for(int i = 0 ; i < numBones ; i++)
    {
        cumulativeMatrix += (finalBonesMatrices[boneIds[i]] * weights[i]);
    }
    gl_Position =  projection * modelView * cumulativeMatrix * vec4(pos, 1.0);
    vs_out.normal = normalize(modelView * cumulativeMatrix * vec4(norm, 0.0));
}

几何着色器:

#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;

uniform float normal_length;

in VS_OUT {
    vec4 normal;
} gs_in[];

void main() {    
    gl_Position = gl_in[0].gl_Position; 
    EmitVertex();
    gl_Position = gl_in[0].gl_Position + gs_in[0].normal * normal_length;
    EmitVertex();
    EndPrimitive();
}

片段着色器:

#version 330 core
out vec4 FragColor;

void main()
{    
    FragColor = vec4(1, 0, 0, 1);
}

如果您需要其他代码,请告诉我,我会提供,但我想我发布了您需要的所有代码和图像。

好的,我不知道我怎么没注意到它,但是是的,问题是我没有将投影矩阵应用于法线向量。 感谢 Spektre 指出这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM