Класс текстуры
This commit is contained in:
		
							parent
							
								
									cee62312d0
								
							
						
					
					
						commit
						86f85229b5
					
				
							
								
								
									
										34
									
								
								include/Texture.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/Texture.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
#ifndef TEXTURE_H
 | 
			
		||||
#define TEXTURE_H
 | 
			
		||||
 | 
			
		||||
#include <glad/glad.h>
 | 
			
		||||
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
enum TexType {
 | 
			
		||||
    TEX_DIFFUSE,
 | 
			
		||||
    TEX_AVAILABLE_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Texture
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
        Texture(GLuint type = TEX_AVAILABLE_COUNT, const std::string& filename = ""); // Загрузка текстуры с диска или использование "пустой"
 | 
			
		||||
        Texture(const Texture& other); // Конструктор копирования
 | 
			
		||||
        ~Texture();
 | 
			
		||||
 | 
			
		||||
        Texture& operator=(const Texture& other); // Оператор присваивания
 | 
			
		||||
 | 
			
		||||
        static void init_textures(GLuint programID); // Инициализация текстур на шейдере
 | 
			
		||||
        void use(); // Привязка текстуры
 | 
			
		||||
        static void disable(GLuint type); // Отвязка текстуры по типу
 | 
			
		||||
        GLuint getType(); // Возвращает тип текстуры
 | 
			
		||||
    private:
 | 
			
		||||
        GLuint handler; // Дескриптор текстуры
 | 
			
		||||
        GLuint type; // Тип текстуры, соответствует её слоту
 | 
			
		||||
        static std::map<std::string, int> filename_handler; // Получение дескриптора текстуры по её имени
 | 
			
		||||
        static std::map<int, int> handler_count; // Получение количества использований по дескриптору текстуры (Shared pointer)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // TEXTURE_H
 | 
			
		||||
							
								
								
									
										129
									
								
								src/Texture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/Texture.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,129 @@
 | 
			
		||||
#include "Texture.h"
 | 
			
		||||
 | 
			
		||||
#define STB_IMAGE_IMPLEMENTATION
 | 
			
		||||
#include <stb_image.h>
 | 
			
		||||
 | 
			
		||||
std::map<std::string, int> Texture::filename_handler; // Получение дескриптора текстуры по её имени
 | 
			
		||||
std::map<int, int> Texture::handler_count; // Получение количества использований по дескриптору текстуры (Shared pointer)
 | 
			
		||||
 | 
			
		||||
// Загрузка текстуры с диска или использование "пустой"
 | 
			
		||||
Texture::Texture(GLuint t, const std::string& filename) : type(t)
 | 
			
		||||
{
 | 
			
		||||
    if (!filename_handler.count(filename))
 | 
			
		||||
    {
 | 
			
		||||
        std::string empty = "";
 | 
			
		||||
        int width, height, channels; // Ширина, высота и цветовые каналы текстуры
 | 
			
		||||
        unsigned char* image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_default); // Загрузка в оперативную память изображения
 | 
			
		||||
        // Если изображение успешно счиитано с диска или отсутствует пустая текстура
 | 
			
		||||
        if (image || !filename_handler.count(empty))
 | 
			
		||||
        {
 | 
			
		||||
            glActiveTexture(type + GL_TEXTURE0);
 | 
			
		||||
            glGenTextures(1, &handler); // Генерация одной текстуры
 | 
			
		||||
            glBindTexture(GL_TEXTURE_2D, handler); // Привязка текстуры как активной
 | 
			
		||||
 | 
			
		||||
            filename_handler[filename] = handler; // Запоминим её дескриптор для этого имени файла
 | 
			
		||||
            handler_count[handler] = 0; // Создадим счетчик использований дескриптора, который будет изменен в конце
 | 
			
		||||
 | 
			
		||||
            // Если изображение успешно считано
 | 
			
		||||
            if (image)
 | 
			
		||||
            {
 | 
			
		||||
                // Загрузка данных с учетом прозрачности
 | 
			
		||||
                if (channels == 3) // RGB
 | 
			
		||||
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
 | 
			
		||||
                else if (channels == 4) // RGBA
 | 
			
		||||
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
 | 
			
		||||
 | 
			
		||||
                glGenerateMipmap(GL_TEXTURE_2D); // Генерация мипмапа для активной текстуры
 | 
			
		||||
                glBindTexture(GL_TEXTURE_2D, 0); // Отвязка активной текстуры
 | 
			
		||||
                
 | 
			
		||||
                stbi_image_free(image); // Освобождение оперативной памяти
 | 
			
		||||
            }
 | 
			
		||||
            // Иначе изображение не считано и надо создать пустую текстуру
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                image = new unsigned char[3] {255,255,255}; // RGB по 1 байту на 
 | 
			
		||||
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, image); // Загрузка данных на видеокарту
 | 
			
		||||
                delete[] image; // Освобождение оперативной памяти
 | 
			
		||||
                
 | 
			
		||||
                filename_handler[empty] = handler; // Запоминим дополнительно её дескриптор для NULL-строки
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Иначе используем существующую пустую текстуру (текстура не загружена, пустую создавать не нужно)
 | 
			
		||||
        else
 | 
			
		||||
            handler = filename_handler[empty];
 | 
			
		||||
    }
 | 
			
		||||
    // Иначе используем уже существующую по имени файла
 | 
			
		||||
    else
 | 
			
		||||
        handler = filename_handler[filename];
 | 
			
		||||
        
 | 
			
		||||
    handler_count[handler]++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Конструктор копирования
 | 
			
		||||
Texture::Texture(const Texture& other) : handler(other.handler), type(other.type)
 | 
			
		||||
{
 | 
			
		||||
    // Делаем копию и увеличиваем счетчик
 | 
			
		||||
    handler_count[handler]++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Оператор присваивания
 | 
			
		||||
Texture& Texture::operator=(const Texture& other)
 | 
			
		||||
{
 | 
			
		||||
    // Если это разные текстуры
 | 
			
		||||
    if (handler != other.handler)
 | 
			
		||||
    {
 | 
			
		||||
        this->~Texture(); // Уничтожаем имеющуюся
 | 
			
		||||
        // Заменяем новой
 | 
			
		||||
        handler = other.handler;
 | 
			
		||||
        handler_count[handler]++;
 | 
			
		||||
    }
 | 
			
		||||
    type = other.type;
 | 
			
		||||
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Texture::~Texture()
 | 
			
		||||
{
 | 
			
		||||
    if (!--handler_count[handler]) // Если количество ссылок = 0
 | 
			
		||||
    {
 | 
			
		||||
        glDeleteTextures(1, &handler); // Удаление текстуры
 | 
			
		||||
        // Удаление из словаря имен файлов и дескрипторов
 | 
			
		||||
        for (auto it = filename_handler.begin(); it != filename_handler.end();)
 | 
			
		||||
        {
 | 
			
		||||
            if (it->second == handler) 
 | 
			
		||||
                it = filename_handler.erase(it);
 | 
			
		||||
            else
 | 
			
		||||
                it++;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char* textures_base_shader_names[] = {"tex_diffuse"};
 | 
			
		||||
 | 
			
		||||
// Инициализация текстур на шейдере
 | 
			
		||||
void Texture::init_textures(GLuint programID)
 | 
			
		||||
{
 | 
			
		||||
    // Цикл по всем доступным текстурам
 | 
			
		||||
    for (int i = 0; i < TEX_AVAILABLE_COUNT; i++)
 | 
			
		||||
        glUniform1i(glGetUniformLocation(programID, textures_base_shader_names[i]), i); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Привязка текстуры
 | 
			
		||||
void Texture::use()
 | 
			
		||||
{
 | 
			
		||||
    glActiveTexture(type + GL_TEXTURE0);
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, handler); // Привязка текстуры как активной
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Отвязка текстуры по типу
 | 
			
		||||
void Texture::disable(GLuint type)
 | 
			
		||||
{
 | 
			
		||||
    glActiveTexture(type + GL_TEXTURE0);
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, 0); // Отвязка текстуры
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Возвращает тип текстуры
 | 
			
		||||
GLuint Texture::getType()
 | 
			
		||||
{
 | 
			
		||||
    return type;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/main.cpp
									
									
									
									
									
								
							@ -2,13 +2,12 @@
 | 
			
		||||
#include <glad/glad.h>
 | 
			
		||||
#include <GLFW/glfw3.h>
 | 
			
		||||
#include <GLM/glm.hpp>
 | 
			
		||||
#define STB_IMAGE_IMPLEMENTATION
 | 
			
		||||
#include <stb_image.h>
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
#include "Camera.h"
 | 
			
		||||
#include "Model.h"
 | 
			
		||||
#include "Texture.h"
 | 
			
		||||
 | 
			
		||||
#define WINDOW_WIDTH 800
 | 
			
		||||
#define WINDOW_HEIGHT 600
 | 
			
		||||
@ -182,6 +181,8 @@ int main(void)
 | 
			
		||||
    GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
 | 
			
		||||
    // Активация шейдера
 | 
			
		||||
    glUseProgram(shaderProgram);
 | 
			
		||||
    // Установим значения текстур
 | 
			
		||||
    Texture::init_textures(shaderProgram);
 | 
			
		||||
 | 
			
		||||
    // Вершины прямоугольника
 | 
			
		||||
    glm::vec3 verticies[] = {  {-0.5f, -0.5f, 0.0f}
 | 
			
		||||
@ -217,23 +218,8 @@ int main(void)
 | 
			
		||||
    rectangle.e_rotation() = {0.707f, 0.707f, 0.0f, 0.0f};
 | 
			
		||||
    rectangle.e_scale() = glm::vec3(3);
 | 
			
		||||
    
 | 
			
		||||
    // Работа с текстурой
 | 
			
		||||
    GLuint texture; // Дескриптор текстуры
 | 
			
		||||
    glGenTextures(1, &texture); // Генерация одной текстуры
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, texture); // Привязка текстуры как активной
 | 
			
		||||
    
 | 
			
		||||
    int width, height, channels; // Ширина, высота и цветовые каналы текстуры
 | 
			
		||||
    unsigned char* image = stbi_load("../resources/textures/grass.png", &width, &height, &channels, STBI_default); // Загрузка в оперативную память изображения
 | 
			
		||||
    // Загрузка данных с учетом прозрачности
 | 
			
		||||
    if (channels == 3) // RGB
 | 
			
		||||
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
 | 
			
		||||
    else if (channels == 4) // RGBA
 | 
			
		||||
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
 | 
			
		||||
 | 
			
		||||
    glGenerateMipmap(GL_TEXTURE_2D); // Генерация мипмапа для активной текстуры
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, 0); // Отвязка активной текстуры
 | 
			
		||||
 | 
			
		||||
    stbi_image_free(image); // Освобождение оперативной памяти
 | 
			
		||||
    // Текстура травы
 | 
			
		||||
    Texture grass(TEX_DIFFUSE, "../resources/textures/grass.png");
 | 
			
		||||
 | 
			
		||||
    // Установка цвета очистки буфера цвета
 | 
			
		||||
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 | 
			
		||||
@ -254,7 +240,7 @@ int main(void)
 | 
			
		||||
        glClear(GL_COLOR_BUFFER_BIT);
 | 
			
		||||
 | 
			
		||||
        // Тут производится рендер
 | 
			
		||||
        glBindTexture(GL_TEXTURE_2D, texture); // Привязка текстуры как активной
 | 
			
		||||
        grass.use(); // Привязка текстуры как активной
 | 
			
		||||
        rectangle.render(model_uniform);
 | 
			
		||||
 | 
			
		||||
        // Представление содержимого буфера цепочки показа на окно
 | 
			
		||||
@ -263,9 +249,6 @@ int main(void)
 | 
			
		||||
        glfwPollEvents();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Удаление текстуры
 | 
			
		||||
    glDeleteTextures(1, &texture);
 | 
			
		||||
 | 
			
		||||
    // Удаление шейдерной программы
 | 
			
		||||
    glDeleteProgram(shaderProgram);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user