From 0e8879d54382c35ad8f869d0f090cd966239d0cb Mon Sep 17 00:00:00 2001 From: jiegeaiai Date: Mon, 2 Dec 2024 01:31:51 +0800 Subject: [PATCH] add texture --- src/ImageBuffer.cpp | 37 ++++++++++++++++++--- src/ImageBuffer.h | 8 +++-- src/Ipc/IpcMoudle.cpp | 5 ++- src/Main.cpp | 38 ++++++++++----------- src/RHI/OpenglDrv/gl.h | 8 +++++ src/Texture2D.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++ src/Texture2D.h | 20 +++++++++++ src/shader_s.h | 4 +-- 8 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 src/Texture2D.cpp create mode 100644 src/Texture2D.h diff --git a/src/ImageBuffer.cpp b/src/ImageBuffer.cpp index 42f42d1..4a2a5d1 100644 --- a/src/ImageBuffer.cpp +++ b/src/ImageBuffer.cpp @@ -1,7 +1,18 @@ #include "ImageBuffer.h" +#include "Texture2D.h" #include "Core/Thread/ScopeLock.h" +ImageBuffer* Singleton::instance_ = nullptr; + +bool ImageBuffer::Initialize() { + return true; +} + +void ImageBuffer::Uninitialize() { + +} + void ImageBuffer::PushImage(ImageBuffer::IBType type, std::vector data, uint32 width, uint32 height, uint32 comp) { switch (type) { @@ -13,12 +24,30 @@ void ImageBuffer::PushImage(ImageBuffer::IBType type, std::vector } } +void ImageBuffer::Update(IBType type, Texture2D* texture) { + switch (type) { + case ImageBuffer::IBType::Background: + UpdateBackground(texture); + break; + default: + break; + } +} + void ImageBuffer::PushBackgroundImage(std::vector data, uint32 width, uint32 height, uint32 comp) { ScopeLock lock(&cs_); - if (background_.size() >= 10) { - background_.pop(); + + background_.data = std::move(data); + background_.width = width; + background_.height = height; + background_.comp = comp; +} + +void ImageBuffer::UpdateBackground(Texture2D* texture) { + if (background_.data.empty()) { + return; } - Image newImage{ std::move(data), width, height, comp }; - background_.push(std::move(newImage)); + ScopeLock lock(&cs_); + texture->Update(background_.width, background_.height, background_.comp, background_.data.data()); } diff --git a/src/ImageBuffer.h b/src/ImageBuffer.h index ffe88be..6ea35e8 100644 --- a/src/ImageBuffer.h +++ b/src/ImageBuffer.h @@ -19,11 +19,15 @@ public: ImageBuffer(const ImageBuffer&) = delete; ImageBuffer& operator=(const ImageBuffer&) = delete; + bool Initialize() override; + void Uninitialize() override; + void PushImage(IBType type, std::vector data, uint32 width, uint32 height, uint32 comp); + void Update(IBType type, class Texture2D* texture); private: void PushBackgroundImage(std::vector data, uint32 width, uint32 height, uint32 comp); - + void UpdateBackground(class Texture2D* texture); private: struct Image { std::vector data; @@ -32,7 +36,7 @@ private: uint32 comp; }; CriticalSection cs_; - std::queue background_; + Image background_; }; diff --git a/src/Ipc/IpcMoudle.cpp b/src/Ipc/IpcMoudle.cpp index 4085aee..b1ed62d 100644 --- a/src/Ipc/IpcMoudle.cpp +++ b/src/Ipc/IpcMoudle.cpp @@ -7,6 +7,7 @@ #include "Core/Core.h" #include "Ipc/ipclib.h" +#include "ImageBuffer.h" IpcMoudle* Singleton::instance_ = nullptr; @@ -34,8 +35,10 @@ void OnParseImageData(const char* data, size_t size) { // Extract image bytes const char* img_bytes = data + 13; size_t img_size = size - 13; + std::vector img_data(img_size); + memcpy(img_data.data(), img_bytes, img_size); - + ImageBuffer::Get()->PushImage(ImageBuffer::IBType::Background, std::move(img_data), width, height, bit_depth); // Further processing of img_bytes can be done here } diff --git a/src/Main.cpp b/src/Main.cpp index b72462e..55f691c 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -10,12 +10,15 @@ #include "Core/Logger.h" #include "Ipc/IpcMoudle.h" +#include "ImageBuffer.h" #include "shader_s.h" +#include "Texture2D.h" static int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { Logger::Init(); IpcMoudle::Init(); + ImageBuffer::Init(); auto glfwErrorCallback = [](int error, const char* description) { ERRORLOG("code={}, description={}", error, description); }; @@ -112,33 +115,26 @@ static int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevI // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. glBindVertexArray(0); - unsigned int texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); // all upcoming GL_TEXTURE_2D operations now have effect on this texture object - // set the texture wrapping parameters - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - // set texture filtering parameters - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - // load image, create texture and generate mipmaps + Texture2D background; int width, height, nrChannels; // The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path. stbi_set_flip_vertically_on_load(true); unsigned char* data = stbi_load("./data/background/background.jpg", &width, &height, &nrChannels, 0); if (data) { - if (nrChannels == 3) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - } else if (nrChannels == 4) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - } - glGenerateMipmap(GL_TEXTURE_2D); + background.Create(width, height, nrChannels, nullptr); + background.Update(width, height, nrChannels, data); } else { std::cout << "Failed to load texture" << std::endl; } stbi_image_free(data); + Texture2D huaman; + huaman.Create(1920, 1080, 4, nullptr); + Shader shader("./data/shader/texture.vs", "./data/shader/texture.fs"); + shader.use(); + shader.setInt("background", 0); + shader.setInt("human", 1); while (!glfwWindowShouldClose(window)) { @@ -156,10 +152,13 @@ static int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevI view = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); projection = glm::perspective(glm::radians(60.f), ratio, 1.f, 1000.f); - glBindTexture(GL_TEXTURE_2D, texture); - shader.use(); + ImageBuffer::Get()->Update(ImageBuffer::IBType::Background, &huaman); glBindVertexArray(VAO); + shader.use(); + background.Active(0); + huaman.Active(1); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); @@ -168,11 +167,12 @@ static int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevI glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized //glDrawArrays(GL_TRIANGLES, 0, 6); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwDestroyWindow(window); glfwTerminate(); + ImageBuffer::Shotdown(); IpcMoudle::Shotdown(); Logger::Shotdown(); return 0; diff --git a/src/RHI/OpenglDrv/gl.h b/src/RHI/OpenglDrv/gl.h index f71cecd..e2059cc 100644 --- a/src/RHI/OpenglDrv/gl.h +++ b/src/RHI/OpenglDrv/gl.h @@ -1,7 +1,15 @@ #pragma once //#include +#include "Core/Logger.h" #define GLEW_STATIC #include #include + +#define __CHECK_GL_ERROR__ { \ + auto gl_error_code=glGetError();\ + if(gl_error_code!=GL_NO_ERROR){\ + ERRORLOG("gl_error_code: {}", static_cast(gl_error_code));\ + }\ + } diff --git a/src/Texture2D.cpp b/src/Texture2D.cpp new file mode 100644 index 0000000..5fcf167 --- /dev/null +++ b/src/Texture2D.cpp @@ -0,0 +1,75 @@ +#include "Texture2D.h" + +#include "RHI/OpenglDrv/gl.h" + + +Texture2D::Texture2D() noexcept { + glGenTextures(1, &texture_); +} + +Texture2D::~Texture2D() { + if (0 == texture_) { + return; + } + + glDeleteTextures(1, &texture_); + texture_ = 0; +} + +bool Texture2D::Create(int32 width, int32 height, int32 nrChannels, uint8* data) noexcept { + if (0 == texture_) { + return false; + } + width_ = width; + height_ = height; + channels_ = nrChannels; + GLenum format = GL_RGB; + if (nrChannels == 1) { + format = GL_RED; + } else if (nrChannels == 3) { + format = GL_RGB; + } else if (nrChannels == 4) { + format = GL_RGBA; + } + bool alloced = false; + if (nullptr == data) { + const uint32 size = width * height * nrChannels; + data = new uint8[size]; + memset(data, 0, size); + alloced = true; + } + + glBindTexture(GL_TEXTURE_2D, texture_); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); __CHECK_GL_ERROR__ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); __CHECK_GL_ERROR__ + + if (alloced) { + delete[] data; + } + + //glGenerateMipmap(GL_TEXTURE_2D); + return true; +} + +void Texture2D::Update(int32 width, int32 height, int32 channels, uint8* data) noexcept { + if (0 == texture_ || nullptr == data) { + return; + } + glBindTexture(GL_TEXTURE_2D, texture_); __CHECK_GL_ERROR__ + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); __CHECK_GL_ERROR__ + if (3 == channels){ + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); __CHECK_GL_ERROR__ + } else if (4 == channels) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); __CHECK_GL_ERROR__ + } +} + +void Texture2D::Active(int32 txture) { + if (0 == texture_) { + return; + } + + glActiveTexture(GL_TEXTURE0 + txture); + glBindTexture(GL_TEXTURE_2D, texture_); +} diff --git a/src/Texture2D.h b/src/Texture2D.h new file mode 100644 index 0000000..b565630 --- /dev/null +++ b/src/Texture2D.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Core/Core.h" + +class Texture2D { +public: + explicit Texture2D() noexcept; + ~Texture2D(); + + bool Create(int32 width, int32 height, int32 channels, uint8* data) noexcept; + void Update(int32 width, int32 height, int32 channels, uint8* data) noexcept; + void Active(int32 txture); + +private: + uint32 texture_{ 0 }; + + int32 width_{ 0 }; + int32 height_{ 0 }; + int32 channels_{ 0 }; +}; diff --git a/src/shader_s.h b/src/shader_s.h index 3536c52..bd7d80c 100644 --- a/src/shader_s.h +++ b/src/shader_s.h @@ -1,9 +1,7 @@ #ifndef SHADER_H #define SHADER_H -#define GLEW_STATIC -#include -#include +#include "RHI/OpenglDrv/gl.h" #include #include