Opengl 3.3 Проблема с загрузкой текстур в моей программе - PullRequest
1 голос
/ 29 июня 2019

В настоящее время у меня проблема с рендерингом нескольких текстур одновременно с OpenGL 3.3 Core. Я загружаю 2 отдельных изображения через SOIL (библиотека загрузки изображений), но в финальной программе появляется только одно изображение. Это мой текущий код:

#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 ]

2 голосов
/ 30 июня 2019

Я не звонил glGenTextures() в классе texture2D.Спасибо пользователю stackOverflow @ Rabbid76 за указание на это

2 голосов
/ 30 июня 2019

Если неиспользуемое имя привязано к цели текстуры с помощью 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);
2 голосов
/ 30 июня 2019

Вы должны добавить следующую строку в начале Texture::LoadTexture(), чтобы сгенерировать идентификатор текстуры:

glGenTextures(1, &texture_M);

Это зарезервирует действительный идентификатор, используемый для идентификации объекта текстуры (который позже потребуетсябыть инициализирован вызовом glBindTexture()).Он может использоваться для ссылки на текстуру в последующих вызовах OpenGL (включая удаление текстуры с помощью glDeleteTextures()).

...