Opengl 3.3 在我的程序中加载纹理的问题

Opengl 3.3 Issue with loading textures in my program

我目前在使用 OpenGL 3.3 Core 一次渲染多个纹理时遇到问题。我通过 SOIL(图像加载库)加载了 2 个单独的图像,但只有一个图像出现在最终程序中。这是我当前的代码:

#include <iostream>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <SOIL.h>
#include "Shader.h"
#include "texture2D.h"

using namespace std;

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

int main() {

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

    GLFWwindow *window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
    if (window == NULL) {
        cout << "GLFW WINDOW CREATION FAILED! " << endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    cout << "Made By Rial Seebran " << endl;
    cout << glfwGetVersionString() << endl;

    glewInit();
    if (glewInit() != GLEW_OK) {
        cout << "GLEW INITIALIZATION FAILED! " << endl;
        glfwTerminate();
        return -1;
    }

    float positions[] = {
        -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
        -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
        0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.0f, 1.0f, 1.0f
    };

    unsigned int indices[] = {
        0, 1, 2,
        3, 2, 1
    };

    unsigned int VAO;
    unsigned int VBO;
    unsigned int EBO;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(0)));
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(sizeof(float) * 3)));
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    Shader shader("shader.vs", "shader.fs");

    Texture2D texture1;
    texture1.LoadTexture("container.jpg");

    Texture2D texture2;
    texture2.LoadTexture("awesomeface.png");

    shader.Use();

    while (!glfwWindowShouldClose(window)) {

        glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        texture1.BindTexture(0);
        texture2.BindTexture(1);

        shader.Uniform1I("myTexture1", 0);
        shader.Uniform1I("myTexture2", 1);

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);

        processInput(window);
        glfwPollEvents();
        glfwSwapBuffers(window);
    }

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


    glfwTerminate();
    return 0;
}

这是纹理 class(全部在 .h 文件中):

#ifndef TEXTURE2D
#define TEXTURE2D

#include <GL\glew.h>
#include <GL\GL.h>
#include <SOIL.h>
#include <iostream>

using namespace std;

class Texture2D {
public:
    Texture2D();
    ~Texture2D();
    void LoadTexture(const char* texPath);
    void BindTexture(unsigned int texUnit);
    unsigned int texture_M;
};

Texture2D::Texture2D() {

}

Texture2D::~Texture2D() {
    glDeleteTextures(1, &texture_M);
}

void Texture2D::LoadTexture(const char* texPath) {
    int width;
    int height;
    unsigned char *image = SOIL_load_image(texPath, &width, &height, 0, SOIL_LOAD_RGBA);
    if (image == NULL) {
        cout << "Failed to load Image! " << endl;
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, texture_M);
    if (image != NULL) {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
        glGenerateMipmap(GL_TEXTURE_2D);
    }

    SOIL_free_image_data(image);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void Texture2D::BindTexture(unsigned int texUnit) {
    glActiveTexture(GL_TEXTURE0 + texUnit);
    glBindTexture(GL_TEXTURE_2D, texture_M);
}

#endif 

在片段着色器中,我使用 mix() 函数对 2 个纹理进行线性插值,但 "awesomeface.png" 图像是最终程序中唯一出现的纹理。应该修复什么,程序才能显示两种纹理?

您必须在 Texture::LoadTexture() 的开头添加以下行以生成纹理 ID:

glGenTextures(1, &texture_M);

这将保留一个用于识别纹理对象的有效 ID(稍后必须通过调用 glBindTexture() 进行初始化)。它可用于在后续 OpenGL 调用中引用纹理(包括使用 glDeleteTextures() 删除纹理)。

我没有在texture2D中调用glGenTextures()class。感谢 Whosebug 用户@Rabbid76 指出这一点

当一个未使用的名称通过glBindTexture绑定到一个纹理目标时,就会生成一个纹理对象。 但是 glGenTextures.

必须保留一个新的未使用的纹理名称

glTexParameteri设置的纹理参数设置为绑定到指定目标的纹理对象。

保留未使用的纹理名称,然后创建纹理对象。之后你可以设置参数并指定two-dimensional纹理图像。

// 1. reserve texture name 
glGenTextures(1, &texture_M);

// 2. generate texture object
glBindTexture(GL_TEXTURE_2D, texture_M);

// set parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// generate texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);