add texture

This commit is contained in:
jiegeaiai 2024-12-02 01:31:51 +08:00
parent 61b9c17426
commit 0e8879d543
8 changed files with 166 additions and 29 deletions

View File

@ -1,7 +1,18 @@
#include "ImageBuffer.h" #include "ImageBuffer.h"
#include "Texture2D.h"
#include "Core/Thread/ScopeLock.h" #include "Core/Thread/ScopeLock.h"
ImageBuffer* Singleton<ImageBuffer>::instance_ = nullptr;
bool ImageBuffer::Initialize() {
return true;
}
void ImageBuffer::Uninitialize() {
}
void ImageBuffer::PushImage(ImageBuffer::IBType type, std::vector<unsigned char> data, void ImageBuffer::PushImage(ImageBuffer::IBType type, std::vector<unsigned char> data,
uint32 width, uint32 height, uint32 comp) { uint32 width, uint32 height, uint32 comp) {
switch (type) { switch (type) {
@ -13,12 +24,30 @@ void ImageBuffer::PushImage(ImageBuffer::IBType type, std::vector<unsigned char>
} }
} }
void ImageBuffer::PushBackgroundImage(std::vector<uint8> data, uint32 width, uint32 height, uint32 comp) { void ImageBuffer::Update(IBType type, Texture2D* texture) {
ScopeLock<CriticalSection> lock(&cs_); switch (type) {
if (background_.size() >= 10) { case ImageBuffer::IBType::Background:
background_.pop(); UpdateBackground(texture);
break;
default:
break;
}
} }
Image newImage{ std::move(data), width, height, comp }; void ImageBuffer::PushBackgroundImage(std::vector<uint8> data, uint32 width, uint32 height, uint32 comp) {
background_.push(std::move(newImage)); ScopeLock<CriticalSection> lock(&cs_);
background_.data = std::move(data);
background_.width = width;
background_.height = height;
background_.comp = comp;
}
void ImageBuffer::UpdateBackground(Texture2D* texture) {
if (background_.data.empty()) {
return;
}
ScopeLock<CriticalSection> lock(&cs_);
texture->Update(background_.width, background_.height, background_.comp, background_.data.data());
} }

View File

@ -19,11 +19,15 @@ public:
ImageBuffer(const ImageBuffer&) = delete; ImageBuffer(const ImageBuffer&) = delete;
ImageBuffer& operator=(const ImageBuffer&) = delete; ImageBuffer& operator=(const ImageBuffer&) = delete;
bool Initialize() override;
void Uninitialize() override;
void PushImage(IBType type, std::vector<uint8> data, uint32 width, uint32 height, uint32 comp); void PushImage(IBType type, std::vector<uint8> data, uint32 width, uint32 height, uint32 comp);
void Update(IBType type, class Texture2D* texture);
private: private:
void PushBackgroundImage(std::vector<uint8> data, uint32 width, uint32 height, uint32 comp); void PushBackgroundImage(std::vector<uint8> data, uint32 width, uint32 height, uint32 comp);
void UpdateBackground(class Texture2D* texture);
private: private:
struct Image { struct Image {
std::vector<uint8> data; std::vector<uint8> data;
@ -32,7 +36,7 @@ private:
uint32 comp; uint32 comp;
}; };
CriticalSection cs_; CriticalSection cs_;
std::queue<Image> background_; Image background_;
}; };

View File

@ -7,6 +7,7 @@
#include "Core/Core.h" #include "Core/Core.h"
#include "Ipc/ipclib.h" #include "Ipc/ipclib.h"
#include "ImageBuffer.h"
IpcMoudle* Singleton<IpcMoudle>::instance_ = nullptr; IpcMoudle* Singleton<IpcMoudle>::instance_ = nullptr;
@ -34,8 +35,10 @@ void OnParseImageData(const char* data, size_t size) {
// Extract image bytes // Extract image bytes
const char* img_bytes = data + 13; const char* img_bytes = data + 13;
size_t img_size = size - 13; size_t img_size = size - 13;
std::vector<uint8> 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 // Further processing of img_bytes can be done here
} }

View File

@ -10,12 +10,15 @@
#include "Core/Logger.h" #include "Core/Logger.h"
#include "Ipc/IpcMoudle.h" #include "Ipc/IpcMoudle.h"
#include "ImageBuffer.h"
#include "shader_s.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) { static int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) {
Logger::Init(); Logger::Init();
IpcMoudle::Init(); IpcMoudle::Init();
ImageBuffer::Init();
auto glfwErrorCallback = [](int error, const char* description) { auto glfwErrorCallback = [](int error, const char* description) {
ERRORLOG("code={}, description={}", error, 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. // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0); glBindVertexArray(0);
unsigned int texture; Texture2D background;
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
int width, height, nrChannels; 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. // 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); stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load("./data/background/background.jpg", &width, &height, &nrChannels, 0); unsigned char* data = stbi_load("./data/background/background.jpg", &width, &height, &nrChannels, 0);
if (data) { if (data) {
if (nrChannels == 3) { background.Create(width, height, nrChannels, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); background.Update(width, height, nrChannels, 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);
} else { } else {
std::cout << "Failed to load texture" << std::endl; std::cout << "Failed to load texture" << std::endl;
} }
stbi_image_free(data); stbi_image_free(data);
Texture2D huaman;
huaman.Create(1920, 1080, 4, nullptr);
Shader shader("./data/shader/texture.vs", "./data/shader/texture.fs"); Shader shader("./data/shader/texture.vs", "./data/shader/texture.fs");
shader.use();
shader.setInt("background", 0);
shader.setInt("human", 1);
while (!glfwWindowShouldClose(window)) { 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)); 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); projection = glm::perspective(glm::radians(60.f), ratio, 1.f, 1000.f);
glBindTexture(GL_TEXTURE_2D, texture); ImageBuffer::Get()->Update(ImageBuffer::IBType::Background, &huaman);
shader.use();
glBindVertexArray(VAO); glBindVertexArray(VAO);
shader.use();
background.Active(0);
huaman.Active(1);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window); 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 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); //glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwDestroyWindow(window); glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();
ImageBuffer::Shotdown();
IpcMoudle::Shotdown(); IpcMoudle::Shotdown();
Logger::Shotdown(); Logger::Shotdown();
return 0; return 0;

View File

@ -1,7 +1,15 @@
#pragma once #pragma once
//#include <glad/glad.h> //#include <glad/glad.h>
#include "Core/Logger.h"
#define GLEW_STATIC #define GLEW_STATIC
#include <GL/glew.h> #include <GL/glew.h>
#include <glfw/glfw3.h> #include <glfw/glfw3.h>
#define __CHECK_GL_ERROR__ { \
auto gl_error_code=glGetError();\
if(gl_error_code!=GL_NO_ERROR){\
ERRORLOG("gl_error_code: {}", static_cast<int>(gl_error_code));\
}\
}

75
src/Texture2D.cpp Normal file
View File

@ -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_);
}

20
src/Texture2D.h Normal file
View File

@ -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 };
};

View File

@ -1,9 +1,7 @@
#ifndef SHADER_H #ifndef SHADER_H
#define SHADER_H #define SHADER_H
#define GLEW_STATIC #include "RHI/OpenglDrv/gl.h"
#include <GL/glew.h>
#include <glfw/glfw3.h>
#include <string> #include <string>
#include <fstream> #include <fstream>