简体   繁体   English

如何在 opengl 中正常显示顶点

[英]How to display vertices normal in opengl

I'm trying to show the normals of some vertices of the mesh when I select them but accordingly to the position of the cam these normals are displayed or not and the big problem is that they are displayed when they shouldn't (ie when i select vertices of the tibia but i'm looking at the calf so they should be hidden by the leg) and not displayed when they should be displayed.我试图在我 select 时显示网格的某些顶点的法线,但根据凸轮的 position,这些法线是否显示,最大的问题是它们在不应该显示的时候显示(即当我select 胫骨的顶点,但我正在看小腿,所以它们应该被腿隐藏)并且在应该显示时不显示。 I could be wrong but it's like some geometry of the model is drawn above the line.我可能是错的,但这就像 model 的某些几何图形绘制在线条上方。 Moreover, if before calling the draw calls i disable the depth test it works (even if the problem of being showed when they shouldn't isn't resolved obviously).此外,如果在调用绘图调用之前我禁用了深度测试它可以工作(即使在不应该显示的时候显示的问题没有明显解决)。 That's some images to give you an idea of what I mean.这是一些图像,可以让您了解我的意思。

WITH DEPTH TEST OFF:深度测试关闭:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

DEPT TEST ON:部门测试:

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

That's the code:那是代码:

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 just for completeness VERTEX SHADER: 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));
}

GEOMETRY SHADER:几何着色器:

#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();
}

FRAGMENT SHADER:片段着色器:

#version 330 core
out vec4 FragColor;

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

If you need other piece of code tell me and I'll provide it, but I think I posted all the code and images you need.如果您需要其他代码,请告诉我,我会提供,但我想我发布了您需要的所有代码和图像。

Ok I don't know how I didn't noticed it, but yes, the problem was that I wasn't applying the projection matrix to the normal vector.好的,我不知道我怎么没注意到它,但是是的,问题是我没有将投影矩阵应用于法线向量。 Thanks Spektre to point this out.感谢 Spektre 指出这一点。

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

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