Класс текстуры
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 <glad/glad.h>
 | 
				
			||||||
#include <GLFW/glfw3.h>
 | 
					#include <GLFW/glfw3.h>
 | 
				
			||||||
#include <GLM/glm.hpp>
 | 
					#include <GLM/glm.hpp>
 | 
				
			||||||
#define STB_IMAGE_IMPLEMENTATION
 | 
					 | 
				
			||||||
#include <stb_image.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Camera.h"
 | 
					#include "Camera.h"
 | 
				
			||||||
#include "Model.h"
 | 
					#include "Model.h"
 | 
				
			||||||
 | 
					#include "Texture.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define WINDOW_WIDTH 800
 | 
					#define WINDOW_WIDTH 800
 | 
				
			||||||
#define WINDOW_HEIGHT 600
 | 
					#define WINDOW_HEIGHT 600
 | 
				
			||||||
@ -182,6 +181,8 @@ int main(void)
 | 
				
			|||||||
    GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
 | 
					    GLuint shaderProgram = LoadShaders("shaders/shader.vert", "shaders/shader.frag");
 | 
				
			||||||
    // Активация шейдера
 | 
					    // Активация шейдера
 | 
				
			||||||
    glUseProgram(shaderProgram);
 | 
					    glUseProgram(shaderProgram);
 | 
				
			||||||
 | 
					    // Установим значения текстур
 | 
				
			||||||
 | 
					    Texture::init_textures(shaderProgram);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Вершины прямоугольника
 | 
					    // Вершины прямоугольника
 | 
				
			||||||
    glm::vec3 verticies[] = {  {-0.5f, -0.5f, 0.0f}
 | 
					    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_rotation() = {0.707f, 0.707f, 0.0f, 0.0f};
 | 
				
			||||||
    rectangle.e_scale() = glm::vec3(3);
 | 
					    rectangle.e_scale() = glm::vec3(3);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Работа с текстурой
 | 
					    // Текстура травы
 | 
				
			||||||
    GLuint texture; // Дескриптор текстуры
 | 
					    Texture grass(TEX_DIFFUSE, "../resources/textures/grass.png");
 | 
				
			||||||
    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); // Освобождение оперативной памяти
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Установка цвета очистки буфера цвета
 | 
					    // Установка цвета очистки буфера цвета
 | 
				
			||||||
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 | 
					    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 | 
				
			||||||
@ -254,7 +240,7 @@ int main(void)
 | 
				
			|||||||
        glClear(GL_COLOR_BUFFER_BIT);
 | 
					        glClear(GL_COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Тут производится рендер
 | 
					        // Тут производится рендер
 | 
				
			||||||
        glBindTexture(GL_TEXTURE_2D, texture); // Привязка текстуры как активной
 | 
					        grass.use(); // Привязка текстуры как активной
 | 
				
			||||||
        rectangle.render(model_uniform);
 | 
					        rectangle.render(model_uniform);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Представление содержимого буфера цепочки показа на окно
 | 
					        // Представление содержимого буфера цепочки показа на окно
 | 
				
			||||||
@ -263,9 +249,6 @@ int main(void)
 | 
				
			|||||||
        glfwPollEvents();
 | 
					        glfwPollEvents();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Удаление текстуры
 | 
					 | 
				
			||||||
    glDeleteTextures(1, &texture);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Удаление шейдерной программы
 | 
					    // Удаление шейдерной программы
 | 
				
			||||||
    glDeleteProgram(shaderProgram);
 | 
					    glDeleteProgram(shaderProgram);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user