尝试应用纹理时,opengl崩溃

时间:2018-08-07 22:34:14

标签: opengl

我正在尝试将纹理应用于opengl程序,但是该程序由于某种原因而崩溃,有人可以告诉我我做错了什么吗?现在尝试修复此问题两天:/当片段着色器中的颜色设置为某种随机颜色,但当颜色为时: vec4 textColor = texture(u_Texture,v_TextCoord); color = textColor;

编辑:

#define GLEW_STATIC
#define alloca __builtin_alloca

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stb_image.h>

using namespace std;

static string ParseShader(const string& filepath);
static unsigned int CompileShader(unsigned int type, const string& source);
static unsigned int CreateShader(const string& vertexShader, const string& fragmentShader);
void glCheckError();

    float vertex[] =
    {
    0.5f,  0.5f, 0.0f,
    1.0f, 1.0f,     // 0
    0.5f, -0.5f, 0.0f,
    1.0f, 0.0f,     // 1
    -0.5f, -0.5f, 0.0f,
    0.0f, 0.0f,     // 2
   -0.5f,  0.5f, 0.0f,
    0.0f, 1.0f      // 3
    };

    float vertexBack[] =
    {
    -0.6,  -0.6f, -0.5f,    // 0
    0.6f, -0.6f, -0.5f,     // 1
    0.6f,  0.6f, -0.5f,     // 2
    -0.6f, 0.6f, -0.5f      // 3
    };

    unsigned int indexes[] =
    {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
    };

int main(void)
{
    GLFWwindow* window;


    /* Initialize the library */
    if (!glfwInit())
    {
        cout << "GLFW failed to load!" << endl;
        return -1;
    }

    else
        cout << "GLFW loaded" << endl << endl;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(800, 600, "Window", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;

    if(glewInit() != GLEW_OK)
        cout << "Error loading GLEW" << endl;
    else
        cout << "GLEW loaded - version: " << glGetString(GL_VERSION) << endl;

    unsigned int shader = CreateShader(ParseShader("shaders/vertex.shader"), ParseShader("shaders/fragment.shader"));
    glUseProgram(shader);


        // Make vertex position array
        unsigned int buffers;
        glGenBuffers(1, &buffers);
        glBindBuffer(GL_ARRAY_BUFFER, buffers);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);

        // Make vertex position indexes out of arrays
        unsigned int ib;
        glGenBuffers(1, &ib);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW);

        // Position layout
        unsigned int posAttrib = glGetAttribLocation(shader, "position");
        glEnableVertexAttribArray(posAttrib);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);

        // Texture layout
        unsigned int texAttrib = glGetAttribLocation(shader, "texCoord");
        glEnableVertexAttribArray(texAttrib);
        glCheckError();
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(3 * sizeof(float)));

        // Load image
        int h, w, v_bpp;
        unsigned char *image = stbi_load("texture.png", &w, &h, &v_bpp, 4);

        if(image == nullptr)
            cout << "failed to load image!" << endl;

        unsigned int texture_id;
        glGenTextures(1, &texture_id);
        glBindTexture(GL_TEXTURE_2D, texture_id);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
        glGenerateMipmap(GL_TEXTURE_2D);
        stbi_image_free(image);

        // Set slot
        glActiveTexture(GL_TEXTURE0);
        int location = glGetUniformLocation(shader, "u_Texture");
        glUniform1i(location, 0);



        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


        glBindTexture(GL_TEXTURE_2D, 0);


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS)
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);


        glCheckError();
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

static string ParseShader(const string& filepath) {
    ifstream stream(filepath);

    string line;
    stringstream code;

    while(getline(stream, line))
        code << line << "\n";

    return code.str();
}

static unsigned int CompileShader(unsigned int type, const string& source) {
    unsigned int id = glCreateShader(type);
    const char* src = source.c_str();
    glShaderSource(id, 1, &src, NULL);
    glCompileShader(id);

    int result;
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);

    if(result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        char* message = (char*)alloca(length * sizeof(char));
        glGetShaderInfoLog(id, length, &length, message);
        cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "Vertex" : "Fragment") << " shader!" << endl;
        cout << message << endl;

        glDeleteShader(id);
        return 0;
    }

    return id;
}

static unsigned int CreateShader(const string& vertexShader, const string& fragmentShader) {
    unsigned int program = glCreateProgram();
    unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
    unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);

    glDeleteShader(vs);
    glDeleteShader(fs);

    return program;
}

void glCheckError() {
        GLenum err = glGetError();
        while(err!=GL_NO_ERROR) {
                string error;

                switch(err) {
                        case GL_INVALID_OPERATION:      error="INVALID_OPERATION";      break;
                        case GL_INVALID_ENUM:           error="INVALID_ENUM";           break;
                        case GL_INVALID_VALUE:          error="INVALID_VALUE";          break;
                        case GL_OUT_OF_MEMORY:          error="OUT_OF_MEMORY";          break;
                        case GL_INVALID_FRAMEBUFFER_OPERATION:  error="INVALID_FRAMEBUFFER_OPERATION";  break;
                }

                cerr << err << " (" << error.c_str() << ")" <<endl;
                err=glGetError();
        }
}

1 个答案:

答案 0 :(得分:2)

您完全搞砸了顶点属性ponter的设置:

   // Position layout
    unsigned int posAttrib = glGetAttribLocation(shader, "position");
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, 0);

首先,您查询名为position的属性,但是您从未使用该索引,而是使用0

   // Texture layout
    unsigned int texAttrib = glGetAttribLocation(shader, "texCoord");
    glEnableVertexAttribArray(1);
    glCheckError();
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(3 * sizeof(float)));

然后,您查询texCoord,再次忽略它,启用属性数组1,并覆盖属性0的属性指针。

这意味着属性1具有一些未定义的指针值,并且您具有未定义的行为。

最有可能发生的事情是,当您不使用纹理时,您很幸运,因为只有一个活动属性恰巧获得位置0。并且您的GL实现似乎忽略了非活动属性的属性数组,因此不会崩溃。同时启用两个属性时,它们将分别为01,并且没有办法不取消引用该无效指针。