簡體   English   中英

紋理不適用於C ++和OpenGL中的立方體

[英]Texture doesn't apply to my cube in C++ & OpenGL

我正在關注C ++中的OpenGL 教程 我的問題是關於對多維數據集進行紋理化。 該程序似乎正確加載了紋理,但未顯示預期結果,我的多維數據集看起來是灰色的。

  • 我通常應該擁有的東西: 我通常應該擁有的
  • 我有的: 我有的

我已經嘗試過更改着色器(如混合值),但它沒有任何改變。

這是我的代碼:

  • 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);
}

看着:

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

與您的着色器:

 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 )啟用數組,因此所有頂點將看到相同的紋理坐標值,因此紋理采樣將在所有位置從紋理返回相同的顏色...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM