diff --git a/AimGL/CMakeSettings.json b/AimGL/CMakeSettings.json new file mode 100644 index 0000000..0c5fbf9 --- /dev/null +++ b/AimGL/CMakeSettings.json @@ -0,0 +1,27 @@ +{ + "configurations": [ + { + "name": "x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ "msvc_x64_x64" ], + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "" + }, + { + "name": "x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "buildRoot": "${projectDir}\\out\\build\\${name}", + "installRoot": "${projectDir}\\out\\install\\${name}", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "inheritEnvironments": [ "msvc_x64_x64" ], + "variables": [] + } + ] +} \ No newline at end of file diff --git a/AimGL/resources/Shaders/Graphics/Sprite.fs b/AimGL/resources/Shaders/Graphics/Sprite.fs new file mode 100644 index 0000000..694d69e --- /dev/null +++ b/AimGL/resources/Shaders/Graphics/Sprite.fs @@ -0,0 +1,15 @@ +#version 330 core + +in vec2 TexCoords; +out vec4 color; + +uniform sampler2D spriteTexture; + +void main() +{ + color = texture(spriteTexture, TexCoords); + // You might want to handle alpha values (like alpha blending, discarding fragments, etc.) + // Example: + if(color.a < 0.1) + discard; +} \ No newline at end of file diff --git a/AimGL/resources/Shaders/Graphics/Sprite.vs b/AimGL/resources/Shaders/Graphics/Sprite.vs new file mode 100644 index 0000000..e69de29 diff --git a/AimGL/resources/Shaders/basic.fs b/AimGL/resources/Shaders/basic.fs index 8379ff8..a081fad 100644 --- a/AimGL/resources/Shaders/basic.fs +++ b/AimGL/resources/Shaders/basic.fs @@ -1,7 +1,12 @@ #version 330 core out vec4 FragColor; + +in vec3 ourColor; +in vec2 TexCoord; + +uniform sampler2D ourTexture; void main() { - FragColor = vec4(0.5,0.5,0.1,1); -} \ No newline at end of file + FragColor = texture(ourTexture, TexCoord); +} \ No newline at end of file diff --git a/AimGL/resources/Shaders/basic.vs b/AimGL/resources/Shaders/basic.vs index cdd6dd3..311ec24 100644 --- a/AimGL/resources/Shaders/basic.vs +++ b/AimGL/resources/Shaders/basic.vs @@ -1,7 +1,14 @@ #version 330 core layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aColor; +layout (location = 2) in vec2 aTexCoord; + +out vec3 ourColor; +out vec2 TexCoord; void main() { - gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + gl_Position = vec4(aPos, 1.0); + ourColor = aColor; + TexCoord = aTexCoord; } \ No newline at end of file diff --git a/AimGL/src/CMakeLists.txt b/AimGL/src/CMakeLists.txt index 3aaf340..bca4bbe 100644 --- a/AimGL/src/CMakeLists.txt +++ b/AimGL/src/CMakeLists.txt @@ -14,11 +14,18 @@ target_precompile_headers(AimGLSrc PUBLIC pch.h) set(CUSTOM_INCLUDES_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_includes) file(MAKE_DIRECTORY ${CUSTOM_INCLUDES_DIR}) -configure_file( - ${FETCHCONTENT_BASE_DIR}/minitrace-src/minitrace.h +set(CUSTOM_INCLUDES + ${FETCHCONTENT_BASE_DIR}/minitrace-src/minitrace.h + ${FETCHCONTENT_BASE_DIR}/stb-src/stb_image.h +) + +foreach(HEADER ${CUSTOM_INCLUDES}) + configure_file( + ${HEADER} ${CUSTOM_INCLUDES_DIR} COPYONLY -) + ) +endforeach() target_include_directories(AimGLSrc PUBLIC ${FETCHCONTENT_BASE_DIR}/glew-src/include diff --git a/AimGL/src/CMakeLists_Sources.txt b/AimGL/src/CMakeLists_Sources.txt index a589e9c..1337f83 100644 --- a/AimGL/src/CMakeLists_Sources.txt +++ b/AimGL/src/CMakeLists_Sources.txt @@ -10,6 +10,8 @@ set(PROJECT_SOURCES Renderer3D/VertexArray.cpp Renderer3D/VertexBuffer.cpp Renderer3D/OpenglUtils.cpp + Renderer3D/Texture.cpp + Renderer3D/Sprite.cpp States/State.cpp States/StateStack.cpp States/CustomStates/SampleState.cpp diff --git a/AimGL/src/Game.cpp b/AimGL/src/Game.cpp index 9daa61a..f4a9fb5 100644 --- a/AimGL/src/Game.cpp +++ b/AimGL/src/Game.cpp @@ -59,6 +59,9 @@ Game::Game() throw std::runtime_error("Failed to initialize GLEW"); } + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Setup all application-flow states mAppStack.saveState(State_ID::SampleState, *mGameWindow); diff --git a/AimGL/src/Renderer3D/Sprite.cpp b/AimGL/src/Renderer3D/Sprite.cpp new file mode 100644 index 0000000..d368085 --- /dev/null +++ b/AimGL/src/Renderer3D/Sprite.cpp @@ -0,0 +1,2 @@ +#include "Sprite.h" +#include "pch.h" \ No newline at end of file diff --git a/AimGL/src/Renderer3D/Sprite.h b/AimGL/src/Renderer3D/Sprite.h new file mode 100644 index 0000000..56cf1d8 --- /dev/null +++ b/AimGL/src/Renderer3D/Sprite.h @@ -0,0 +1,80 @@ +#pragma once +#include "BufferLayout.h" +#include "Shader.h" +#include "Texture.h" +#include "VertexArray.h" +#include "VertexBuffer.h" + +class Sprite +{ +public: + Sprite(const std::string& texturePath) + : position(0.0f) + , scale(1.0f) + , mTexture(texturePath) + , mShader{{ShaderType::VertexShader, "resources/Shaders/basic.vs"}, + {ShaderType::FragmentShader, "resources/Shaders/basic.fs"}} + { + float vertices[] = { + // Positions // Texture Coords + 0.0f, 1.0f, 0.0f, 1.0f,// + 1.0f, 0.0f, 1.0f, 0.0f,// + 0.0f, 0.0f, 0.0f, 0.0f,// + + 0.0f, 1.0f, 0.0f, 1.0f,// + 1.0f, 1.0f, 1.0f, 1.0f,// + 1.0f, 0.0f, 1.0f, 0.0f // + }; + + unsigned int indices[] = { + // note that we start from 0! + 0, 1, 3,// first Triangle + 1, 2, 3 // second Triangle + }; + + // Initialize VAO and VBO (as before) + mVBO.setBuffer(vertices, sizeof(vertices)); + + mVAO.bind(); + mVBO.bind(); + mBufferLayout.push(2); + mBufferLayout.push(2); + mVAO.setBuffer(mVBO, mBufferLayout); + mVAO.unbind(); + } + + void Draw() + { + // Prepare transformations + mShader.bind(); + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, glm::vec3(position, 0.0f)); + model = glm::scale(model, glm::vec3(scale, 1.0f)); + mShader.set("model", model); + + mTexture.bind(0); + + mVAO.bind(); + glDrawArrays(GL_TRIANGLES, 0, 6); + mVAO.unbind(); + } + + void setPosition(const glm::vec2& newPosition) + { + position = newPosition; + } + + void setScale(const glm::vec2& newScale) + { + scale = newScale; + } + +private: + VertexArray mVAO; + VertexBuffer mVBO; + Texture mTexture; + Shader mShader; + BufferLayout mBufferLayout; + glm::vec2 position; + glm::vec2 scale; +}; \ No newline at end of file diff --git a/AimGL/src/Renderer3D/Texture.cpp b/AimGL/src/Renderer3D/Texture.cpp new file mode 100644 index 0000000..f80fa27 --- /dev/null +++ b/AimGL/src/Renderer3D/Texture.cpp @@ -0,0 +1,70 @@ +#include "Texture.h" + +#include "Renderer3D/OpenglUtils.h" + +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +Texture::Texture(const std::string& path) + : mTextureId(0) + , mFilePath(path) + , mData(nullptr) + , mWidth(0) + , mHeight(0) + , nrChannels(0) +{ + stbi_set_flip_vertically_on_load(true); + mData = stbi_load(path.c_str(), &mWidth, &mHeight, &nrChannels, 0); + GLCall(glGenTextures(1, &mTextureId)); + GLCall(glBindTexture(GL_TEXTURE_2D, mTextureId)); + + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); + + if (mData) + { + GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, + GL_UNSIGNED_BYTE, mData)); + GLCall(glGenerateMipmap(GL_TEXTURE_2D)); + mAspectRatio = static_cast(mWidth) / static_cast(mHeight); + unbind(); + } + else + { + spdlog::error("Failed to load a texture: {}", path); + } + stbi_image_free(mData); +}; + +Texture::~Texture() +{ + GLCall(glDeleteTextures(1, &mTextureId)); +} + +void Texture::bind(unsigned int slot) const +{ + GLCall(glActiveTexture(GL_TEXTURE0 + slot)); + GLCall(glBindTexture(GL_TEXTURE_2D, mTextureId)); +} + +void Texture::unbind() const +{ + GLCall(glBindTexture(GL_TEXTURE_2D, 0)); +} + +int Texture::width() const +{ + return mWidth; +} + +int Texture::height() const +{ + return mHeight; +} + +float Texture::aspectRatio() const +{ + return mAspectRatio; +} diff --git a/AimGL/src/Renderer3D/Texture.h b/AimGL/src/Renderer3D/Texture.h index 300fb2b..ee68705 100644 --- a/AimGL/src/Renderer3D/Texture.h +++ b/AimGL/src/Renderer3D/Texture.h @@ -1,6 +1,22 @@ #pragma once - class Texture { +public: + Texture(const std::string& path); + ~Texture(); + + void bind(unsigned int slot = 0) const; + void unbind() const; + + inline int width() const; + inline int height() const; + inline float aspectRatio() const; + +private: + unsigned int mTextureId; + std::string mFilePath; + unsigned char* mData; + float mAspectRatio; + int mWidth, mHeight, nrChannels; }; \ No newline at end of file diff --git a/AimGL/src/States/CustomStates/SampleState.cpp b/AimGL/src/States/CustomStates/SampleState.cpp index 6f2e2db..5dc4cc5 100644 --- a/AimGL/src/States/CustomStates/SampleState.cpp +++ b/AimGL/src/States/CustomStates/SampleState.cpp @@ -1,12 +1,14 @@ #include "SampleState.h" #include "pch.h" -float verticestest[] = { - 0.5f, 0.5f, 0.0f,// top right - 0.5f, -0.5f, 0.0f,// bottom right - -0.5f, -0.5f, 0.0f,// bottom left - -0.5f, 0.5f, 0.0f // top left +float vertices[] = { + // positions // colors // texture coords + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,// top right + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,// bottom right + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,// bottom left + -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left }; + unsigned int indicestest[] = { // note that we start from 0! 0, 1, 3,// first Triangle @@ -15,18 +17,22 @@ unsigned int indicestest[] = { SampleState::SampleState(StateStack& stack, sf::Window& window) : State(stack) + , mLogo("resources/Textures/logo.png") , mShader{{ShaderType::VertexShader, "resources/Shaders/basic.vs"}, {ShaderType::FragmentShader, "resources/Shaders/basic.fs"}} { - mVbo.setBuffer(verticestest, sizeof(verticestest)); + mVbo.setBuffer(vertices, sizeof(vertices)); mEbo.setBuffer(indicestest, sizeof(indicestest)); mBufferLayout.push(3); + mBufferLayout.push(3); + mBufferLayout.push(2); mVao.setBuffer(mVbo, mBufferLayout); } void SampleState::draw(sf::Window& target) const { MTR_SCOPE("SampleState", "SampleState::draw"); + mLogo.bind(0); render3D.draw(mVao, mEbo, mShader); } diff --git a/AimGL/vendor/CMakeLists.txt b/AimGL/vendor/CMakeLists.txt index 18f1951..966fd53 100644 --- a/AimGL/vendor/CMakeLists.txt +++ b/AimGL/vendor/CMakeLists.txt @@ -9,4 +9,5 @@ add_subdirectory(glew) add_subdirectory(spdlog) add_subdirectory(result) add_subdirectory(entt) -add_subdirectory(minitrace) \ No newline at end of file +add_subdirectory(minitrace) +add_subdirectory(stb) \ No newline at end of file diff --git a/AimGL/vendor/stb/CMakeLists.txt b/AimGL/vendor/stb/CMakeLists.txt new file mode 100644 index 0000000..f455400 --- /dev/null +++ b/AimGL/vendor/stb/CMakeLists.txt @@ -0,0 +1,10 @@ +message(STATUS "Fetching stb...") + +FetchContent_Declare( + stb + GIT_REPOSITORY https://github.com/nothings/stb + GIT_TAG beebb24b945efdea3b9bba23affb8eb3ba8982e7 +) +FetchContent_MakeAvailable(stb) + +message(STATUS "stb Fetched!") \ No newline at end of file