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

时间:2019-06-29 20:56:58

标签: c++ opengl glsl opengl-3

我目前在使用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;
}

这是纹理类(都在.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”图像是最终程序中唯一显示的纹理。为了使程序同时显示两种纹理,应该解决什么问题?

final program output

3 个答案:

答案 0 :(得分:2)

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

glGenTextures(1, &texture_M);

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

通过glBindTexture将未使用的名称绑定到纹理目标时,将生成纹理对象。 但是glGenTextures必须保留一个新的未使用的纹理名称。

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

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

user.menu