Add backends

- Renamed GfxOpenGL to GfxOPenGL2
- Added GfxOpenGL3 backend for OpenGL 3.3+
- Added WIP DirectX9 backend
- Added structure for Citro3D
- Added linear Allocator
This commit is contained in:
2026-03-17 16:47:19 +01:00
parent fe9194b907
commit d4c59e5b61
25 changed files with 1109 additions and 188 deletions

View File

@@ -0,0 +1,69 @@
// Well yes, i finally try it
#include <pd_system/gfx_citro3d.hpp>
#if defined(PD_ENABLE_CITRO3D) // && defined(__3DS__)
#include <3ds.h>
#include <citro3d.h>
#include <pd/drivers/drivers.hpp>
namespace PD {
struct GfxCitro3D::Impl {};
void GfxCitro3D::SysInit() {
if (impl) return;
PDLOG("GfxCitro3D::SysInit();");
impl = new Impl();
}
void GfxCitro3D::SysDeinit() {
if (!impl) return;
delete impl;
impl = nullptr;
PDLOG("GfxCitro3D::SysDeinit()");
}
void GfxCitro3D::Submit(size_t count, size_t start) {
if (!impl) return;
}
void GfxCitro3D::BindTexture(TextureID id) {
if (!impl) return;
}
void GfxCitro3D::SysReset() {
if (!impl) return;
}
TextureID GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
if (!impl) return 0;
return 0;
}
void GfxCitro3D::DeleteTexture(const TextureID& tex) {
if (!tex) return;
}
} // namespace PD
#else
namespace PD {
void GfxCitro3D::SysInit() {
PDLOG(
"GfxCitro3D::SysInit: Citro3D Driver is not included in "
"palladium-system");
}
void GfxCitro3D::SysDeinit() {}
void GfxCitro3D::Submit(size_t count, size_t start) {}
void GfxCitro3D::BindTexture(TextureID id) {}
void GfxCitro3D::SysReset() {}
TextureID GfxCitro3D::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
}
void GfxCitro3D::DeleteTexture(const TextureID& tex) {}
} // namespace PD
#endif

View File

@@ -0,0 +1,267 @@
// Well yes, i finally try it
#include <pd_system/gfx_directx9.hpp>
// Sicher ist sicher
#if defined(PD_ENABLE_DIRECTX9) && defined(_WIN32)
#include <d3d9.h>
#include <d3dcompiler.h>
#include <pd/drivers/drivers.hpp>
namespace PD {
static const char* g_vsCode = R"(
float4x4 projection;
struct VS_IN {
float2 pos : POSITION0;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
struct VS_OUT {
float4 pos : POSITION0;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
VS_OUT main(VS_IN input) {
VS_OUT o;
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
o.uv = input.uv;
o.col = input.col;
return o;
}
)";
static const char* g_psCode = R"(
sampler2D tex : register(s0);
bool alfa;
struct PS_IN {
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
float4 main(PS_IN input) : COLOR0 {
float4 tc = tex2D(tex, input.uv);
if (alfa)
return float4(input.col.rgb, tc.a * input.col.a);
else
return tc * input.col;
}
)";
struct GfxDirectX9::Impl {
IDirect3DDevice9* Device = nullptr;
IDirect3DVertexBuffer9* VBO = nullptr;
IDirect3DIndexBuffer9* IBO = nullptr;
IDirect3DVertexDeclaration9* Decl = nullptr;
IDirect3DVertexShader9* VS = nullptr;
IDirect3DPixelShader9* FS = nullptr;
IDirect3DTexture9* CurrentTex = nullptr;
};
void GfxDirectX9::SysInit() {
if (impl) return;
PDLOG("GfxDirectX9::SysInit();");
impl = new Impl();
impl->Device = (IDirect3DDevice9*)pDevice;
if (impl->Device) {
D3DVERTEXELEMENT9 elements[]{
{0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,
0},
{0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,
0},
{0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,
0},
D3DDECL_END()};
impl->Device->CreateVertexDeclaration(elements, &impl->Decl);
impl->Device->CreateVertexBuffer(
GfxDirectX9Config::NumVertices * sizeof(PD::Li::Vertex),
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &impl->VBO,
nullptr);
impl->Device->CreateIndexBuffer(GfxDirectX9Config::NumIndices * sizeof(u16),
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_DEFAULT, &impl->IBO,
nullptr);
ID3DBlob* vsBlob = nullptr;
ID3DBlob* errBlob = nullptr;
HRESULT hr = D3DCompile(g_vsCode, strlen(g_vsCode), nullptr, nullptr,
nullptr, "main", "vs_2_0", 0, 0, &vsBlob, &errBlob);
if (FAILED(hr)) {
PDLOG("Vertex Shader compile error: {}",
errBlob ? (char*)errBlob->GetBufferPointer() : "");
} else {
impl->Device->CreateVertexShader((DWORD*)vsBlob->GetBufferPointer(),
&impl->VS);
}
if (vsBlob) vsBlob->Release();
if (errBlob) errBlob->Release();
ID3DBlob* psBlob = nullptr;
errBlob = nullptr;
hr = D3DCompile(g_psCode, strlen(g_psCode), nullptr, nullptr, nullptr,
"main", "ps_2_0", 0, 0, &psBlob, &errBlob);
if (FAILED(hr)) {
PDLOG("Pixel Shader compile error: {}",
errBlob ? (char*)errBlob->GetBufferPointer() : "");
} else {
impl->Device->CreatePixelShader((DWORD*)psBlob->GetBufferPointer(),
&impl->FS);
}
if (psBlob) psBlob->Release();
if (errBlob) errBlob->Release();
} else {
PDLOG(
"GfxDirectX9::SysInit Error: pDevice is not set!\nYOu need to include "
"your D3D9 Device as "
"folowing:\nPD::Gfx::UseDriver<PD::GfxDirectX9>(D3D9Device);");
}
}
void GfxDirectX9::SysDeinit() {
if (!impl || !impl->Device) return;
if (impl->VBO) impl->VBO->Release();
if (impl->IBO) impl->IBO->Release();
if (impl->Decl) impl->Decl->Release();
if (impl->VS) impl->VS->Release();
if (impl->FS) impl->FS->Release();
delete impl;
impl = nullptr;
PDLOG("GfxDirectX9::SysDeinit()");
}
void GfxDirectX9::Submit(size_t count, size_t start) {
if (!impl || !impl->Device || !impl->VBO || !impl->IBO) return;
impl->Device->SetVertexShaderConstantF(
0, reinterpret_cast<const float*>(&Projection), 4);
void* vptr;
impl->VBO->Lock(0, 0, &vptr, D3DLOCK_DISCARD);
memcpy(vptr, GetVertexBufPtr(0), CurrentVertex * sizeof(PD::Li::Vertex));
impl->VBO->Unlock();
void* iptr;
impl->IBO->Lock(0, 0, &iptr, D3DLOCK_DISCARD);
memcpy(iptr, GetIndexBufPtr(0), CurrentIndex * sizeof(u16));
impl->IBO->Unlock();
impl->Device->SetStreamSource(0, impl->VBO, 0, sizeof(PD::Li::Vertex));
impl->Device->SetIndices(impl->IBO);
impl->Device->SetVertexDeclaration(impl->Decl);
impl->Device->SetVertexShader(impl->VS);
impl->Device->SetPixelShader(impl->FS);
impl->Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, CurrentVertex,
start, count / 3);
}
void GfxDirectX9::BindTexture(TextureID id) {
if (!impl || !impl->Device) return;
impl->CurrentTex = (IDirect3DTexture9*)id;
impl->Device->SetTexture(0, impl->CurrentTex);
bool a8 = false;
if (impl->CurrentTex) {
D3DSURFACE_DESC desc;
impl->CurrentTex->GetLevelDesc(0, &desc);
a8 = (desc.Format == D3DFMT_A8);
}
float v = a8 ? 1.0f : 0.0f;
impl->Device->SetPixelShaderConstantF(0, &v, 1);
}
void GfxDirectX9::SysReset() {
if (!impl || !impl->Device) return;
impl->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
impl->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
impl->Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
}
TextureID GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
if (!impl || !impl->Device) return 0;
IDirect3DTexture9* tex = nullptr;
D3DFORMAT fmt = D3DFMT_A8R8G8B8;
if (type == TextureFormat::RGB24)
fmt = D3DFMT_X8R8G8B8;
else if (type == TextureFormat::A8)
fmt = D3DFMT_A8;
HRESULT hr = impl->Device->CreateTexture(w, h, 1, 0, fmt, D3DPOOL_MANAGED,
&tex, nullptr);
if (FAILED(hr) || !tex) return 0;
D3DLOCKED_RECT rect;
tex->LockRect(0, &rect, nullptr, 0);
if (type == TextureFormat::RGB24) {
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
for (int y = 0; y < h; ++y) {
u32* dst = reinterpret_cast<u32*>(dstRow);
for (int x = 0; x < w; ++x) {
u8 r = pixels[(y * w + x) * 3 + 0];
u8 g = pixels[(y * w + x) * 3 + 1];
u8 b = pixels[(y * w + x) * 3 + 2];
dst[x] = (0xFF << 24) | (r << 16) | (g << 8) | b; // X8R8G8B8
}
dstRow += rect.Pitch;
}
} else if (type == TextureFormat::RGBA32) {
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
for (int y = 0; y < h; ++y) {
u32* dst = reinterpret_cast<u32*>(dstRow);
for (int x = 0; x < w; ++x) {
u8 r = pixels[(y * w + x) * 4 + 0];
u8 g = pixels[(y * w + x) * 4 + 1];
u8 b = pixels[(y * w + x) * 4 + 2];
u8 a = pixels[(y * w + x) * 4 + 3];
dst[x] = (a << 24) | (r << 16) | (g << 8) | b; // A8R8G8B8
}
dstRow += rect.Pitch;
}
} else if (type == TextureFormat::A8) {
u8* dstRow = reinterpret_cast<u8*>(rect.pBits);
for (int y = 0; y < h; ++y) {
memcpy(dstRow, &pixels[y * w], w);
dstRow += rect.Pitch;
}
}
tex->UnlockRect(0);
PDLOG("GfxDirectX9::LoadTexture -> [{}] 0x{:X}, [{}, {}]", PD::ivec2(w, h),
(TextureID)tex, type, filter);
return (TextureID)tex;
}
void GfxDirectX9::DeleteTexture(const TextureID& tex) {
if (!tex) return;
IDirect3DTexture9* t = (IDirect3DTexture9*)tex;
t->Release();
}
} // namespace PD
#else
namespace PD {
void GfxDirectX9::SysInit() {
PDLOG(
"GfxDirectX9::SysInit: DirectX9 Driver is not included in "
"palladium-system");
}
void GfxDirectX9::SysDeinit() {}
void GfxDirectX9::Submit(size_t count, size_t start) {}
void GfxDirectX9::BindTexture(TextureID id) {}
void GfxDirectX9::SysReset() {}
TextureID GfxDirectX9::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
}
void GfxDirectX9::DeleteTexture(const TextureID& tex) {}
} // namespace PD
#endif

View File

@@ -1,56 +1,13 @@
#include <pd_system/gfx_opengl2.hpp>
#if defined(PD_ENABLE_OPENGL2)
#include <glad/glad.h>
#include <gfx_opengl.hpp>
#include "pd/common.hpp"
#include "pd/drivers/gfx.hpp"
#include <pd/drivers/drivers.hpp>
#include <pd_system/gl-helper.hpp>
namespace PD {
GLuint compileShader(const std::string& source, GLenum type) {
GLuint shader = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, nullptr, infoLog);
std::cerr << "Shader Compilation Error: " << infoLog << std::endl;
}
return shader;
}
GLuint createShaderProgram(const std::string& vertexShaderSource,
const std::string& fragmentShaderSource) {
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
GLuint fragmentShader =
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
GLint success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
std::cerr << "Shader Program Linking Error: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
if (success) PDLOG("Shader [{}] compiled sucessfully", shaderProgram);
return shaderProgram;
}
const char* vertex_shader = R"(
const char* GfxOpenGL2::pVertCode = R"(
#version 120
attribute vec2 pos;
@@ -71,7 +28,7 @@ const char* vertex_shader = R"(
}
)";
const char* frag_shader = R"(
const char* GfxOpenGL2::pFragCode = R"(
#version 120
varying vec2 oUV;
@@ -90,7 +47,7 @@ const char* frag_shader = R"(
}
)";
void GfxOpenGL::pSetupShaderAttribs(u32 shader) {
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {
GLint _pos = glGetAttribLocation(shader, "pos");
GLint _uv = glGetAttribLocation(shader, "uv");
GLint _color = glGetAttribLocation(shader, "color");
@@ -108,15 +65,15 @@ void GfxOpenGL::pSetupShaderAttribs(u32 shader) {
glEnableVertexAttribArray(_color);
}
void GfxOpenGL::SysInit() {
pShader = createShaderProgram(vertex_shader, frag_shader);
void GfxOpenGL2::SysInit() {
pShader = CreateShaderProgram(pVertCode, pFragCode);
glUseProgram(pShader);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
pSetupShaderAttribs(pShader);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
pSetupShaderAttribs(pShader);
pLocTex = glGetUniformLocation(pShader, "tex");
pLocAlfa = glGetUniformLocation(pShader, "alfa");
pLocProjection = glGetUniformLocation(pShader, "projection");
@@ -124,21 +81,20 @@ void GfxOpenGL::SysInit() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
PDLOG(
"GfxOpenGL::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
"GfxOpenGL2::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}",
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO);
}
void GfxOpenGL::SysDeinit() {
void GfxOpenGL2::SysDeinit() {
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &IBO);
PDLOG("GfxOpenGL::SysDeinit()");
PDLOG("GfxOpenGL2::SysDeinit()");
}
void GfxOpenGL::Submit(size_t count, size_t start) {
void GfxOpenGL2::Submit(size_t count, size_t start) {
BindTexture(CurrentTex);
glUseProgram(pShader);
pSetupShaderAttribs(pShader);
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
@@ -148,14 +104,17 @@ void GfxOpenGL::Submit(size_t count, size_t start) {
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT,
pSetupShaderAttribs(pShader);
GLint ibo = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
reinterpret_cast<void*>(start * sizeof(u16)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
BindTexture(0);
}
void GfxOpenGL::BindTexture(TextureID id) {
void GfxOpenGL2::BindTexture(TextureID id) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, (GLuint)id);
glUniform1i(pLocTex, 0);
@@ -164,25 +123,25 @@ void GfxOpenGL::BindTexture(TextureID id) {
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
}
void GfxOpenGL::SysReset() {
void GfxOpenGL2::SysReset() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
TextureID GfxOpenGL::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
TextureID GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
GLuint texID;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
// Set base format (Always using RGBA as base)
GLenum fmt = GL_RGBA;
/*if (type == PD::Li::Texture::Type::RGB24) {
if (type == TextureFormat::RGB24) {
fmt = GL_RGB;
} else if (type == PD::Li::Texture::Type::A8) {
} else if (type == TextureFormat::A8) {
fmt = GL_ALPHA;
}*/
}
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
pixels.data());
if (filter == TextureFilter::Linear) {
@@ -193,12 +152,33 @@ TextureID GfxOpenGL::LoadTexture(const std::vector<PD::u8>& pixels, int w,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
glBindTexture(GL_TEXTURE_2D, 0);
PDLOG("GfxOpenGL::LoadTexture -> [{}] {}", PD::ivec2(w, h), texID);
PDLOG("GfxOpenGL2::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID,
type, filter);
return texID;
}
void GfxOpenGL::DeleteTexture(const TextureID& tex) {
void GfxOpenGL2::DeleteTexture(const TextureID& tex) {
GLuint tex_ = tex;
glDeleteTextures(1, &tex_);
}
} // namespace PD
} // namespace PD
#else
namespace PD {
void GfxOpenGL2::SysInit() {
PDLOG(
"GfxOpenGL2::SysInit: OpenGL2 Driver is not included in "
"palladium-system");
}
void GfxOpenGL2::SysDeinit() {}
void GfxOpenGL2::Submit(size_t count, size_t start) {}
void GfxOpenGL2::BindTexture(TextureID id) {}
void GfxOpenGL2::SysReset() {}
TextureID GfxOpenGL2::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
}
void GfxOpenGL2::DeleteTexture(const TextureID& tex) {}
void GfxOpenGL2::pSetupShaderAttribs(u32 shader) {}
} // namespace PD
#endif

View File

@@ -0,0 +1,180 @@
#include <pd_system/gfx_opengl3.hpp>
#if defined(PD_ENABLE_OPENGL3)
#include <glad/glad.h>
#include <pd/drivers/drivers.hpp>
#include <pd_system/gl-helper.hpp>
namespace PD {
const char* GfxOpenGL3::pVertCode = R"(
#version 330 core
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 uv;
layout(location = 2) in vec4 color;
out vec2 oUV;
out vec4 oColor;
// Probably forgot about this matrix and
// searched hours for why the rendering isn't working :/
uniform mat4 projection;
void main() {
gl_Position = projection*vec4(pos, 0.0, 1.0);
oUV = uv;
oColor = color;
}
)";
const char* GfxOpenGL3::pFragCode = R"(
#version 330 core
in vec2 oUV;
in vec4 oColor;
uniform sampler2D tex;
uniform bool alfa;
out vec4 FragColor;
void main() {
vec4 tc = texture(tex, oUV);
if (alfa) {
FragColor = vec4(oColor.rgb, tc.a * oColor.a);
} else {
FragColor = tc * oColor;
}
}
)";
void GfxOpenGL3::SysInit() {
pShader = CreateShaderProgram(pVertCode, pFragCode);
glUseProgram(pShader);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, pos));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, uv));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PD::Li::Vertex),
(void*)offsetof(PD::Li::Vertex, color));
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
pLocTex = glGetUniformLocation(pShader, "tex");
pLocAlfa = glGetUniformLocation(pShader, "alfa");
pLocProjection = glGetUniformLocation(pShader, "projection");
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
PDLOG(
"GfxOpenGL3::SysInit():\n pShader = {}\n pLocTex = {}\n pLocAlfa = "
"{}\n pLocProjection = {}\n VBO = {}\n IBO = {}, VAO = {}",
pShader, pLocTex, pLocAlfa, pLocProjection, VBO, IBO, VAO);
}
void GfxOpenGL3::SysDeinit() {
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &IBO);
glDeleteVertexArrays(1, &VAO);
PDLOG("GfxOpenGL3::SysDeinit()");
}
void GfxOpenGL3::Submit(size_t count, size_t start) {
BindTexture(CurrentTex);
glUseProgram(pShader);
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
GetVertexBufPtr(0), GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(u16),
GetIndexBufPtr(0), GL_DYNAMIC_DRAW);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT,
reinterpret_cast<void*>(start * sizeof(u16)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
BindTexture(0);
}
void GfxOpenGL3::BindTexture(TextureID id) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, (GLuint)id);
glUniform1i(pLocTex, 0);
GLint fmt = 0;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
}
void GfxOpenGL3::SysReset() {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
TextureID GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
GLuint texID;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
// Set base format (Always using RGBA as base)
GLenum fmt = GL_RGBA;
if (type == TextureFormat::RGB24) {
fmt = GL_RGB;
} else if (type == TextureFormat::A8) {
fmt = GL_ALPHA;
}
glTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, fmt, GL_UNSIGNED_BYTE,
pixels.data());
if (filter == TextureFilter::Linear) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} else if (filter == TextureFilter::Nearest) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
glBindTexture(GL_TEXTURE_2D, 0);
PDLOG("GfxOpenGL3::LoadTexture -> [{}] {}, [{}, {}]", PD::ivec2(w, h), texID,
type, filter);
return texID;
}
void GfxOpenGL3::DeleteTexture(const TextureID& tex) {
GLuint tex_ = tex;
glDeleteTextures(1, &tex_);
}
} // namespace PD
#else
namespace PD {
void GfxOpenGL3::SysInit() {
PDLOG(
"GfxOpenGL3::SysInit: OpenGL3 Driver is not included in "
"palladium-system");
}
void GfxOpenGL3::SysDeinit() {}
void GfxOpenGL3::Submit(size_t count, size_t start) {}
void GfxOpenGL3::BindTexture(TextureID id) {}
void GfxOpenGL3::SysReset() {}
TextureID GfxOpenGL3::LoadTexture(const std::vector<PD::u8>& pixels, int w,
int h, TextureFormat type,
TextureFilter filter) {
return 0;
}
void GfxOpenGL3::DeleteTexture(const TextureID& tex) {}
void GfxOpenGL3::pSetupShaderAttribs(u32 shader) {}
} // namespace PD
#endif

View File

@@ -0,0 +1,46 @@
#include <glad/glad.h>
#include <iostream>
#include <pd_system/gl-helper.hpp>
namespace PD {
GLuint compileShader(const char* src, GLenum type) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
GLint success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success) {
char infoLog[512];
glGetShaderInfoLog(shader, 512, nullptr, infoLog);
std::cerr << "Shader Compilation Error: " << infoLog << std::endl;
}
return shader;
}
u32 CreateShaderProgram(const char* vert, const char* frag) {
GLuint vertexShader = compileShader(vert, GL_VERTEX_SHADER);
GLuint fragmentShader = compileShader(frag, GL_FRAGMENT_SHADER);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
GLint success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
char infoLog[512];
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
std::cerr << "Shader Program Linking Error: " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
if (success) PDLOG("Shader [{}] compiled sucessfully", shaderProgram);
return shaderProgram;
}
} // namespace PD