纹理不适用于C ++和OpenGL中的立方体

时间:2019-08-05 21:50:23

标签: c++ opengl shader textures

我正在使用C ++中的OpenGL tutorial。 我的问题是关于对多维数据集进行纹理化。该程序似乎正确加载了纹理,但是没有显示预期的结果,我的多维数据集看起来是灰色的。

  • 我通常应该拥有的东西: What I should normally have
  • 我所拥有的: What I have

我已经尝试过更改着色器(例如混合值),但是它什么都没有改变。

这是我的代码:

  • head.h
#pragma once

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>


#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <chrono>

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include "shader.hpp"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
  • shader.hpp
#include "head.h"

/*TODO -- refresh shader every sec*/

class Shader {

public:

    Shader(std::string const& nameFragment, std::string const& nameVertex)
        : nameFragment_(nameFragment), nameVertex_(nameVertex) {

        update();
    }

    void update(){

        if (nameFragment_.empty() || nameVertex_.empty() || (nameFragment_.empty() && nameVertex_.empty())) {
            return;
        }


            bool recreate = false;
            std::ifstream stream(nameFragment_);
            std::string tmp = std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
            stream.close();
            if (tmp != fragment_) {
                setFragment(tmp);
                recreate = true;
            }

            stream.open(nameVertex_);
            tmp = std::string(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>());
            stream.close();
            if (tmp != vertex_) {
                setVertex(tmp);
                recreate = true;
            }

            if (recreate) {
                createFragmentObject();
                createVertexObject();
                createProgramObject();
                deleteUselessShaders();
                std::cout << nameFragment_ << " & " << nameVertex_ << " Shaders loaded.\n";
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    void use() {
        glUseProgram(programObject_);
    }

    void setFragmentName(std::string const& name) {
        nameFragment_ = name;
    }

    void setVertexName(std::string const& name) {
        nameVertex_ = name;
    }

    std::string getFragmentName() {
        return nameFragment_;
    }

    std::string getVertexName() {
        return nameVertex_;
    }

    void setFragment(std::string const& fragment) {
        fragment_ = fragment;
        fs_ptr_ = fragment_.c_str();
    }

    const GLchar*& getFragment() {
        return fs_ptr_;
    }

    void setVertex(std::string const& vertex) {
        vertex_ = vertex;
        vs_ptr_ = vertex_.c_str();
    }

    const GLchar*& getVertex() {
        return vs_ptr_;
    }

    void createVertexObject() {
        /*Creating a VS object*/
        vertexObject_ = glCreateShader(GL_VERTEX_SHADER);

        /*Link the VS code to the VS object*/
        glShaderSource(vertexObject_, 1, &vs_ptr_, NULL);
        glCompileShader(vertexObject_);

        /*Testing the VS compilation*/
        int  success;
        char infoLog[512];
        glGetShaderiv(vertexObject_, GL_COMPILE_STATUS, &success);

        if (!success) {
            glGetShaderInfoLog(vertexObject_, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
    }

    const unsigned int & getVertexObject() {
        return vertexObject_;
    }

    void createFragmentObject() {
        /*As the VS, same for FS*/
        fragmentObject_ = glCreateShader(GL_FRAGMENT_SHADER);

        glShaderSource(fragmentObject_, 1, &fs_ptr_, NULL);
        glCompileShader(fragmentObject_);

        int  success;
        char infoLog[512];

        glGetShaderiv(fragmentObject_, GL_COMPILE_STATUS, &success);

        if (!success) {
            glGetShaderInfoLog(fragmentObject_, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
    }

    const unsigned int& getFragmentObject() {
        return fragmentObject_;
    }

    void createProgramObject() {
        /*Creating the program Shader*/
        programObject_ = glCreateProgram();

        glAttachShader(programObject_, vertexObject_);
        glAttachShader(programObject_, fragmentObject_);
        glLinkProgram(programObject_);

        int  success;
        char infoLog[512];

        /*Testing PS compilation*/
        glGetProgramiv(programObject_, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(programObject_, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
    }

    const unsigned int& getProgramObject() {
        return programObject_;
    }

    void deleteUselessShaders() {
        /*Deleting shaders already used*/
        glDeleteShader(vertexObject_);
        glDeleteShader(fragmentObject_);
    }

    void setBool(const std::string& name, bool value) const
    {
        glUniform1i(glGetUniformLocation(programObject_, name.c_str()), (int)value);
    }
    // ------------------------------------------------------------------------
    void setInt(const std::string& name, int value) const
    {
        glUniform1i(glGetUniformLocation(programObject_, name.c_str()), value);
    }
    // ------------------------------------------------------------------------
    void setFloat(const std::string& name, float value) const
    {
        glUniform1f(glGetUniformLocation(programObject_, name.c_str()), value);
    }
    // ------------------------------------------------------------------------
    void setVec2(const std::string& name, const glm::vec2& value) const
    {
        glUniform2fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
    }
    void setVec2(const std::string& name, float x, float y) const
    {
        glUniform2f(glGetUniformLocation(programObject_, name.c_str()), x, y);
    }
    // ------------------------------------------------------------------------
    void setVec3(const std::string& name, const glm::vec3& value) const
    {
        glUniform3fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
    }
    void setVec3(const std::string& name, float x, float y, float z) const
    {
        glUniform3f(glGetUniformLocation(programObject_, name.c_str()), x, y, z);
    }
    // ------------------------------------------------------------------------
    void setVec4(const std::string& name, const glm::vec4& value) const
    {
        glUniform4fv(glGetUniformLocation(programObject_, name.c_str()), 1, &value[0]);
    }
    void setVec4(const std::string& name, float x, float y, float z, float w) const
    {
        glUniform4f(glGetUniformLocation(programObject_, name.c_str()), x, y, z, w);
    }
    // ------------------------------------------------------------------------
    void setMat2(const std::string& name, const glm::mat2& mat) const
    {
        glUniformMatrix2fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    // ------------------------------------------------------------------------
    void setMat3(const std::string& name, const glm::mat3& mat) const
    {
        glUniformMatrix3fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    // ------------------------------------------------------------------------
    void setMat4(const std::string& name, const glm::mat4& mat) const
    {
        glUniformMatrix4fv(glGetUniformLocation(programObject_, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }


private:
    std::string nameFragment_;
    std::string nameVertex_;
    std::string vertex_;
    std::string fragment_;
    const GLchar *vs_ptr_;
    const GLchar *fs_ptr_;
    unsigned int vertexObject_;
    unsigned int fragmentObject_;
    unsigned int programObject_;
};
  • main.cpp
/*mises à l’échelle, puis les rotations et enfin les translations*/
/*glm::mat4; mat = glm::mat4(1.0f);*/

#include "head.h"

#define FPS 62
#define WIDTH 800
#define HEIGHT 600

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

int main(){

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);    //For MacOS
#endif

    /*Window initialization*/
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Hello Window!", NULL, NULL);
    if (window == NULL){
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);


    /*GLAD initialization*/
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    // configure global opengl state
    // -----------------------------
    glEnable(GL_DEPTH_TEST);


    /*Initialize shaders*/
    Shader myShaders("./Shaders/Hello.fs", "./Shaders/Hello.vs");

    /*Vertices*/
    float vertices[] = {
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    glm::vec3 cubePositions[] = {
        glm::vec3(0.0f,  0.0f,  0.0f),
        glm::vec3(2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3(2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3(1.3f, -2.0f, -2.5f),
        glm::vec3(1.5f,  2.0f, -2.5f),
        glm::vec3(1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

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


    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // texture coord attribute
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);



    // load and create a texture 
    // -------------------------
    unsigned int texture1, texture2;
    // texture 1
    // ---------
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
    // set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    // set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // load image, create texture and generate mipmaps
    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    // The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
    unsigned char* data = stbi_load(("./Textures/container.jpg"), &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data); 
    // texture 2
    // ---------
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);
    // set the texture wrapping parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // set texture filtering parameters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // load image, create texture and generate mipmaps
    data = stbi_load("./Textures/awesomeface.png", &width, &height, &nrChannels, 0);
    if (data)
    {
        // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
    myShaders.use();
    myShaders.setInt("texture1", 0);
    myShaders.setInt("texture2", 1);


    /*To get a wireframe style*/
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);


    /*Render Loop*/
    double lasttime = glfwGetTime();
    while (!glfwWindowShouldClose(window)){

        glfwSwapBuffers(window);

        while (glfwGetTime() < lasttime + 1.0 / FPS) {

            processInput(window);

            glClearColor(0.2f, 0.7f, 0.6f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now!

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, texture1);
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, texture2);

            /*Activating our shader*/
            myShaders.use();

            // create transformations
            glm::mat4 view = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
            glm::mat4 projection = glm::mat4(1.0f);
            projection = glm::perspective(glm::radians(45.0f), (float)WIDTH / (float)HEIGHT, 0.1f, 100.0f);
            view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

            // pass transformation matrices to the shader
            myShaders.setMat4("projection", projection); // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
            myShaders.setMat4("view", view);

            // render boxes
            glBindVertexArray(VAO);

            for (unsigned int i = 0; i < 10; i++)
            {
                // calculate the model matrix for each object and pass it to shader before drawing
                glm::mat4 model = glm::mat4(1.0f);
                model = glm::translate(model, cubePositions[i]);
                float angle = 20.0f * i;
                model = glm::rotate(model,  glm::radians((float)angle), glm::vec3(1.0f, 0.3f, 0.5f));
                myShaders.setMat4("model", model);

                glDrawArrays(GL_TRIANGLES, 0, 36);
            }

            glfwPollEvents();
        }
        lasttime += 1.0 / FPS;

    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    glfwTerminate();


    return 0;
}


/*Resize*/
void framebuffer_size_callback(GLFWwindow* window, int width, int height){
    glViewport(0, 0, width, height);
}


/*Handle inputs*/
void processInput(GLFWwindow* window){
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}
  • Hello.fs
#version 330 core

out vec4 FragColor;

in vec2 TexCoord;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
  FragColor = mix(texture(texture1,TexCoord),texture(texture2,TexCoord),0.2f);
}
  • Hello.vs
#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor; // la variable aColor a l'attribut de position 1
layout (location = 2) 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, 1.0 - aTexCoord.y);
}

1 个答案:

答案 0 :(得分:3)

看看:

// texture coord attribute
glVertexAttribPointer(1, [...] );

vs。您的着色器:

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor; // la variable aColor a l'attribut de position 1
layout (location = 2) in vec2 aTexCoord;

因此,您实际上告诉GL将纹理坐标用作aColor属性。而且,由于您根本没有为属性位置2(aTexCoord)启用数组,因此所有顶点都将看到相同的纹理坐标值,因此纹理采样将在所有位置从纹理返回相同的颜色...