为什么这会导致访问冲突?

时间:2014-09-21 04:02:56

标签: c++ opengl glsl

这是一个非常庞大的程序,因此我尝试将其缩小到我认为导致0xFEEEFEEE违规的范围。虽然是一个庞大的程序(通过行数反正),但它确实很简单:使用OpenGL绘制一个三角形。需要注意的一点是,如果我输出控制台,该程序似乎只会触发访问冲突,假设它没有正确破坏。

部首:

#include <iostream>
#include <vector>
#include <string>

class Mesh
{

public:

    Mesh(std::string FileName);
    ~Mesh();
    void Draw();

private:

    unsigned int VBO = 0;
    unsigned int VAO = 0;

    std::vector<float> Vertices;

    const char* VertexShader =
        "#version 330\n"
        "in vec3 vp;"
        "void main () {"
        "  gl_Position = vec4 (vp, 2.0);"
        "}";

    const char* FragmentShader =
        "#version 330\n"
        "out vec4 frag_colour;"
        "void main () {"
        "  frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);"
        "}";

};

#endif // MESH_H

CPP:

#define GLEW_STATIC

#include <GL\glew.h>
#include <glm\glm.hpp>

#include <iostream>
#include <fstream>
#include <string>

#include "Mesh.h"

Mesh::Mesh(std::string FileName)
{
    float X;
    float Y;
    float Z;

    int LoopCount = 1;
    int VerticesCount = 0;

    std::string Input;

    std::ifstream OBJFile;
    OBJFile.open(FileName);

    while (!OBJFile.eof())
    {

        OBJFile >> Input;

        if (Input == "v")
        {
            OBJFile >> X;
            OBJFile >> Y;
            OBJFile >> Z;

            std::cout << "Loaded in " << X << " for X # " << LoopCount << std::endl;
            std::cout << "Loaded in " << Y << " for Y # " << LoopCount << std::endl;
            std::cout << "Loaded in " << Z << " for Z # " << LoopCount << std::endl;

            Vertices.push_back(X);
            Vertices.push_back(Y);
            Vertices.push_back(Z);

            LoopCount++;
            VerticesCount = VerticesCount + 3;
        }
        else
        {
            std::cout << "In loading " << FileName << " " << "skipped " << Input << std::endl;
            continue;
        }

    }

}

Mesh::~Mesh()
{
    std::cout << "Deconstructed" << std::endl;
}

void Mesh::Draw()
{

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, Vertices.size() * sizeof(float), &Vertices.front(), GL_STATIC_DRAW);

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &VertexShader, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &FragmentShader, NULL);
    glCompileShader(fs);

    GLuint shader_programme = glCreateProgram();
    glAttachShader(shader_programme, fs);
    glAttachShader(shader_programme, vs);
    glLinkProgram(shader_programme);

    glUseProgram(shader_programme);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

然后我执行Mesh myMesh,然后在我的主循环Mesh.draw()

1 个答案:

答案 0 :(得分:1)

关于您的程序的一个注意事项 - 您正在重新创建所有顶点数组和程序等,并在每次调用Draw时重新编译着色器。如果您在主循环中执行此操作,则意味着您在每个帧上重做它,这将非常慢。 GL对象的整点是在程序启动时将它们设置为一次,然后在每次绘制时重复使用它们。所以你的Draw函数应该是:

void Mesh::Draw() {
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBindVertexArray(VAO);
    glUseProgram(shader_programme);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

所有其他设置内容应该在构造函数中。