Browse Source

Add texture class and texture test

master
Riyyi 3 years ago
parent
commit
9aee7e391d
  1. BIN
      assets/gfx/test.png
  2. 12
      assets/glsl/texture.frag
  3. 12
      assets/glsl/texture.vert
  4. 72
      inferno/src/inferno/application.cpp
  5. 21
      inferno/src/inferno/application.h
  6. 139
      inferno/src/inferno/render/texture.cpp
  7. 56
      inferno/src/inferno/render/texture.h

BIN
assets/gfx/test.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

12
assets/glsl/texture.frag

@ -0,0 +1,12 @@
#version 450 core
layout(location = 0) out vec4 color;
in vec2 v_texCoord;
uniform sampler2D u_texture;
void main()
{
color = texture(u_texture, v_texCoord);
}

12
assets/glsl/texture.vert

@ -0,0 +1,12 @@
#version 450 core
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec2 a_texCoord;
out vec2 v_texCoord;
void main()
{
v_texCoord = a_texCoord;
gl_Position = vec4(a_position, 1.0f);
}

72
inferno/src/inferno/application.cpp

@ -12,6 +12,7 @@
#include "inferno/render/context.h"
#include "inferno/render/renderer.h"
#include "inferno/render/shader.h"
#include "inferno/render/texture.h"
#include "inferno/window.h"
namespace Inferno {
@ -29,32 +30,68 @@ namespace Inferno {
m_window = std::make_unique<Window>();
m_window->setEventCallback(NF_BIND_EVENT(Application::onEvent));
float vertices[] = {
TextureManager textureManager;
m_texture = textureManager.load("assets/gfx/test.png");
// -----------------------------------------
float verticesColor[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
uint32_t indices[] = {
uint32_t indicesColor[] = {
0, 1, 2, 2, 3, 0
};
m_vertexArray = std::make_shared<VertexArray>();
m_vertexArrayColor = std::make_shared<VertexArray>();
std::shared_ptr<VertexBuffer> vertexBuffer = std::make_shared<VertexBuffer>(vertices, sizeof(vertices));
vertexBuffer->setLayout({
std::shared_ptr<VertexBuffer> vertexBufferColor = std::make_shared<VertexBuffer>(verticesColor, sizeof(verticesColor));
vertexBufferColor->setLayout({
{ BufferElementType::Vec3, "a_position" },
{ BufferElementType::Vec4, "a_color" },
});
m_vertexArray->addVertexBuffer(vertexBuffer);
m_vertexArrayColor->addVertexBuffer(vertexBufferColor);
std::shared_ptr<IndexBuffer> indexBufferColor = std::make_shared<IndexBuffer>(indicesColor, sizeof(indicesColor));
m_vertexArrayColor->setIndexBuffer(indexBufferColor);
// -----------------------------------------
std::shared_ptr<IndexBuffer> indexBuffer = std::make_shared<IndexBuffer>(indices, sizeof(indices));
m_vertexArrayTexture = std::make_shared<VertexArray>();
m_vertexArray->setIndexBuffer(indexBuffer);
float verticesTexture[] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
};
m_shader = std::make_unique<Shader>("assets/glsl/simple.vert", "assets/glsl/simple.frag");
uint32_t indicesTexture[] = {
0, 1, 2, 2, 3, 0
};
std::shared_ptr<VertexBuffer> vertexBufferTexture = std::make_shared<VertexBuffer>(verticesTexture, sizeof(verticesTexture));
vertexBufferTexture->setLayout({
{ BufferElementType::Vec3, "a_position" },
{ BufferElementType::Vec2, "a_texCoord" },
});
m_vertexArrayTexture->addVertexBuffer(vertexBufferTexture);
std::shared_ptr<IndexBuffer> indexBufferTexture = std::make_shared<IndexBuffer>(indicesTexture, sizeof(indicesTexture));
m_vertexArrayTexture->setIndexBuffer(indexBufferTexture);
// -----------------------------------------
m_shaderSimple = std::make_shared<Shader>("assets/glsl/simple.vert", "assets/glsl/simple.frag");
m_shaderTexture = std::make_shared<Shader>("assets/glsl/texture.vert", "assets/glsl/texture.frag");
m_shaderTexture->setInt("u_texture", m_texture->id());
}
Application::~Application()
@ -74,10 +111,19 @@ namespace Inferno {
Command::clearColor({ 0.2f, 0.3f, 0.3f, 1.0f });
Command::clear();
Renderer::beginScene(); // camera, lights, environment
m_shader->bind();
Renderer::submit(m_vertexArray);
Renderer::endScene();
// Renderer::beginScene(); // camera, lights, environment
// m_shaderSimple->bind();
// Renderer::submit(m_vertexArrayColor);
// m_shaderSimple->unbind();
m_shaderTexture->bind();
m_texture->bind();
Renderer::submit(m_vertexArrayTexture);
m_texture->unbind();
m_shaderTexture->unbind();
// Renderer::endScene();
m_window->update();
}

21
inferno/src/inferno/application.h

@ -6,9 +6,11 @@
namespace Inferno {
class Event;
class Texture;
class TextureManager;
class Window;
class WindowCloseEvent;
class WindowResizeEvent;
class Window;
class VertexArray;
class Shader;
@ -20,22 +22,25 @@ namespace Inferno {
void run();
void onEvent(Event &e);
bool onWindowClose(WindowCloseEvent &e);
bool onWindowResize(WindowResizeEvent &e);
void onEvent(Event& e);
bool onWindowClose(WindowCloseEvent& e);
bool onWindowResize(WindowResizeEvent& e);
// -----------------------------------------
inline Window &getWindow() { return *m_window; }
inline Window& getWindow() const { return *m_window; }
static inline Application &get() { return *s_instance; }
static inline Application& get() { return *s_instance; }
private:
std::unique_ptr<Window> m_window;
//
std::shared_ptr<VertexArray> m_vertexArray;
std::unique_ptr<Shader> m_shader;
std::shared_ptr<VertexArray> m_vertexArrayColor;
std::shared_ptr<VertexArray> m_vertexArrayTexture;
std::shared_ptr<Shader> m_shaderSimple;
std::shared_ptr<Shader> m_shaderTexture;
std::shared_ptr<Texture> m_texture;
//
static Application* s_instance;

139
inferno/src/inferno/render/texture.cpp

@ -0,0 +1,139 @@
#include <climits> // UINT_MAX
#include <memory>
#include <glad/glad.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include "inferno/assertions.h"
#include "inferno/render/texture.h"
namespace Inferno {
Texture::Texture(const std::string& path)
{
int width;
int height;
int channels;
// Load image data
stbi_set_flip_vertically_on_load(1);
unsigned char* data = stbi_load(path.c_str(), &width, &height, &channels, STBI_default);
ASSERT(data, "Failed to load image: '{}'", path);
m_width = width;
m_height = height;
if (channels == 4) {
m_internalFormat = GL_RGBA8;
m_dataFormat = GL_RGBA;
}
else if (channels == 3) {
m_internalFormat = GL_RGB8;
m_dataFormat = GL_RGB;
}
create(data);
// Clean resources
stbi_image_free(data);
}
Texture::~Texture()
{
glDeleteTextures(1, &m_id);
}
void Texture::bind() const
{
glBindTexture(GL_TEXTURE_2D, m_id);
}
void Texture::unbind() const
{
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture::create(unsigned char* data)
{
m_id = UINT_MAX;
// Create texture object
glGenTextures(1, &m_id);
// Bind texture object
glBindTexture(GL_TEXTURE_2D, m_id);
// Set unpacking of pixel data to byte-alignment,
// this prevents alignment issues when using a single byte for color
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Generate texture
glTexImage2D(
GL_TEXTURE_2D, // Texture target
0, // Midmap level, base starts at level 0
m_internalFormat, // Texture format
m_width, m_height, // Image width/height
0, // Always 0 (legacy)
m_dataFormat, // Texture source format
GL_UNSIGNED_BYTE, // Texture source datatype
data); // Image data
// Set the texture wrapping / filtering options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // X
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Y
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Minify
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Magnify
// Automatically generate all mipmap levels
glGenerateMipmap(GL_TEXTURE_2D);
// Unbind texture object
glBindTexture(GL_TEXTURE_2D, 0);
}
// -----------------------------------------
void TextureManager::add(const std::string& path, const std::shared_ptr<Texture>& texture)
{
// Construct (key, value) pair and insert it into the unordered_map
m_textureList.emplace(path, texture);
}
std::shared_ptr<Texture> TextureManager::load(const std::string& path)
{
if (exists(path)) {
return get(path);
}
std::shared_ptr<Texture> texture = std::make_shared<Texture>(path);
add(path, texture);
return get(path);
}
std::shared_ptr<Texture> TextureManager::get(const std::string& path)
{
return exists(path) ? m_textureList.at(path) : nullptr;
}
bool TextureManager::exists(const std::string& path)
{
return m_textureList.find(path) != m_textureList.end();
}
void TextureManager::remove(const std::string& path)
{
if (exists(path)) {
m_textureList.erase(path);
}
}
void TextureManager::remove(const std::shared_ptr<Texture>& texture)
{
if (exists(texture->path())) {
m_textureList.erase(texture->path());
}
}
}

56
inferno/src/inferno/render/texture.h

@ -0,0 +1,56 @@
#ifndef TEXTURE_H
#define TEXTURE_H
#include <cstdint> // std::uint32_t
#include <memory> // std::shared_ptr
#include <string> // std::string
#include <unordered_map> // std::unordered_map
namespace Inferno {
class Texture {
public:
Texture(const std::string& path);
virtual ~Texture();
void bind() const;
void unbind() const;
inline std::string path() const { return m_path; }
inline uint32_t width() const { return m_width; }
inline uint32_t height() const { return m_height; }
inline uint32_t id() const { return m_id; }
inline uint32_t internalFormat() const { return m_internalFormat; }
inline uint32_t dataFormat() const { return m_dataFormat; }
protected:
void create(unsigned char* data);
private:
std::string m_path;
uint32_t m_width;
uint32_t m_height;
uint32_t m_id;
uint32_t m_internalFormat;
uint32_t m_dataFormat;
};
// -----------------------------------------
class TextureManager {
public:
void add(const std::string& path, const std::shared_ptr<Texture>& texture);
std::shared_ptr<Texture> load(const std::string& path);
std::shared_ptr<Texture> get(const std::string& path);
bool exists(const std::string& path);
void remove(const std::string& path);
void remove(const std::shared_ptr<Texture>& texture);
private:
std::unordered_map<std::string, std::shared_ptr<Texture>> m_textureList;
};
}
#endif // TEXTURE_H
Loading…
Cancel
Save