OpenGL矩阵转换不起作用

时间:2017-06-30 12:41:51

标签: c opengl matrix

我正在关注learnopengl.com上的教程,但我遇到了一些问题。我用C而不是C ++编写我的程序,并使用linmath库进行矩阵转换,我有shader.c和texture.c文件。我认为问题在于我的矩阵转换,但我无法弄清楚我哪里出错了。程序运行并编译,创建窗口并且背景颜色正确但是对象不显示。

以下是来源:

#include <stdio.h>
#include <stdlib.h>

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "linmath.h"
#include "shader.h"
#include "texture.h"

void framebuffer_size_callback(GLFWwindow* window, int width, int height);

void processInput(GLFWwindow *window);

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main(){
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL){
        printf("Failed to create GLFW window");
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        printf("Failed to initialize GLAD");
        return -1;
    }
    Shader ourShader;
    ourShader.ID = loadShader("3.3.shader.vs", "3.3.shader.fs");

    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float vertices[] = {
        // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // top left 
    };     
    unsigned int indices[] = {
        0, 1, 3, // first triangle
        1, 2, 3  // second triangle
    };
    unsigned int VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    // texture coord attribute
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    Texture tex1 = loadTexture("container.jpg");
    Texture tex2 = loadTexture("awesomeface.png");

    // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
    // -------------------------------------------------------------------------------------------
    useShader(ourShader.ID);
    setIntShader("texture1", 0, ourShader.ID);
    setIntShader("texture2", 1, ourShader.ID);


    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        // input
        // -----
        processInput(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // bind textures on corresponding texture units
        bindTexture(tex1, GL_TEXTURE0);
        bindTexture(tex2, GL_TEXTURE1);

        // activate shader
        useShader(ourShader.ID);

        // create transformations
        mat4x4 model;
        mat4x4 m;
        mat4x4 view;
        mat4x4 projection;
        mat4x4_rotate(model, m, 1.0f, 0.0f, 0.0f, -0.95993f);
        mat4x4_translate(view, 0.0f, 0.0f, -3.0f);
        mat4x4_perspective(projection, 0.785f, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);

        // pass them to the shaders
        setMat4Shader("model", model, ourShader.ID);
        setMat4Shader("view", view, ourShader.ID);
        setMat4Shader("projection", projection, ourShader.ID);

        // render container
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

shader.c

#include "shader.h"

GLuint loadShader(const char * vertex_file_path,const char * fragment_file_path){

    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    char* VertexShaderCode;
    FILE * vertexFile = fopen(vertex_file_path, "r");
    if( vertexFile == NULL ){
        printf("Impossible to open the file !\n");
        return LOAD_FAILURE;
    }
    long vertex_file_size;
    fseek(vertexFile, 0, SEEK_END);
    vertex_file_size = ftell(vertexFile);
    rewind(vertexFile);
    VertexShaderCode = malloc((vertex_file_size + 1) * (sizeof(char)));
    fread(VertexShaderCode, sizeof(char), vertex_file_size, vertexFile);
    fclose(vertexFile);
    VertexShaderCode[vertex_file_size] = 0;

    // Read the Fragment Shader code from the file
    char* FragmentShaderCode;
    FILE * fragmentFile = fopen(fragment_file_path, "r");
    if( fragmentFile == NULL ){
        printf("Impossible to open the file !\n");
        return LOAD_FAILURE;
    }
    long fragment_file_size;
    fseek(fragmentFile, 0, SEEK_END);
    fragment_file_size = ftell(fragmentFile);
    rewind(fragmentFile);
    FragmentShaderCode = malloc((fragment_file_size + 1) * (sizeof(char)));
    fread(FragmentShaderCode, sizeof(char), fragment_file_size, fragmentFile);
    fclose(fragmentFile);
    FragmentShaderCode[fragment_file_size] = 0;


    const char* vsCode = VertexShaderCode;
    const char* fsCode = FragmentShaderCode;

    // 2. compile shaders
    unsigned int vertex, fragment;
    int success;
    char infoLog[512];
    // vertex shader
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vsCode, NULL);
    glCompileShader(vertex);
    checkCompileErrors(vertex, "VERTEX");
    // fragment Shader
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fsCode, NULL);
    glCompileShader(fragment);
    checkCompileErrors(fragment, "FRAGMENT");
    // shader Program
    GLuint ID = glCreateProgram();
    glAttachShader(ID, vertex);
    glAttachShader(ID, fragment);
    glLinkProgram(ID);
    checkCompileErrors(ID, "PROGRAM");
    // delete the shaders as they're linked into our program now and no longer necessery
    glDeleteShader(vertex);
    glDeleteShader(fragment);

    return ID;
}

void useShader(unsigned int ID){
    glUseProgram(ID);
}  

void setBoolShader(const char * name, int value, unsigned int ID)
{
    glUniform1i(glGetUniformLocation(ID, name), value);
}
void setIntShader(const char * name, int value, unsigned int ID) 
{
    glUniform1i(glGetUniformLocation(ID, name), value);
}
void setFloatShader(const char * name, float value, unsigned int ID)
{
    glUniform1f(glGetUniformLocation(ID, name), value);
}
void setMat4Shader(const char * name, mat4x4 mat, unsigned int ID)
{
    glUniformMatrix4fv(glGetUniformLocation(ID, name), 1, GL_FALSE, *mat);
}

void checkCompileErrors(GLuint shader, char type[])
{
    GLint success;
    GLchar infoLog[1024];
    if(strncmp(type, "PROGRAM", 7) != 0)
    {
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if(!success)
        {
            glGetShaderInfoLog(shader, 1024, NULL, infoLog);
            printf("ERROR::SHADER_COMPILATION_ERROR of type: %s \n %s \n", type, infoLog);
        }
    }
    else
    {
        glGetProgramiv(shader, GL_LINK_STATUS, &success);
        if(!success)
        {
            glGetProgramInfoLog(shader, 1024, NULL, infoLog);
            printf("ERROR::SHADER_COMPILATION_ERROR of type: %s \n %s \n", type, infoLog);
        }
    }
}

texture.c

#include "texture.h"

Texture loadTexture(const char* path){
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    // set the texture wrapping/filtering options (on the currently bound texture object)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    //load texture
    int width, height, nrChannels;
    unsigned char *data = SOIL_load_image(path, &width, &height, &nrChannels, SOIL_LOAD_RGB);
    if(data){
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    } else{
        printf("Failed to load Image");
    }
    SOIL_free_image_data(data);

    Texture t;
    t.ID = texture;
    t.path = path;

    return t;
}

void bindTexture(Texture texture, GLenum unit){
    // bind textures on corresponding texture units
    glActiveTexture(unit);
    glBindTexture(GL_TEXTURE_2D, texture.ID);
}

顶点着色器

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

片段着色器

#version 330 core
out vec4 FragColor;

in vec2 TexCoord;

// texture samplers
uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    // linearly interpolate between both textures (80% container, 20% awesomeface)
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

0 个答案:

没有答案