【问题标题】:Opengl 3.3 Issue with loading textures in my program在我的程序中加载纹理的 Opengl 3.3 问题
【发布时间】:2019-11-11 05:36:40
【问题描述】:

我目前在使用 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() 函数线性插值这两个纹理,但“awesomeface.png”图像是唯一出现在最终程序中的纹理。应该解决什么问题,让程序显示两种纹理?

【问题讨论】:

  • 在哪里生成纹理名称 (glGenTextures)?
  • 请发布您的着色器代码。
  • 如果可能,考虑使用 OpenGL 4.5 中引入的新的直接状态访问模式来避免绑定。
  • 谢谢,我假设在类的公共区域创建 texture_M 会创建纹理。你已经回答了我的问题@Rabbid76

标签: c++ opengl glsl opengl-3


【解决方案1】:

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

glGenTextures(1, &texture_M);

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • @cs95 对不起,你是对的,对不起我很生气,因为我正在研究一个完整的答案,而我的评论已作为答案发布并被接受。
    • @Rabbid76 接受是次要的。只需专注于写一个好的答案,其余的将由投票系统(和标记系统,如果需要)来处理。干杯。
    • @cs95 是的,我知道,但我是人类,正如我提到的,我很生气。我道歉
    【解决方案3】:

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

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

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

    // 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);
    

    【讨论】:

    • 对不起,我不应该发布那个答案。如果不被接受,我会删除它。
    • @YanB。别担心。你的答案没有错,没关系。昨天我很生气,但今天是另一天。无需删除。
    猜你喜欢
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多