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_Glfw_Opengl 3_Opengl 4 - Fatal编程技术网

C++ OpenGL中的多边形撕裂

C++ OpenGL中的多边形撕裂,c++,opengl,glfw,opengl-3,opengl-4,C++,Opengl,Glfw,Opengl 3,Opengl 4,500x500网格,带有1000个子分区: 只有一个问题 为什么会这样 #include <iostream> #include <sstream> #include <vector> #define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h> #include "glm/glm.hpp" #include "glm/gtc/matrix_transform.hpp"

500x500网格,带有1000个子分区:

只有一个问题

为什么会这样

#include <iostream>
#include <sstream>
#include <vector>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "GameEngine.hpp"
#include "ShaderProgram.h"
#include "Camera.h"
#include "Mesh.h"

const char *title = "Terrain";

GameEngine engine;
OrbitCamera orbitCamera;
float gYaw = 0.0f;
float gPitch = 1.0f;
float gRadius = 200.0f;
const float MOUSE_SENSTIVITY = 0.25f;

bool gWireFrame = false;
void glfw_onKey(GLFWwindow *window, int key, int scancode, int action, int mode);
void glfw_onMouseMove(GLFWwindow *window, double posX, double posY);
void glfw_onMouseScroll(GLFWwindow *window, double deltaX, double deltaY);

int main()
{
    if (!engine.init(1024, 768, title))
    {
        std::cerr << "OpenGL init failed" << std::endl;
        std::cin.get();
        return -1;
    }

    //set callbacks
    glfwSetKeyCallback(engine.getWindow(), glfw_onKey);
    glfwSetCursorPosCallback(engine.getWindow(), glfw_onMouseMove);

    std::vector<Vertex> VER;

    std::vector<glm::vec3> verts;
    std::vector<unsigned int> indices;
    std::vector<glm::vec3> norms;

    int subDiv = 1000;
    int width = 500;
    int height = 500;
    int size = 0;

    for (int row = 0; row < subDiv; row++)
    {
        for (int col = 0; col < subDiv; col++)
        {
            float x = (float)((col * width) / subDiv - (width / 2.0));
            float z = ((subDiv - row) * height) / subDiv - (height / 2.0);
            glm::vec3 pos = glm::vec3(x, 0, z);
            verts.push_back(pos);
        }
    }

    size = subDiv * subDiv;

    size = verts.size();

    for (int row = 0; row < subDiv -1 ; row++)
    {
        for (int col = 0; col < subDiv -1; col++)
        {
             int row1 = row * (subDiv);
            int row2 = (row+1) * (subDiv);

            indices.push_back(row1+col);
            indices.push_back(row1+col+1);
            indices.push_back( row2+col+1);

            indices.push_back(row1+col);
            indices.push_back( row2+col+1);
            indices.push_back(row2+col);
        }
    }


    for (int i = 0; i < verts.size(); i++)
    {
        Vertex vertex;
        vertex.position = verts[i];

        vertex.normal = glm::vec3(0, 0, 0);
        vertex.texCoords = glm::vec2(0, 0);

        VER.push_back(vertex);
    }

    VER.begin();

    for (int i = 0; i < indices.size(); i += 3)
    {
        Vertex a = VER[indices[i]];
        Vertex b = VER[indices[i + 1]];
        Vertex c = VER[indices[i + 2]];

        glm::vec3 p = glm::cross(b.position - a.position, c.position - a.position);

        VER[indices[i]].normal += p;
        VER[indices[i + 1]].normal += p;
        VER[indices[i + 2]].normal += p;
    }

    for (int i = 0; i < VER.size(); i++)
    {
        VER[i].normal = glm::normalize(VER[i].normal);
    }



    glm::vec3 cubePos = glm::vec3(0.0f, 0.0f, -5.0f);

    GLuint vbo, vao, ibo;

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);

    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, VER.size() * sizeof(Vertex), &VER[0], GL_STATIC_DRAW);


// Vertex Positions
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    // Normals attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    // Vertex Texture Coords
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(6 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);

    int n = indices.size() * sizeof(unsigned int);


    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);


    glBindVertexArray(0);

    ShaderProgram shaderProgram;
    shaderProgram.loadShaders("shaders/vert.glsl", "shaders/frag.glsl");
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    while (!glfwWindowShouldClose(engine.getWindow()))
    {

        glfwPollEvents();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glm::mat4 model, view, projection;

        model = glm::mat4(1.0f);

        orbitCamera.setLookAt(glm::vec3(0, 0, 0));
        orbitCamera.rotate(gYaw, gPitch);
        orbitCamera.setRadius(gRadius);

        model = glm::translate(model, glm::vec3(0, 0, 0));
        //model = glm::scale(model, glm::vec3(1, 0, 1));

        //model = scaleMat;

        projection = glm::perspective(glm::radians(45.0f), (float)engine.getWidth() / (float)engine.getHeight(), 0.00001f, 100.0f);

        shaderProgram.use();
        glm::vec3 viewPos;
        viewPos.x = orbitCamera.getPosition().x;
        viewPos.y = orbitCamera.getPosition().y;
        viewPos.z = orbitCamera.getPosition().z;

        shaderProgram.setUniform("projection", projection);
        shaderProgram.setUniform("view", orbitCamera.getViewMatrix());
        shaderProgram.setUniform("model", model);
        shaderProgram.setUniform("lightPos", glm::vec3(5, 10, 10));
        shaderProgram.setUniform("viewPos", viewPos);

        glBindVertexArray(vao);
        glDrawElements(GL_TRIANGLES,indices.size(), GL_UNSIGNED_INT, 0);
        //glDrawArrays(GL_TRIANGLES, 0, VER.size());
        glBindVertexArray(0);

        glfwSwapBuffers(engine.getWindow());
    }

    //cleanup
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);

    glfwTerminate();
    return 0;
}

void glfw_onKey(GLFWwindow *window, int key, int scancode, int action, int mode)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    {
        glfwSetWindowShouldClose(window, GL_TRUE);
    }

    if (key == GLFW_KEY_E && action == GLFW_PRESS)
    {
        gWireFrame = !gWireFrame;
        if (gWireFrame)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        else
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
}

void glfw_onMouseMove(GLFWwindow *window, double posX, double posY)
{
    static glm::vec2 lastMousePos = glm::vec2(0, 0);
    if (glfwGetMouseButton(engine.getWindow(), GLFW_MOUSE_BUTTON_LEFT) == 1)
    {
        gYaw -= ((float)posX - lastMousePos.x) * MOUSE_SENSTIVITY;
        gPitch += ((float)posY - lastMousePos.y) * MOUSE_SENSTIVITY;
    }
    if (glfwGetMouseButton(engine.getWindow(), GLFW_MOUSE_BUTTON_RIGHT) == 1)
    {
        float dx = 0.01f * ((float)posX - lastMousePos.x);
        float dy = 0.01f * ((float)posY - lastMousePos.y);
        gRadius += dx - dy;
    }
    lastMousePos.x = (float)posX;
    lastMousePos.y = (float)posY;
}

这是主代码。Rest只是基本的初始化代码,没有什么特别之处。 我已经试着换了swapinterval,但这似乎不是问题。 如果有人想看的话,我可以分享其他类的代码。我也试着降低分区

编辑*

将“远平面”的值增加到8000后:


仍然不清晰。

第二张图像的编辑正在告诉您发生了什么。。。如果篡改znear/zfar会像这样更改输出,则意味着您的深度缓冲区的位宽度较低,无法达到您想要使用的范围

然而,增加zfar会让事情变得更糟,只是因为某些原因,你看不到它,可能是它被切断了,或者是一些奇怪的数学精度奇点

对我来说,通常选择平面,以便:

zfar/znear < (2^depth_buffer_bitwidth)/2
检查深度\缓冲区\位宽度

尝试使用24位,您现在可能有16位。这对现在所有的gfx卡都有效。您也可以尝试32位,但这只适用于较新的卡。我正在使用此代码来获得我能达到的最大值:

然而,你正在使用GLFW,所以你需要找到如何在它做。。。也许这里面有一些暗示

尽可能地增加znear

篡改znear比zfar有更大的影响

使用线性深度缓冲区

这是在整个深度视图范围内覆盖stuf的地形等大深度范围视图的最佳选择。见:

但是,您需要着色器和新的api来实现此。。。我不认为这在旧api中是可行的,但幸运的是,您已经在使用新api了

如果以上都不够的话

可以将更多的平截头体堆叠在一起,但代价是对同一几何体进行多次渲染。有关更多信息,请参阅:


如何初始化OpenGL

您使用的是GL_BLEND吗? 使用混合可以很好地获得抗锯齿多边形边,但是这也意味着您的z缓冲区即使在绘制非常半透明的片段时也会得到更新。这可以防止绘制具有相同z深度的其他不透明碎片,这可能是导致这些孔的原因。您可以尝试禁用GL_BLEND以查看问题是否消失

你用的是什么深度函数?
默认情况下,它设置为无总账。您可能想试试gldepthfungl_LEQUAL;因此,将绘制具有相同z深度的片段。但是,由于舍入错误,这可能无法完全解决您的问题。

@t.niese是否需要更多代码?