Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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++_Xcode_Opengl_Glfw_Glew - Fatal编程技术网

C++ OpenGL缺陷-不需要的插值

C++ OpenGL缺陷-不需要的插值,c++,xcode,opengl,glfw,glew,C++,Xcode,Opengl,Glfw,Glew,我正在尝试使用贝齐尔曲面渲染犹他州的茶壶,并在这方面取得了一定的成功。然而,我有一些完全不受欢迎的缺陷。正如你所看到的,茶壶看起来还可以,但存在一些不必要的“插值”。你认为这可能是什么原因造成的?顺便说一下,当我将对象写入.ply文件时,我可以使用meshlab打开它,没有问题,也没有缺陷。最后,我使用Xcode作为我的开发环境 我真的很感激你能提供的任何帮助 编辑:添加了部分代码。首先,从旧纸张中检索控制点和使用的补丁 struct position3D { GLfloat x, y, z;

我正在尝试使用贝齐尔曲面渲染犹他州的茶壶,并在这方面取得了一定的成功。然而,我有一些完全不受欢迎的缺陷。正如你所看到的,茶壶看起来还可以,但存在一些不必要的“插值”。你认为这可能是什么原因造成的?顺便说一下,当我将对象写入.ply文件时,我可以使用meshlab打开它,没有问题,也没有缺陷。最后,我使用Xcode作为我的开发环境

我真的很感激你能提供的任何帮助

编辑:添加了部分代码。首先,从旧纸张中检索控制点和使用的补丁

struct position3D { GLfloat x, y, z; };
struct position3D teapot_cp_vertices[] = {
    // 1
    { 1.4   ,   0.0   ,  2.4 },
    { 1.4   ,  -0.784 ,  2.4 },
    { 0.784 ,  -1.4   ,  2.4 },
    { 0.0   ,  -1.4   ,  2.4 },
                 .
                 .
                 .
}

#define TEAPOT_NB_PATCHES 32
#define ORDER 3
unsigned short teapot_patches[][ORDER + 1][ORDER + 1] =
{
    // rim
    { { 1,   2,   3,   4 },{ 5,   6,   7,   8 },{ 9,  10,  11,  12 },{ 13,  14,  15,  16, } },
    { { 4,  17,  18,  19 },{ 8,  20,  21,  22 },{ 12,  23,  24,  25 },{ 16,  26,  27,  28, } },
    { { 19,  29,  30,  31 },{ 22,  32,  33,  34 },{ 25,  35,  36,  37 },{ 28,  38,  39,  40, } },
    { { 31,  41,  42,   1 },{ 34,  43,  44,   5 },{ 37,  45,  46,   9 },{ 40,  47,  48,  13, } },
       ...
       ...
       ...
   } }
}
所有的点和补丁都可以在本文中找到

用于渲染茶壶的顶点和三角形使用以下公式计算:

int factorial(int n)
{
    assert(n >= 0);
    return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
float binomial_coefficient(int i, int n) {
    assert(i >= 0); assert(n >= 0);
    return 1.0f * factorial(n) / (factorial(i) * factorial(n-i));
}
float bernstein_polynomial(int i, int n, float u) {
    return binomial_coefficient(i, n) * powf(u, i) * powf(1-u, n-i);
}
void build_control_points_k(int p, struct position3D control_points_k[][ORDER+1]) {
    for (int i = 0; i <= ORDER; i++) {
        for (int j = 0; j <= ORDER; j++) {
            control_points_k[i][j] = teapot_cp_vertices[teapot_patches[p][i][j] - 1];

        }
    }
}

Vertex compute_position(struct position3D control_points_k[][ORDER+1], float u, float v) {
    Vertex result = *new Vertex();
    for (int i = 0; i <= ORDER; i++) {
        float poly_i = bernstein_polynomial(i, ORDER, u);
        for (int j = 0; j <= ORDER; j++) {
            float poly_j = bernstein_polynomial(j, ORDER, v);
            result.x += poly_i * poly_j * control_points_k[i][j].x;
            result.y += poly_i * poly_j * control_points_k[i][j].y;
            result.z += poly_i * poly_j * control_points_k[i][j].z;
            result.r = 0; //default colour 
            result.g = 0;
            result.b = 0;
        }
    }
    return result;
}
#define RESU 10 //resolution in u axis
#define RESV 10 //resolution in v axis

void Object3D::build_teapot() {
    vlist = new Vertex[TEAPOT_NB_PATCHES * RESU*RESV]; //vertex list
    tlist = new Triangle[TEAPOT_NB_PATCHES * (RESU-1)*(RESV-1) * 2]; //triangle list

    //calculate vertices
    for (int p = 0; p < TEAPOT_NB_PATCHES; p++) {
        struct position3D control_points_k[ORDER+1][ORDER+1];
        build_control_points_k(p, control_points_k);
        for (int ru = 0; ru <= RESU-1; ru++) {
            float u = 1.0 * ru / (RESU-1);
            for (int rv = 0; rv <= RESV-1; rv++) {
                float v = 1.0 * rv / (RESV-1);
                vlist[p*RESU*RESV + ru*RESV + rv] = compute_position(control_points_k, u, v);
                vlist[p*RESU*RESV + ru*RESV + rv].r = 1.0 * p / TEAPOT_NB_PATCHES;
                vlist[p*RESU*RESV + ru*RESV + rv].g = 1.0 * p / TEAPOT_NB_PATCHES;
                vlist[p*RESU*RESV + ru*RESV + rv].b = 0.7;
            }
        }
    }
//calculate triangle vertex orders or namely triangles
int n = 0;
Triangle tmpTrg = *new Triangle();
tmpTrg.nverts = 3;
for (int p = 0; p < TEAPOT_NB_PATCHES; p++) {
    for (int ru = 0; ru < RESU-1; ru++)
        for (int rv = 0; rv < RESV-1; rv++) {
            // ABCD is a square
            // triangle in the order ABC is the first one
            tmpTrg.verts = new int[tmpTrg.nverts];
            tmpTrg.verts[0] = p*RESU*RESV +  ru   *RESV +  rv   ;
            tmpTrg.verts[1] = p*RESU*RESV +  ru   *RESV + (rv+1);
            tmpTrg.verts[2] = p*RESU*RESV + (ru+1)*RESV + (rv+1);
            tlist[n] = tmpTrg;
            n++;
            // triangle in the order CDA is the second one
            tmpTrg.verts = new int[tmpTrg.nverts];
            tmpTrg.verts[0] = p*RESU*RESV + (ru+1)*RESV + (rv+1);
            tmpTrg.verts[1] = p*RESU*RESV + (ru+1)*RESV +  rv   ;
            tmpTrg.verts[2] = p*RESU*RESV +  ru   *RESV +  rv   ;

            tlist[n] = tmpTrg;
            n++;
        }
    }
}
编辑2:我尝试使用Visual Studio 15 as在Windows计算机上运行代码,但没有类似的缺陷。有人知道是什么导致了这样一个愚蠢的问题吗

编辑3:以下是对象创建代码:

void Object3D::CreateObject()
{

    int attributeCount = 6;
    vertexCount        = TEAPOT_NB_PATCHES * RESU*RESV;
    triangleCount      = TEAPOT_NB_PATCHES * (RESU-1)*(RESV-1) * 2;
    build_teapot();

    //Bind the vertex and index buffers
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    // Bind our Vertex Array Object first, then bind and set our buffers and pointers.
    glBindVertexArray(VAO);
    //Convert our vertex list into a continuous array, copy the vertices into the vertex buffer.
    float* vertexData = new float[vertexCount * attributeCount];
    for (int i = 0; i < vertexCount; i++)
        memcpy(&vertexData[i*attributeCount], 
            vlist[i].getAsArray(), sizeof(float)*attributeCount);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*attributeCount*vertexCount, vertexData, GL_STATIC_DRAW);
    //Copy the index data found in the list of triangles into the element array buffer (index array)
    //We are using a triangles, so we need triangleCount * 3 indices.
    int* indexData = new int[triangleCount * 3];
    for (int i = 0; i < triangleCount; i++)
        memcpy(&indexData[i * 3], tlist[i].verts, sizeof(int) * 3);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*3*triangleCount, indexData, GL_STATIC_DRAW);
    // Position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, attributeCount * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    // Color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, attributeCount * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);
    // Unbind VAO
    glBindVertexArray(0);

    // Delete temporary buffers
    delete[] vertexData;
    delete[] indexData;
}
void Object3D::CreateObject()
{
int attributeCount=6;
vertexCount=茶壶\u NB\u贴片*RESU*RESV;
三角计数=茶壶(RESU-1)*(RESV-1)*2;
制作茶壶();
//绑定顶点和索引缓冲区
glGenVertexArrays(1和VAO);
glGenBuffers(1,&VBO);
glGenBuffers(1和EBO);
//首先绑定顶点数组对象,然后绑定并设置缓冲区和指针。
glBindVertexArray(VAO);
//将顶点列表转换为连续数组,将顶点复制到顶点缓冲区中。
浮点*vertexData=新浮点[vertexCount*attributeCount];
对于(int i=0;i
主要功能是:

void init(int w, int h)
{
    // Init GLFW
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    // macOSX requirement :
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    glfwWindowHint(GLFW_SAMPLES, 4);

    window = glfwCreateWindow(w, h, "OpenGLTeapot", nullptr, nullptr); // Windowed
    glfwMakeContextCurrent(window);

    glfwSetKeyCallback(window, key_callback);

    // Initialize GLEW to setup the OpenGL Function pointers
    glewExperimental = GL_TRUE;
    glewInit();

    // Define the viewport dimensions
    glViewport(0, 0, w, h);

    // Enable depth test
    glEnable(GL_DEPTH_TEST);
}
int main()
{
    int screenWidth = 800;
    int screenHeight = 600;
    init(screenWidth, screenHeight);
    std::vector<Object3D*> listOfObjects;


    Object3D* pObj = new Object3D();


    pObj->CreateObject();
    listOfObjects.push_back(pObj);

    //Create the shaders. 
    Shader shader(VertexShaderPath, FragmentShaderPath);

    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();
        // Clear the colorbuffer
        glClearColor(0.0f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Use the shader
        shader.Use();
        // Transformations
        // Create camera transformation
        glm::mat4 view;
        glm::vec3 cameraPos = glm::vec3(0.0f, 150.0f, 100.0f);
        glm::vec3 cameraTarget = glm::vec3(0.0, 80.0f, 20.0f);
        glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
        view = glm::lookAt(cameraPos, cameraTarget, cameraUp);
        // Create projection transformation
        glm::mat4 projection;
        projection = glm::perspective<float>(90.0, (float)screenWidth / (float)screenHeight, 0.1f, 1000.0f);
        // Get the uniform locations
        GLint modelLoc = glGetUniformLocation(shader.Program, "model");
        GLint viewLoc = glGetUniformLocation(shader.Program, "view");
        GLint projLoc = glGetUniformLocation(shader.Program, "projection");
        // Pass the view and projection matrices to the shaders
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
        // Put the bottom of the object on XZ plane and scale it up
        pObj->modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(30.0f));
        pObj->modelMatrix = glm::rotate(pObj->modelMatrix, -90.0f, glm::vec3(1.0f, 0.0f,0.0f));
        for (auto pObj : listOfObjects)
        {
            glBindVertexArray(pObj->VAO);

            glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(pObj->modelMatrix));
            glDrawElements(GL_TRIANGLES, (pObj->vertexCount) * 6, GL_UNSIGNED_INT, 0);
            //glDrawElements(GL_TRIANGLES, 50, GL_UNSIGNED_INT, 0);
            glBindVertexArray(0);
        }
        // Swap the buffers

        glfwSwapBuffers(window);

    }
    for (auto pObj : listOfObjects)
    {
        glDeleteVertexArrays(1, &pObj->VAO);
        glDeleteBuffers(1, &pObj->VBO);
        glDeleteBuffers(1, &pObj->EBO);
        delete pObj;
    }
    glfwTerminate();
    return 0;
}
intmain()
{
int屏幕宽度=800;
int屏幕高度=600;
初始值(屏幕宽度、屏幕高度);
std::向量对象列表;
Object3D*pObj=新建Object3D();
pObj->CreateObject();
对象列表。推回(pObj);
//创建着色器。
着色器(VertexShaderPath、FragmentShaderPath);
而(!glfwWindowShouldClose(窗口))
{
glfwPollEvents();
//清除颜色缓冲区
glClearColor(0.0f、0.3f、0.3f、1.0f);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
//使用着色器
shader.Use();
//转变
//创建摄影机变换
glm::mat4视图;
glm::vec3 cameraPos=glm::vec3(0.0f、150.0f、100.0f);
glm::vec3摄像机目标=glm::vec3(0.0,80.0f,20.0f);
glm::vec3 cameraUp=glm::vec3(0.0f,1.0f,0.0f);
视图=glm::注视(cameraPos、cameraTarget、cameraUp);
//创建投影变换
glm::mat4投影;
投影=glm::透视(90.0,(浮动)屏幕宽度/(浮动)屏幕高度,0.1f,1000.0f);
//获取统一的位置
GLint modelLoc=glGetUniformLocation(shader.Program,“model”);
GLint viewLoc=glGetUniformLocation(shader.Program,“视图”);
GLint projLoc=glGetUniformLocation(shader.Program,“投影”);
//将视图和投影矩阵传递给着色器
glUniformMatrix4fv(视图位置,1,GL_假,glm::value_ptr(视图));
glUniformMatrix4fv(projLoc,1,GL_FALSE,glm::value_ptr(投影));
//将对象的底部放在XZ平面上,并将其放大
pObj->modelMatrix=glm::scale(glm::mat4(1.0f),glm::vec3(30.0f));
pObj->modelMatrix=glm::rotate(pObj->modelMatrix,-90.0f,glm::vec3(1.0f,0.0f,0.0f));
用于(自动pObj:listOfObjects)
{
glBindVertexArray(pObj->VAO);
glUniformMatrix4fv(modelLoc,1,GL_FALSE,glm::value_ptr(pObj->modelMatrix));
GLD元素(GL_三角形,(pObj->顶点计数)*6,GL_无符号整数,0);
//GLD元素(GLU三角形,50,GLU无符号整数,0);
glBindVertexArray(0);
}
//交换缓冲区
glfwSwapBuffers(窗口);
}
用于(自动pObj:listOfObjects)
{
GLDeleteVertexarray(1,&pObj->VAO);
glDeleteBuffers(1,&pObj->VBO);
glDeleteBuffers(1,&pObj->EBO);
删除pObj;
}
glfwTerminate();
返回0;
}

问题似乎与GLD元素函数的偏移量有关。当我将该行更改为:

glDrawElements(GL_TRIANGLES, (listOfObjects[i]->vertexCount) * 6, GL_UNSIGNED_INT, (void*)(sizeof(Vertex)));

它可以正确渲染。

欢迎使用SO。请阅读本文并遵循其中的指导原则,使用其他信息(如代码和错误消息)来完善您的问题,以描述您的编程问题。谢谢。问题是,没有错误消息。这就是为什么我没有添加任何源代码。我想分享整个代码,但因为这很容易