(WIP) hardware: add render hardware interface

This commit is contained in:
Eidolon 2023-01-06 03:29:01 -06:00
parent cafe7603b8
commit 01ddbf6dcf
43 changed files with 12729 additions and 566 deletions

View file

@ -26,6 +26,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
font.c
hu_stuff.c
i_time.c
i_video_common.cpp
y_inter.c
st_stuff.c
m_aatree.c
@ -224,6 +225,9 @@ target_sources(SRB2SDL2 PRIVATE discord.c stun.c)
target_link_libraries(SRB2SDL2 PRIVATE tcbrindle::span)
target_link_libraries(SRB2SDL2 PRIVATE stb_vorbis)
target_link_libraries(SRB2SDL2 PRIVATE xmp-lite::xmp-lite)
target_link_libraries(SRB2SDL2 PRIVATE glad::glad)
target_link_libraries(SRB2SDL2 PRIVATE fmt)
target_link_libraries(SRB2SDL2 PRIVATE imgui::imgui)
set(SRB2_HAVE_THREADS ON)
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS)
@ -528,9 +532,12 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
endif()
add_subdirectory(audio)
add_subdirectory(core)
add_subdirectory(hwr2)
add_subdirectory(io)
add_subdirectory(sdl)
add_subdirectory(objects)
add_subdirectory(rhi)
add_subdirectory(tests)
add_subdirectory(menus)

3
src/core/CMakeLists.txt Normal file
View file

@ -0,0 +1,3 @@
target_sources(SRB2SDL2 PRIVATE
static_vec.hpp
)

288
src/core/static_vec.hpp Normal file
View file

@ -0,0 +1,288 @@
#ifndef __SRB2_CORE_STATIC_VEC_HPP__
#define __SRB2_CORE_STATIC_VEC_HPP__
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iterator>
#include <initializer_list>
#include <stdexcept>
#include <type_traits>
#include "../cxxutil.hpp"
namespace srb2 {
template <typename T, size_t Limit>
class StaticVec
{
std::array<T, Limit> arr_ {{}};
size_t size_ = 0;
public:
constexpr StaticVec() {}
StaticVec(const StaticVec& rhs)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = rhs.arr_[i];
}
}
StaticVec(StaticVec&& rhs) noexcept(std::is_nothrow_move_assignable_v<T>)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = std::move(rhs.arr_[i]);
}
while (rhs.size() > 0)
{
rhs.pop_back();
}
}
constexpr StaticVec(std::initializer_list<T> list) noexcept(std::is_nothrow_move_assignable_v<T>)
{
size_ = list.size();
size_t i = 0;
for (auto itr = list.begin(); itr != list.end(); itr++)
{
arr_[i] = *itr;
i++;
}
}
~StaticVec() = default;
StaticVec& operator=(const StaticVec& rhs)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = rhs.arr_[i];
}
return *this;
}
StaticVec& operator=(StaticVec&& rhs) noexcept(std::is_nothrow_move_constructible_v<T>)
{
for (size_t i = size_; i > 0; i--)
{
arr_[i] = T();
}
size_ = rhs.size();
for (size_t i = 0; i < size_; i++)
{
arr_[i] = std::move(rhs.arr_[i]);
}
while (rhs.size() > 0)
{
rhs.pop_back();
}
return *this;
}
void push_back(const T& value)
{
arr_[size_++] = value;
}
void pop_back()
{
arr_[size_--] = T();
}
void resize(size_t size, T value = T())
{
if (size >= Limit)
{
throw std::length_error("new size >= Capacity");
}
if (size == size_)
{
return;
}
else if (size < size_)
{
while (size_ > size)
{
pop_back();
}
}
else
{
while (size_ < size)
{
push_back(value);
}
}
}
constexpr T* begin() noexcept
{
return &arr_[0];
}
constexpr const T* begin() const noexcept
{
return cbegin();
}
constexpr const T* cbegin() const noexcept
{
return &arr_[0];
}
constexpr T* end() noexcept
{
return &arr_[size_];
}
constexpr const T* end() const noexcept
{
return cend();
}
constexpr const T* cend() const noexcept
{
return &arr_[size_];
}
constexpr std::reverse_iterator<T*> rbegin() noexcept
{
return &arr_[size_];
}
constexpr std::reverse_iterator<const T*> crbegin() const noexcept
{
return &arr_[size_];
}
constexpr std::reverse_iterator<T*> rend() noexcept
{
return &arr_[0];
}
constexpr std::reverse_iterator<const T*> crend() const noexcept
{
return &arr_[0];
}
constexpr bool empty() const noexcept
{
return size_ == 0;
}
constexpr size_t size() const noexcept
{
return size_;
}
constexpr size_t capacity() const noexcept
{
return Limit;
}
constexpr size_t max_size() const noexcept
{
return Limit;
}
constexpr T& operator[](size_t index) noexcept
{
return arr_[index];
}
T& at(size_t index)
{
if (index >= size_)
{
throw std::out_of_range("index >= size");
}
return this[index];
}
constexpr const T& operator[](size_t index) const noexcept
{
return arr_[index];
}
const T& at(size_t index) const
{
if (index >= size_)
{
throw std::out_of_range("index >= size");
}
return this[index];
}
T& front()
{
return *arr_[0];
}
T& back()
{
return *arr_[size_ - 1];
}
};
} // namespace srb2
template <typename T, size_t L1, size_t L2>
bool operator==(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>& rhs)
{
const size_t size = lhs.size();
if (size != rhs.size())
{
return false;
}
for (size_t i = 0; i < lhs; i++) {
if (rhs[i] != lhs[i])
{
return false;
}
}
return true;
}
template <typename T, size_t L1, size_t L2>
bool operator!=(const srb2::StaticVec<T, L1>& lhs, const srb2::StaticVec<T, L2>& rhs)
{
return !(lhs == rhs);
}
template <typename T, size_t Limit>
struct std::hash<srb2::StaticVec<T, Limit>>
{
uint64_t operator()(const srb2::StaticVec<T, Limit>& input) const
{
constexpr const uint64_t prime { 0x00000100000001B3 };
std::size_t ret { 0xcbf29ce484222325 };
for (auto itr = input.begin(); itr != input.end(); itr++)
{
ret = (ret * prime) ^ std::hash<T>(*itr);
}
return ret;
}
};
#endif // __SRB2_CORE_STATIC_VEC_HPP__

View file

@ -1115,6 +1115,7 @@ static void IdentifyVersion(void)
#define PATCHNAME "MISC_SCRIPTS.pk3"
#define UNLOCKNAME "MISC_UNLOCKS.pk3"
#define MUSICNAME "MISC_MUSIC.PK3"
#define SHADERSNAME "MISC_SHADERS.pk3"
////
#else
////
@ -1123,6 +1124,7 @@ static void IdentifyVersion(void)
#define PATCHNAME "scripts.pk3"
#define UNLOCKNAME "unlocks.pk3"
#define MUSICNAME "music.pk3"
#define SHADERSNAME "shaders.pk3"
////
#endif
////
@ -1140,6 +1142,7 @@ static void IdentifyVersion(void)
#if defined(DEVELOP) && defined(UNLOCKTESTING)
D_AddFile(startupiwads, va(pandf,srb2waddir,UNLOCKNAME));
#endif
D_AddFile(startupiwads, va(pandf,srb2waddir,SHADERSNAME));
////
#undef TEXTURESNAME
#undef MAPSNAME

8
src/hwr2/CMakeLists.txt Normal file
View file

@ -0,0 +1,8 @@
target_sources(SRB2SDL2 PRIVATE
pass_imgui.cpp
pass_imgui.hpp
pass_software.cpp
pass_software.hpp
pass.cpp
pass.hpp
)

3
src/hwr2/pass.cpp Normal file
View file

@ -0,0 +1,3 @@
#include "pass.hpp"
srb2::hwr2::Pass::~Pass() = default;

35
src/hwr2/pass.hpp Normal file
View file

@ -0,0 +1,35 @@
#ifndef __SRB2_HWR2_PASS_HPP__
#define __SRB2_HWR2_PASS_HPP__
#include "../rhi/rhi.hpp"
namespace srb2::hwr2
{
/// @brief A rendering pass which performs logic during each phase of a frame render.
/// During rendering, all registered Pass's individual stages will be run together.
struct Pass {
virtual ~Pass();
/// @brief Perform rendering logic and create necessary GPU resources.
/// @param rhi
virtual void prepass(rhi::Rhi& rhi) = 0;
/// @brief Upload contents for needed GPU resources.
/// @param rhi
/// @param ctx
virtual void transfer(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx) = 0;
/// @brief Issue draw calls.
/// @param rhi
/// @param ctx
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) = 0;
/// @brief Cleanup GPU resources. Transient resources should be cleaned up here.
/// @param rhi
virtual void postpass(rhi::Rhi& rhi) = 0;
};
} // namespace srb2::hwr2
#endif // __SRB2_HWR2_PASS_HPP__

255
src/hwr2/pass_imgui.cpp Normal file
View file

@ -0,0 +1,255 @@
#include "pass_imgui.hpp"
#include <imgui.h>
#include "../v_video.h"
using namespace srb2;
using namespace srb2::hwr2;
using namespace srb2::rhi;
static const PipelineDesc kPipelineDesc =
{
PipelineProgram::kUnshaded,
{
{
{sizeof(ImDrawVert)}
},
{
{VertexAttributeName::kPosition, 0, 0},
{VertexAttributeName::kTexCoord0, 0, 12},
{VertexAttributeName::kColor, 0, 24}
}
},
{{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
{{
SamplerName::kSampler0
}},
PipelineDepthAttachmentDesc {
PixelFormat::kDepth16,
CompareFunc::kAlways,
true
},
{
PixelFormat::kRGBA8,
BlendDesc {
BlendFactor::kSourceAlpha,
BlendFactor::kOneMinusSourceAlpha,
BlendFunction::kAdd,
BlendFactor::kOne,
BlendFactor::kOneMinusSourceAlpha,
BlendFunction::kAdd
},
{true, true, true, true}
},
PrimitiveType::kTriangles,
CullMode::kNone,
FaceWinding::kCounterClockwise,
{0.f, 0.f, 0.f, 1.f}
};
ImguiPass::~ImguiPass() = default;
void ImguiPass::prepass(Rhi& rhi)
{
if (!pipeline_)
{
pipeline_ = rhi.create_pipeline(kPipelineDesc);
}
ImGuiIO& io = ImGui::GetIO();
if (!font_atlas_)
{
unsigned char* pixels;
int width;
int height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
uint32_t uwidth = static_cast<uint32_t>(width);
uint32_t uheight = static_cast<uint32_t>(height);
font_atlas_ = rhi.create_texture({TextureFormat::kRGBA, uwidth, uheight});
io.Fonts->SetTexID(font_atlas_);
}
ImGui::Render();
ImDrawData* data = ImGui::GetDrawData();
ImVec2 clip_off(data->DisplayPos);
ImVec2 clip_scale(data->FramebufferScale);
tcb::span<ImDrawList*> draw_lists = tcb::span(data->CmdLists, data->CmdListsCount);
for (auto list : draw_lists)
{
Handle<Buffer> vbo = rhi.create_buffer(
{
static_cast<uint32_t>(list->VtxBuffer.size_in_bytes()),
BufferType::kVertexBuffer,
BufferUsage::kImmutable
}
);
Handle<Buffer> ibo = rhi.create_buffer(
{
static_cast<uint32_t>(list->IdxBuffer.size_in_bytes()),
BufferType::kIndexBuffer,
BufferUsage::kImmutable
}
);
DrawList hwr2_list;
hwr2_list.list = list;
hwr2_list.vbo = vbo;
hwr2_list.ibo = ibo;
for (auto& cmd : list->CmdBuffer)
{
if (cmd.UserCallback)
{
cmd.UserCallback(list, &cmd);
continue;
}
ImVec2 clip_min((cmd.ClipRect.x - clip_off.x) * clip_scale.x, (cmd.ClipRect.y - clip_off.y) * clip_scale.y);
ImVec2 clip_max((cmd.ClipRect.z - clip_off.x) * clip_scale.x, (cmd.ClipRect.w - clip_off.y) * clip_scale.y);
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
{
continue;
}
DrawCmd draw_cmd;
ImTextureID tex_id = cmd.GetTexID();
draw_cmd.tex = tex_id;
draw_cmd.v_offset = cmd.VtxOffset;
draw_cmd.i_offset = cmd.IdxOffset;
draw_cmd.elems = cmd.ElemCount;
draw_cmd.clip =
{
static_cast<int32_t>(clip_min.x),
static_cast<int32_t>((data->DisplaySize.y * data->FramebufferScale.y) - clip_max.y),
static_cast<uint32_t>(clip_max.x - clip_min.x),
static_cast<uint32_t>(clip_max.y - clip_min.y)
};
hwr2_list.cmds.push_back(std::move(draw_cmd));
}
draw_lists_.push_back(std::move(hwr2_list));
}
}
void ImguiPass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
{
ImGuiIO& io = ImGui::GetIO();
{
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
rhi.update_texture(
ctx,
font_atlas_,
{0, 0, static_cast<uint32_t>(width), static_cast<uint32_t>(height)},
rhi::PixelFormat::kRGBA8,
tcb::as_bytes(tcb::span(pixels, static_cast<size_t>(width * height * 4)))
);
}
for (auto& draw_list : draw_lists_)
{
Handle<Buffer> vbo = draw_list.vbo;
Handle<Buffer> ibo = draw_list.ibo;
ImDrawList* im_list = static_cast<ImDrawList*>(draw_list.list);
for (auto& vtx : im_list->VtxBuffer)
{
vtx.pos.z = 0.f;
vtx.colf[0] = ((vtx.col & 0xFF) >> 0) / 255.f;
vtx.colf[1] = ((vtx.col & 0xFF00) >> 8) / 255.f;
vtx.colf[2] = ((vtx.col & 0xFF0000) >> 16) / 255.f;
vtx.colf[3] = ((vtx.col & 0xFF000000) >> 24) / 255.f;
}
tcb::span<ImDrawVert> vert_span = tcb::span(im_list->VtxBuffer.Data, im_list->VtxBuffer.size());
rhi.update_buffer_contents(ctx, vbo, 0, tcb::as_bytes(vert_span));
tcb::span<ImDrawIdx> index_span = tcb::span(im_list->IdxBuffer.Data, im_list->IdxBuffer.size());
rhi.update_buffer_contents(ctx, ibo, 0, tcb::as_bytes(index_span));
// Uniform sets
std::array<UniformVariant, 1> g1_uniforms =
{{
// Projection
std::array<std::array<float, 4>, 4>
{{
{2.f / vid.realwidth, 0.f, 0.f, 0.f},
{0.f, 2.f / vid.realheight, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{-1.f, 1.f, 0.f, 1.f}
}},
}};
std::array<UniformVariant, 2> g2_uniforms =
{{
// ModelView
std::array<std::array<float, 4>, 4>
{{
{1.f, 0.f, 0.f, 0.f},
{0.f, -1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0, 0.f, 1.f}
}},
// Texcoord0 Transform
std::array<std::array<float, 3>, 3>
{{
{1.f, 0.f, 0.f},
{0.f, 1.f, 0.f},
{0.f, 0.f, 1.f}
}}
}};
Handle<UniformSet> us_1 = rhi.create_uniform_set(ctx, {g1_uniforms});
Handle<UniformSet> us_2 = rhi.create_uniform_set(ctx, {g2_uniforms});
draw_list.us_1 = us_1;
draw_list.us_2 = us_2;
for (auto& draw_cmd : draw_list.cmds)
{
// Binding set
std::array<rhi::VertexAttributeBufferBinding, 1> vbos = {{0, vbo}};
std::array<rhi::TextureBinding, 1> tbs = {{{rhi::SamplerName::kSampler0, draw_cmd.tex}}};
rhi::Handle<rhi::BindingSet> binding_set = rhi.create_binding_set(ctx, pipeline_, {vbos, tbs});
draw_cmd.binding_set = binding_set;
}
}
}
void ImguiPass::graphics(Rhi& rhi, Handle<GraphicsContext> ctx)
{
rhi.begin_default_render_pass(ctx, false);
rhi.bind_pipeline(ctx, pipeline_);
for (auto& draw_list : draw_lists_)
{
rhi.bind_uniform_set(ctx, 0, draw_list.us_1);
rhi.bind_uniform_set(ctx, 1, draw_list.us_2);
for (auto& cmd : draw_list.cmds)
{
rhi.bind_binding_set(ctx, cmd.binding_set);
rhi.bind_index_buffer(ctx, draw_list.ibo);
rhi.set_scissor(ctx, cmd.clip);
rhi.draw_indexed(ctx, cmd.elems, cmd.i_offset);
}
}
rhi.end_render_pass(ctx);
}
void ImguiPass::postpass(Rhi& rhi)
{
for (auto& list : draw_lists_)
{
rhi.destroy_buffer(list.vbo);
rhi.destroy_buffer(list.ibo);
}
draw_lists_.clear();
}

52
src/hwr2/pass_imgui.hpp Normal file
View file

@ -0,0 +1,52 @@
#ifndef __SRB2_HWR2_PASS_IMGUI_HPP__
#define __SRB2_HWR2_PASS_IMGUI_HPP__
#include <vector>
#include "../rhi/rhi.hpp"
#include "pass.hpp"
namespace srb2::hwr2
{
class ImguiPass : public Pass
{
struct DrawCmd
{
rhi::Handle<rhi::Texture> tex;
uint32_t v_offset;
uint32_t elems;
uint32_t i_offset;
rhi::Rect clip;
rhi::Handle<rhi::BindingSet> binding_set;
};
struct DrawList
{
void* list;
rhi::Handle<rhi::Buffer> vbo;
rhi::Handle<rhi::Buffer> ibo;
rhi::Handle<rhi::UniformSet> us_1;
rhi::Handle<rhi::UniformSet> us_2;
std::vector<DrawCmd> cmds;
};
rhi::Handle<rhi::Pipeline> pipeline_;
rhi::Handle<rhi::Texture> font_atlas_;
std::vector<DrawList> draw_lists_;
public:
virtual ~ImguiPass();
virtual void prepass(rhi::Rhi& rhi) override;
virtual void transfer(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx) override;
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
virtual void postpass(rhi::Rhi& rhi) override;
};
} // namespace srb2::hwr2
#endif // __SRB2_HWR2_PASS_IMGUI_HPP__

284
src/hwr2/pass_software.cpp Normal file
View file

@ -0,0 +1,284 @@
#include "pass_software.hpp"
#include <optional>
#include <tcb/span.hpp>
#include "../cxxutil.hpp"
#include "../d_netcmd.h"
#ifdef HAVE_DISCORDRPC
#include "../discord.h"
#endif
#include "../doomstat.h"
#include "../st_stuff.h"
#include "../s_sound.h"
#include "../v_video.h"
using namespace srb2;
using namespace srb2::hwr2;
using namespace srb2::rhi;
SoftwareBlitPass::~SoftwareBlitPass() = default;
namespace
{
struct SwBlitVertex
{
float x = 0.f;
float y = 0.f;
float z = 0.f;
float u = 0.f;
float v = 0.f;
};
} // namespace
static const SwBlitVertex kVerts[] =
{
{-.5f, -.5f, 0.f, 0.f, 0.f},
{.5f, -.5f, 0.f, 1.f, 0.f},
{-.5f, .5f, 0.f, 0.f, 1.f},
{.5f, .5f, 0.f, 1.f, 1.f}
};
static const uint16_t kIndices[] = {0, 1, 2, 1, 3, 2};
static const PipelineDesc kPipelineDescription =
{
PipelineProgram::kUnshadedPaletted,
{
{
{sizeof(SwBlitVertex)}
},
{
{VertexAttributeName::kPosition, 0, 0},
{VertexAttributeName::kTexCoord0, 0, 12}
}
},
{{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
{{
// R8 index texture
SamplerName::kSampler0,
// 256x1 palette texture
SamplerName::kSampler1
}},
std::nullopt,
{
PixelFormat::kRGBA8,
std::nullopt,
{true, true, true, true}
},
PrimitiveType::kTriangles,
CullMode::kNone,
FaceWinding::kCounterClockwise,
{0.f, 0.f, 0.f, 1.f}
};
static uint32_t next_pow_of_2(uint32_t in)
{
in--;
in |= in >> 1;
in |= in >> 2;
in |= in >> 4;
in |= in >> 8;
in |= in >> 16;
in++;
return in;
}
static void temp_legacy_finishupdate_draws()
{
SCR_CalculateFPS();
if (st_overlay)
{
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame &&
( consoleplayer != serverplayer || ! server_lagless ))
{
if (server_lagless)
{
if (consoleplayer != serverplayer)
SCR_DisplayLocalPing();
}
else
{
for (
int player = 1;
player < MAXPLAYERS;
player++
){
if (D_IsPlayerHumanAndGaming(player))
{
SCR_DisplayLocalPing();
break;
}
}
}
}
if (cv_mindelay.value && consoleplayer == serverplayer && Playing())
SCR_DisplayLocalPing();
}
if (marathonmode)
SCR_DisplayMarathonInfo();
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
#ifdef HAVE_DISCORDRPC
if (discordRequestList != NULL)
ST_AskToJoinEnvelope();
#endif
}
void SoftwareBlitPass::prepass(Rhi& rhi)
{
if (!pipeline_)
{
pipeline_ = rhi.create_pipeline(kPipelineDescription);
}
if (!quad_vbo_)
{
quad_vbo_ = rhi.create_buffer({sizeof(kVerts), BufferType::kVertexBuffer, BufferUsage::kImmutable});
quad_vbo_needs_upload_ = true;
}
if (!quad_ibo_)
{
quad_ibo_ = rhi.create_buffer({sizeof(kIndices), BufferType::kIndexBuffer, BufferUsage::kImmutable});
quad_ibo_needs_upload_ = true;
}
temp_legacy_finishupdate_draws();
uint32_t vid_width = static_cast<uint32_t>(vid.width);
uint32_t vid_height = static_cast<uint32_t>(vid.height);
if (screen_tex_ && (screen_tex_width_ < vid_width || screen_tex_height_ < vid_height))
{
rhi.destroy_texture(screen_tex_);
screen_tex_ = kNullHandle;
}
if (!screen_tex_)
{
screen_tex_width_ = next_pow_of_2(vid_width);
screen_tex_height_ = next_pow_of_2(vid_height);
screen_tex_ = rhi.create_texture({TextureFormat::kLuminance, screen_tex_width_, screen_tex_height_});
}
if (!palette_tex_)
{
palette_tex_ = rhi.create_texture({TextureFormat::kRGBA, 256, 1});
}
}
void SoftwareBlitPass::upload_screen(Rhi& rhi, Handle<TransferContext> ctx)
{
rhi::Rect screen_rect = {
0,
0,
static_cast<uint32_t>(vid.width),
static_cast<uint32_t>(vid.height)
};
tcb::span<uint8_t> screen_span = tcb::span(vid.buffer, static_cast<size_t>(vid.width * vid.height));
rhi.update_texture(ctx, screen_tex_, screen_rect, rhi::PixelFormat::kR8, tcb::as_bytes(screen_span));
}
void SoftwareBlitPass::upload_palette(Rhi& rhi, Handle<TransferContext> ctx)
{
// Unfortunately, pMasterPalette must be swizzled to get a linear layout.
// Maybe some adjustments to palette storage can make this a straight upload.
std::array<byteColor_t, 256> palette_32;
for (size_t i = 0; i < 256; i++)
{
palette_32[i] = pMasterPalette[i].s;
}
rhi.update_texture(ctx, palette_tex_, {0, 0, 256, 1}, rhi::PixelFormat::kRGBA8, tcb::as_bytes(tcb::span(palette_32)));
}
void SoftwareBlitPass::transfer(Rhi& rhi, Handle<TransferContext> ctx)
{
if (quad_vbo_needs_upload_ && quad_vbo_)
{
rhi.update_buffer_contents(ctx, quad_vbo_, 0, tcb::as_bytes(tcb::span(kVerts)));
quad_vbo_needs_upload_ = false;
}
if (quad_ibo_needs_upload_ && quad_ibo_)
{
rhi.update_buffer_contents(ctx, quad_ibo_, 0, tcb::as_bytes(tcb::span(kIndices)));
quad_ibo_needs_upload_ = false;
}
upload_screen(rhi, ctx);
upload_palette(rhi, ctx);
// Calculate aspect ratio for black borders
float aspect = static_cast<float>(vid.width) / static_cast<float>(vid.height);
float real_aspect = static_cast<float>(vid.realwidth) / static_cast<float>(vid.realheight);
bool taller = aspect > real_aspect;
std::array<rhi::UniformVariant, 1> g1_uniforms = {{
// Projection
std::array<std::array<float, 4>, 4> {{
{taller ? 1.f : 1.f / real_aspect, 0.f, 0.f, 0.f},
{0.f, taller ? -1.f / (1.f / real_aspect) : -1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
}},
}};
std::array<rhi::UniformVariant, 2> g2_uniforms =
{{
// ModelView
std::array<std::array<float, 4>, 4>
{{
{taller ? 2.f : 2.f * aspect, 0.f, 0.f, 0.f},
{0.f, taller ? 2.f * (1.f / aspect) : 2.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
}},
// Texcoord0 Transform
std::array<std::array<float, 3>, 3>
{{
{vid.width / static_cast<float>(screen_tex_width_), 0.f, 0.f},
{0.f, vid.height / static_cast<float>(screen_tex_height_), 0.f},
{0.f, 0.f, 1.f}
}}
}};
uniform_sets_[0] = rhi.create_uniform_set(ctx, {g1_uniforms});
uniform_sets_[1] = rhi.create_uniform_set(ctx, {g2_uniforms});
std::array<rhi::VertexAttributeBufferBinding, 1> vbs = {{{0, quad_vbo_}}};
std::array<rhi::TextureBinding, 2> tbs = {{
{rhi::SamplerName::kSampler0, screen_tex_},
{rhi::SamplerName::kSampler1, palette_tex_}
}};
binding_set_ = rhi.create_binding_set(ctx, pipeline_, {vbs, tbs});
}
void SoftwareBlitPass::graphics(Rhi& rhi, Handle<GraphicsContext> ctx)
{
rhi.begin_default_render_pass(ctx, true);
rhi.bind_pipeline(ctx, pipeline_);
rhi.bind_uniform_set(ctx, 0, uniform_sets_[0]);
rhi.bind_uniform_set(ctx, 1, uniform_sets_[1]);
rhi.bind_binding_set(ctx, binding_set_);
rhi.bind_index_buffer(ctx, quad_ibo_);
rhi.draw_indexed(ctx, 6, 0);
rhi.end_render_pass(ctx);
}
void SoftwareBlitPass::postpass(Rhi& rhi)
{
// no-op
}

View file

@ -0,0 +1,44 @@
#ifndef __SRB2_HWR2_PASS_SOFTWARE_HPP__
#define __SRB2_HWR2_PASS_SOFTWARE_HPP__
#include <array>
#include "../rhi/rhi.hpp"
#include "pass.hpp"
namespace srb2::hwr2
{
class SoftwareBlitPass : public Pass
{
rhi::Handle<rhi::Pipeline> pipeline_;
rhi::Handle<rhi::Texture> screen_tex_;
rhi::Handle<rhi::Texture> palette_tex_;
rhi::Handle<rhi::Buffer> quad_vbo_;
rhi::Handle<rhi::Buffer> quad_ibo_;
std::array<rhi::Handle<rhi::UniformSet>, 2> uniform_sets_;
rhi::Handle<rhi::BindingSet> binding_set_;
uint32_t screen_tex_width_ = 0;
uint32_t screen_tex_height_ = 0;
bool quad_vbo_needs_upload_ = false;
bool quad_ibo_needs_upload_ = false;
void upload_screen(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx);
void upload_palette(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx);
public:
virtual ~SoftwareBlitPass();
virtual void prepass(rhi::Rhi& rhi) override;
virtual void transfer(rhi::Rhi& rhi, rhi::Handle<rhi::TransferContext> ctx) override;
virtual void graphics(rhi::Rhi& rhi, rhi::Handle<rhi::GraphicsContext> ctx) override;
virtual void postpass(rhi::Rhi& rhi) override;
};
} // namespace srb2::hwr2
#endif // __SRB2_HWR2_PASS_SOFTWARE_HPP__

View file

@ -17,6 +17,17 @@
#include "doomtype.h"
#ifdef __cplusplus
#include "rhi/rhi.hpp"
namespace srb2::sys {
extern rhi::Handle<rhi::Rhi> g_current_rhi;
rhi::Rhi* get_rhi(rhi::Handle<rhi::Rhi> handle);
} // namespace
extern "C" {
#endif
@ -44,10 +55,6 @@ extern rendermode_t rendermode;
*/
extern rendermode_t chosenrendermode;
/** \brief use highcolor modes if true
*/
extern boolean highcolor;
/** \brief setup video mode
*/
void I_StartupGraphics(void);

100
src/i_video_common.cpp Normal file
View file

@ -0,0 +1,100 @@
#include "i_video.h"
#include <algorithm>
#include <array>
#include <vector>
#include <imgui.h>
#include "cxxutil.hpp"
#include "v_video.h"
#include "hwr2/pass_imgui.hpp"
#include "hwr2/pass_software.hpp"
using namespace srb2;
using namespace srb2::hwr2;
using namespace srb2::rhi;
static SoftwareBlitPass g_sw_pass;
static ImguiPass g_imgui_pass;
Handle<Rhi> srb2::sys::g_current_rhi = kNullHandle;
static bool rhi_changed()
{
return false;
}
void I_FinishUpdate(void)
{
if (rendermode == render_none)
{
return;
}
// TODO move this to srb2loop
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize.x = vid.realwidth;
io.DisplaySize.y = vid.realheight;
ImGui::NewFrame();
if (rhi_changed())
{
// reinitialize passes
g_sw_pass = SoftwareBlitPass();
g_imgui_pass = ImguiPass();
}
rhi::Rhi* rhi = sys::get_rhi(sys::g_current_rhi);
if (rhi == nullptr)
{
// ???
return;
}
// Prepare phase
if (rendermode == render_soft)
{
g_sw_pass.prepass(*rhi);
}
g_imgui_pass.prepass(*rhi);
// Transfer phase
Handle<TransferContext> tc;
tc = rhi->begin_transfer();
if (rendermode == render_soft)
{
g_sw_pass.transfer(*rhi, tc);
}
g_imgui_pass.transfer(*rhi, tc);
rhi->end_transfer(tc);
// Graphics phase
Handle<GraphicsContext> gc;
gc = rhi->begin_graphics();
// Standard drawing passes...
if (rendermode == render_soft)
{
g_sw_pass.graphics(*rhi, gc);
}
g_imgui_pass.graphics(*rhi, gc);
rhi->end_graphics(gc);
// Postpass phase
if (rendermode == render_soft)
{
g_sw_pass.postpass(*rhi);
}
g_imgui_pass.postpass(*rhi);
// Present
rhi->present();
rhi->finish();
}

View file

@ -1167,12 +1167,6 @@ static void R_Init8to16(void)
//
void R_InitTextureData(void)
{
if (highcolor)
{
CONS_Printf("InitHighColor...\n");
R_Init8to16();
}
CONS_Printf("R_LoadTextures()...\n");
R_LoadTextures();

7
src/rhi/CMakeLists.txt Normal file
View file

@ -0,0 +1,7 @@
target_sources(SRB2SDL2 PRIVATE
handle.hpp
rhi.cpp
rhi.hpp
)
add_subdirectory(gl3_core)

View file

@ -0,0 +1,4 @@
target_sources(SRB2SDL2 PRIVATE
gl3_core_rhi.cpp
gl3_core_rhi.hpp
)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,148 @@
#ifndef __SRB2_RHI_GLES2_RHI_HPP__
#define __SRB2_RHI_GLES2_RHI_HPP__
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "../rhi.hpp"
namespace srb2::rhi {
struct GlCoreFramebufferKey {
TextureOrRenderbuffer color;
std::optional<TextureOrRenderbuffer> depth;
bool operator==(const GlCoreFramebufferKey& rhs) const noexcept {
return color == rhs.color && depth == rhs.depth;
}
bool operator!=(const GlCoreFramebufferKey& rhs) const noexcept {
return !(*this == rhs);
}
};
} // namespace srb2::rhi
// To make sure the compiler selects the struct specialization of std::hash for GlCoreFramebufferKey,
// we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
template <>
struct std::hash<srb2::rhi::GlCoreFramebufferKey> {
std::size_t operator()(const srb2::rhi::GlCoreFramebufferKey& key) const {
struct GetHandleHashVisitor {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept {
return std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(handle);
}
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept {
return std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(handle);
}
};
std::size_t color_hash = std::visit(GetHandleHashVisitor {}, key.color);
std::size_t depth_hash = 0;
if (key.depth) {
depth_hash = std::visit(GetHandleHashVisitor {}, *key.depth);
}
return color_hash ^ (depth_hash << 1);
}
};
struct GladGLContext;
namespace srb2::rhi {
typedef void (*GlProc)(void);
typedef GlProc (*GlLoadFunc)(const char* name);
/// @brief Platform-specific implementation details for the GLES2 backend.
struct GlCorePlatform {
virtual ~GlCorePlatform();
virtual void present() = 0;
virtual std::tuple<std::string, std::string> find_shader_sources(PipelineProgram program) = 0;
virtual Rect get_default_framebuffer_dimensions() = 0;
};
class GlCoreRhi final : public Rhi {
std::unique_ptr<GlCorePlatform> platform_;
std::unique_ptr<GladGLContext> gl_;
Slab<RenderPass> render_pass_slab_;
Slab<Texture> texture_slab_;
Slab<Buffer> buffer_slab_;
Slab<Renderbuffer> renderbuffer_slab_;
Slab<Pipeline> pipeline_slab_;
Slab<UniformSet> uniform_set_slab_;
Slab<BindingSet> binding_set_slab_;
std::unordered_map<GlCoreFramebufferKey, uint32_t> framebuffers_ {16};
struct DefaultRenderPassState {};
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
std::optional<RenderPassState> current_render_pass_;
std::optional<Handle<Pipeline>> current_pipeline_;
PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
bool graphics_context_active_ = false;
bool transfer_context_active_ = false;
uint32_t graphics_context_generation_ = 0;
uint32_t index_buffer_offset_ = 0;
uint32_t transfer_context_generation_ = 0;
std::vector<std::function<void()>> disposal_;
public:
GlCoreRhi(std::unique_ptr<GlCorePlatform>&& platform, GlLoadFunc load_func);
virtual ~GlCoreRhi();
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override;
virtual void destroy_render_pass(Handle<RenderPass> handle) override;
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
virtual void destroy_pipeline(Handle<Pipeline> handle) override;
virtual Handle<Texture> create_texture(const TextureDesc& desc) override;
virtual void destroy_texture(Handle<Texture> handle) override;
virtual Handle<Buffer> create_buffer(const BufferDesc& desc) override;
virtual void destroy_buffer(Handle<Buffer> handle) override;
virtual Handle<Renderbuffer> create_renderbuffer(const RenderbufferDesc& desc) override;
virtual void destroy_renderbuffer(Handle<Renderbuffer> handle) override;
virtual Handle<TransferContext> begin_transfer() override;
virtual void end_transfer(Handle<TransferContext> handle) override;
virtual void update_buffer_contents(Handle<TransferContext> ctx, Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) override;
virtual void update_texture(Handle<TransferContext> ctx, Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual Handle<UniformSet> create_uniform_set(Handle<TransferContext> ctx, const CreateUniformSetInfo& info) override;
virtual Handle<BindingSet> create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) override;
virtual Handle<GraphicsContext> begin_graphics() override;
virtual void end_graphics(Handle<GraphicsContext> ctx) override;
// Graphics context functions
virtual void begin_default_render_pass(Handle<GraphicsContext> ctx, bool clear) override;
virtual void begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info) override;
virtual void end_render_pass(Handle<GraphicsContext> ctx) override;
virtual void bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline) override;
virtual void bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Handle<UniformSet> set) override;
virtual void bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet> set) override;
virtual void bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> buffer) override;
virtual void set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) override;
virtual void draw_indexed(Handle<GraphicsContext> ctx,
uint32_t index_count,
uint32_t first_index) override;
virtual void read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, tcb::span<std::byte> out) override;
virtual void present() override;
virtual void finish() override;
};
} // namespace srb2::rhi
#endif // __SRB2_RHI_GLES2_RHI_HPP__

View file

@ -0,0 +1 @@
# Backend not available yet :)

1122
src/rhi/gles2/gles2_rhi.cpp Normal file

File diff suppressed because it is too large Load diff

135
src/rhi/gles2/gles2_rhi.hpp Normal file
View file

@ -0,0 +1,135 @@
#ifndef __SRB2_RHI_GLES2_RHI_HPP__
#define __SRB2_RHI_GLES2_RHI_HPP__
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "../rhi.hpp"
namespace srb2::rhi {
struct Gles2FramebufferKey {
TextureOrRenderbuffer color;
std::optional<TextureOrRenderbuffer> depth;
bool operator==(const Gles2FramebufferKey& rhs) const noexcept {
return color == rhs.color && depth == rhs.depth;
}
bool operator!=(const Gles2FramebufferKey& rhs) const noexcept {
return !(*this == rhs);
}
};
} // namespace srb2::rhi
// To make sure the compiler selects the struct specialization of std::hash for Gles2FramebufferKey,
// we need to split the namespace declarations _before_ the instantiation of std::unordered_map.
template <>
struct std::hash<srb2::rhi::Gles2FramebufferKey> {
std::size_t operator()(const srb2::rhi::Gles2FramebufferKey& key) const {
struct GetHandleHashVisitor {
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Texture>& handle) const noexcept {
return std::hash<srb2::rhi::Handle<srb2::rhi::Texture>>()(handle);
}
uint32_t operator()(const srb2::rhi::Handle<srb2::rhi::Renderbuffer>& handle) const noexcept {
return std::hash<srb2::rhi::Handle<srb2::rhi::Renderbuffer>>()(handle);
}
};
std::size_t color_hash = std::visit(GetHandleHashVisitor {}, key.color);
std::size_t depth_hash = 0;
if (key.depth) {
depth_hash = std::visit(GetHandleHashVisitor {}, *key.depth);
}
return color_hash ^ (depth_hash << 1);
}
};
namespace srb2::rhi {
/// @brief Platform-specific implementation details for the GLES2 backend.
struct Gles2Platform {
virtual ~Gles2Platform();
virtual void present() = 0;
virtual std::tuple<std::string, std::string> find_shader_sources(PipelineProgram program) = 0;
virtual Rect get_default_framebuffer_dimensions() = 0;
};
class Gles2Rhi final : public Rhi {
std::unique_ptr<Gles2Platform> platform_;
Slab<RenderPass> render_pass_slab_;
Slab<Texture> texture_slab_;
Slab<Buffer> buffer_slab_;
Slab<Renderbuffer> renderbuffer_slab_;
Slab<Pipeline> pipeline_slab_;
std::unordered_map<Gles2FramebufferKey, uint32_t> framebuffers_ {16};
struct DefaultRenderPassState {};
using RenderPassState = std::variant<DefaultRenderPassState, RenderPassBeginInfo>;
std::optional<RenderPassState> current_render_pass_;
std::optional<Handle<Pipeline>> current_pipeline_;
PrimitiveType current_primitive_type_ = PrimitiveType::kPoints;
bool graphics_context_active_ = false;
uint32_t graphics_context_generation_ = 0;
uint32_t index_buffer_offset_ = 0;
std::vector<std::function<void()>> disposal_;
public:
Gles2Rhi(std::unique_ptr<Gles2Platform>&& platform);
virtual ~Gles2Rhi();
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) override;
virtual void destroy_render_pass(Handle<RenderPass>&& handle) override;
virtual Handle<Texture> create_texture(const TextureDesc& desc, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual void destroy_texture(Handle<Texture>&& handle) override;
virtual Handle<Buffer> create_buffer(const BufferDesc& desc, tcb::span<const std::byte> data) override;
virtual void destroy_buffer(Handle<Buffer>&& handle) override;
virtual Handle<Renderbuffer> create_renderbuffer(const RenderbufferDesc& desc) override;
virtual void destroy_renderbuffer(Handle<Renderbuffer>&& handle) override;
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) override;
virtual void destroy_pipeline(Handle<Pipeline>&& handle) override;
virtual void update_buffer_contents(Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) override;
virtual void update_texture(Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) override;
virtual Handle<GraphicsContext> begin_graphics() override;
virtual void end_graphics(Handle<GraphicsContext>&& ctx) override;
// Graphics context functions
virtual void begin_default_render_pass(Handle<GraphicsContext> ctx) override;
virtual void begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info) override;
virtual void end_render_pass(Handle<GraphicsContext> ctx) override;
virtual void bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline) override;
virtual void update_bindings(Handle<GraphicsContext> ctx, const UpdateBindingsInfo& info) override;
virtual void update_uniforms(Handle<GraphicsContext> ctx, tcb::span<UniformUpdateData> uniforms) override;
virtual void set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) override;
virtual void draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) override;
virtual void draw_indexed(Handle<GraphicsContext> ctx,
uint32_t index_count,
uint32_t first_index,
uint32_t vertex_offset) override;
virtual void present() override;
virtual void finish() override;
};
typedef void (*Gles2Proc)(void);
typedef Gles2Proc (*Gles2LoadFunc)(const char* name);
void load_gles2(Gles2LoadFunc func);
} // namespace srb2::rhi
#endif // __SRB2_RHI_GLES2_RHI_HPP__

317
src/rhi/handle.hpp Normal file
View file

@ -0,0 +1,317 @@
#ifndef __SRB2_RHI_HANDLE_HPP__
#define __SRB2_RHI_HANDLE_HPP__
#include <atomic>
#include <cstdint>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
#include "../cxxutil.hpp"
namespace srb2::rhi {
struct NullHandleType {};
constexpr const NullHandleType kNullHandle = NullHandleType {};
template <typename T = void>
class Handle {
uint32_t id_;
uint32_t generation_;
public:
Handle(uint32_t id, uint32_t generation) noexcept : id_(id), generation_(generation) {}
Handle(uint64_t combined) noexcept
: id_(combined & 0xFFFFFFFF)
, generation_((combined & 0xFFFFFFFF00000000) >> 32)
{}
Handle() noexcept : Handle(0, 0) {}
Handle(NullHandleType) noexcept : Handle() {}
Handle(const Handle&) = default;
Handle(Handle&& rhs) noexcept {
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
};
Handle& operator=(const Handle&) = default;
Handle& operator=(Handle&& rhs) noexcept {
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
return *this;
}
// Conversions from Handles of derived type U to base type T
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle(const Handle<U>& rhs) noexcept : id_(rhs.id_), generation_(rhs.generation_) {}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle(Handle<U>&& rhs) noexcept {
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle& operator=(const Handle<U>& rhs) noexcept {
id_ = rhs.id_;
generation_ = rhs.generation_;
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
Handle& operator=(Handle<U>&& rhs) noexcept {
id_ = std::exchange(rhs.id_, 0);
generation_ = std::exchange(rhs.generation_, 0);
return *this;
}
uint32_t id() const noexcept { return id_; }
uint32_t generation() const noexcept { return generation_; }
/// @return true if this Handle is valid (belonging to a generation > 0); false otherwise
bool valid() const noexcept { return generation_ != 0; }
bool operator==(const Handle& handle) const noexcept {
return handle.generation_ == generation_ && handle.id_ == id_;
}
bool operator!=(const Handle& handle) const noexcept { return !(handle == *this); }
bool operator==(const NullHandleType&) const noexcept { return generation_ == 0; }
bool operator!=(const NullHandleType&) const noexcept { return generation_ != 0; }
operator bool() const { return id_ != 0 || generation_ != 0; }
operator uint64_t() const { return static_cast<uint64_t>(id_) + (static_cast<uint64_t>(generation_) << 32); }
};
template <typename T>
inline bool operator==(const Handle<T>& lhs, const NullHandleType&) noexcept
{
return lhs.generation() == 0 || lhs.id() == 0;
}
template <typename T>
inline bool operator==(const Handle<T>& lhs, const std::nullptr_t&) noexcept
{
return lhs.generation() == 0 || lhs.id() == 0;
}
// Non-member equality of base Handle<T> to derived Handle<U>
template <typename T, typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
inline bool operator==(const Handle<T>& lhs, const Handle<U>& rhs) noexcept {
return lhs.generation() == rhs.generation() && lhs.id() == rhs.id();
}
template <typename T, typename U, typename std::enable_if_t<std::is_base_of_v<T, U>, bool> = true>
inline bool operator!=(const Handle<T>& lhs, const Handle<U>& rhs) noexcept {
return !(lhs == rhs);
}
template <typename T = void>
class HandlePool {
std::atomic_uint32_t current_id_ {0};
std::atomic_uint32_t current_gen_ {1};
public:
HandlePool() = default;
HandlePool(const HandlePool& rhs) = delete;
HandlePool(HandlePool&& rhs) = default;
HandlePool& operator=(const HandlePool& rhs) = delete;
HandlePool& operator=(HandlePool&& rhs) = default;
/// @brief Create a new unique Handle in the current generation.
/// @return the new Handle.
Handle<T> create() noexcept {
const uint32_t id = current_id_.fetch_add(1);
SRB2_ASSERT(id != UINT32_MAX);
const uint32_t gen = current_gen_.load();
return Handle<T>(id, gen);
}
/// @brief Increment the generation. All handles created after this will belong to a new generation.
void generation() noexcept {
const uint32_t old_gen = current_gen_.fetch_add(1);
SRB2_ASSERT(old_gen != UINT32_MAX);
}
};
template <typename T>
class Slab;
template <typename T>
class SlabIterator
{
size_t index_ = 0;
const Slab<std::remove_const_t<T>>* slab_ = nullptr;
SlabIterator(size_t index, const Slab<std::remove_const_t<T>>* slab) : index_(index), slab_(slab) {}
friend Slab<std::remove_const_t<T>>;
public:
SlabIterator() = default;
SlabIterator(const SlabIterator&) = default;
SlabIterator(SlabIterator&&) = default;
SlabIterator& operator=(const SlabIterator&) = default;
SlabIterator& operator=(SlabIterator&&) = default;
T& operator*() const noexcept
{
return *slab_->vec_[index_].item.get();
}
SlabIterator& operator++() noexcept
{
index_++;
return *this;
}
SlabIterator& operator--() noexcept
{
index_--;
return *this;
}
SlabIterator operator++(int) noexcept
{
index_++;
return SlabIterator {index_ - 1, slab_};
}
SlabIterator operator--(int) noexcept
{
index_--;
return SlabIterator {index_ + 1, slab_};
}
bool operator==(const SlabIterator& rhs) const noexcept
{
return slab_ == rhs.slab_ && index_ == rhs.index_;
}
bool operator!=(const SlabIterator& rhs) const noexcept
{
return !(*this == rhs);
}
};
template <typename T>
class Slab {
struct SlabStorage {
std::unique_ptr<T> item;
uint32_t gen;
};
std::vector<SlabStorage> vec_;
std::vector<uint32_t> free_list_;
uint32_t gen_ = 1;
friend SlabIterator<T>;
friend SlabIterator<const T>;
public:
Slab() = default;
Slab(const Slab&) = delete;
Slab& operator=(const Slab&) = delete;
Handle<T> insert(std::unique_ptr<T>&& value) {
uint32_t ret_id = 0;
if (!free_list_.empty()) {
ret_id = free_list_.back();
free_list_.pop_back();
SlabStorage& storage = vec_[ret_id];
storage.item = std::move(value);
storage.gen = gen_;
} else {
ret_id = vec_.size();
vec_.push_back(SlabStorage {std::move(value), gen_});
}
return Handle<T>(ret_id, gen_);
}
std::unique_ptr<T> remove(Handle<T> handle) {
uint32_t handle_id = handle.id();
uint32_t handle_gen = handle.generation();
if (handle_id >= vec_.size()) {
return nullptr;
}
SlabStorage& storage = vec_[handle_id];
if (storage.gen > handle_gen) {
return nullptr;
}
std::unique_ptr<T> ret = std::move(storage.item);
storage.item = nullptr;
free_list_.push_back(handle_id);
gen_ += 1;
if (gen_ == 0)
{
gen_ = 1;
}
return ret;
}
bool is_valid(Handle<T> handle) {
uint32_t handle_id = handle.id();
uint32_t handle_gen = handle.generation();
if (handle_id >= vec_.size()) {
return false;
}
SlabStorage& storage = vec_[handle_id];
if (storage.gen > handle_gen) {
return false;
}
return true;
}
void clear()
{
vec_.clear();
free_list_.clear();
gen_ += 1;
if (gen_ == 0)
{
gen_ = 1;
}
}
T& operator[](Handle<T> handle) {
SRB2_ASSERT(is_valid(handle));
return *vec_[handle.id()].item;
}
SlabIterator<T> begin()
{
return SlabIterator<T> {0, this};
}
SlabIterator<T> end()
{
return SlabIterator<T> {vec_.size(), this};
}
SlabIterator<const T> cbegin() const
{
return SlabIterator<const T> {0, this};
}
SlabIterator<const T> cend() const
{
return SlabIterator<const T> {vec_.size(), this};
}
};
} // namespace srb2::rhi
namespace std {
template <typename T>
struct hash<srb2::rhi::Handle<T>> {
std::size_t operator()(const srb2::rhi::Handle<T>& e) const {
return std::hash<uint32_t>()(e.generation()) ^ (std::hash<uint32_t>()(e.id()) << 1);
}
};
} // namespace std
#endif // __SRB2_RHI_HANDLE_HPP__

51
src/rhi/rhi.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "rhi.hpp"
#include <exception>
#include <stdexcept>
using namespace srb2;
using namespace srb2::rhi;
Rhi::~Rhi() = default;
const ProgramRequirements srb2::rhi::kProgramRequirementsUnshaded = {
ProgramVertexInputRequirements {{
ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}
}},
ProgramUniformRequirements {{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
ProgramSamplerRequirements {{
ProgramSamplerInput {SamplerName::kSampler0, true}
}}
};
const ProgramRequirements srb2::rhi::kProgramRequirementsUnshadedPaletted = {
ProgramVertexInputRequirements {{
ProgramVertexInput {VertexAttributeName::kPosition, VertexAttributeFormat::kFloat3, true},
ProgramVertexInput {VertexAttributeName::kTexCoord0, VertexAttributeFormat::kFloat2, false},
ProgramVertexInput {VertexAttributeName::kColor, VertexAttributeFormat::kFloat4, false}
}},
ProgramUniformRequirements {{
{{UniformName::kProjection}},
{{UniformName::kModelView, UniformName::kTexCoord0Transform}}
}},
ProgramSamplerRequirements {{
ProgramSamplerInput {SamplerName::kSampler0, true},
ProgramSamplerInput {SamplerName::kSampler1, true}
}}
};
const ProgramRequirements& rhi::program_requirements_for_program(PipelineProgram program) noexcept {
switch (program) {
case PipelineProgram::kUnshaded:
return kProgramRequirementsUnshaded;
case PipelineProgram::kUnshadedPaletted:
return kProgramRequirementsUnshadedPaletted;
default:
std::terminate();
}
}

466
src/rhi/rhi.hpp Normal file
View file

@ -0,0 +1,466 @@
#ifndef __SRB2_RHI_RHI_HPP__
#define __SRB2_RHI_RHI_HPP__
#include <cstdint>
#include <optional>
#include <set>
#include <variant>
#include <vector>
#include <tcb/span.hpp>
#include "../core/static_vec.hpp"
#include "handle.hpp"
namespace srb2::rhi {
struct Buffer {};
struct Texture {};
struct Pipeline {};
struct RenderPass {};
struct Renderbuffer {};
using TextureOrRenderbuffer = std::variant<Handle<Texture>, Handle<Renderbuffer>>;
enum class VertexAttributeFormat {
kFloat,
kFloat2,
kFloat3,
kFloat4
};
enum class UniformFormat {
kFloat,
kFloat2,
kFloat3,
kFloat4,
kInt,
kInt2,
kInt3,
kInt4,
kMat2,
kMat3,
kMat4
};
enum class PixelFormat {
kR8,
kRGBA8,
kDepth16,
kStencil8
};
enum class TextureFormat {
kLuminance,
kRGB,
kRGBA
};
enum class CompareFunc {
kNever,
kLess,
kEqual,
kLessEqual,
kGreater,
kNotEqual,
kGreaterEqual,
kAlways
};
enum class BlendFactor {
kZero,
kOne,
kSource,
kOneMinusSource,
kSourceAlpha,
kOneMinusSourceAlpha,
kDest,
kOneMinusDest,
kDestAlpha,
kOneMinusDestAlpha,
kConstant,
kOneMinusConstant,
kConstantAlpha,
kOneMinusConstantAlpha,
kSourceAlphaSaturated
};
enum class BlendFunction {
kAdd,
kSubtract,
kReverseSubtract
};
enum class PrimitiveType {
kPoints,
kLines,
kLineStrip,
kTriangles,
kTriangleStrip,
kTriangleFan
};
enum class CullMode {
kNone,
kFront,
kBack
};
enum class FaceWinding {
kCounterClockwise,
kClockwise
};
enum class AttachmentLoadOp {
kLoad,
kClear,
kDontCare
};
enum class AttachmentStoreOp {
kStore,
kDontCare
};
enum class PipelineProgram {
kUnshaded,
kUnshadedPaletted
};
enum class BufferType {
kVertexBuffer,
kIndexBuffer
};
enum class BufferUsage {
kImmutable,
kDynamic
};
enum class VertexAttributeName {
kPosition,
kNormal,
kTexCoord0,
kTexCoord1,
kColor
};
enum class UniformName {
kTime,
kModelView,
kProjection,
kTexCoord0Transform
};
enum class SamplerName {
kSampler0,
kSampler1,
kSampler2,
kSampler3
};
struct Color {
float r;
float g;
float b;
float a;
};
struct Rect {
int32_t x;
int32_t y;
uint32_t w;
uint32_t h;
};
constexpr const size_t kMaxVertexAttributes = 8;
constexpr const size_t kMaxSamplers = 4;
struct ProgramVertexInput {
VertexAttributeName name;
VertexAttributeFormat type;
bool required;
};
struct ProgramUniformInput {
UniformName name;
bool required;
};
struct ProgramSamplerInput {
SamplerName name;
bool required;
};
struct ProgramVertexInputRequirements {
srb2::StaticVec<ProgramVertexInput, kMaxVertexAttributes> attributes;
};
struct ProgramUniformRequirements {
srb2::StaticVec<srb2::StaticVec<UniformName, 16>, 4> uniform_groups;
};
struct ProgramSamplerRequirements {
std::array<std::optional<ProgramSamplerInput>, kMaxSamplers> samplers;
};
struct ProgramRequirements {
ProgramVertexInputRequirements vertex_input;
ProgramUniformRequirements uniforms;
ProgramSamplerRequirements samplers;
};
extern const ProgramRequirements kProgramRequirementsUnshaded;
extern const ProgramRequirements kProgramRequirementsUnshadedPaletted;
const ProgramRequirements& program_requirements_for_program(PipelineProgram program) noexcept;
inline constexpr const VertexAttributeFormat vertex_attribute_format(VertexAttributeName name) noexcept
{
switch (name) {
case VertexAttributeName::kPosition:
return VertexAttributeFormat::kFloat3;
case VertexAttributeName::kNormal:
return VertexAttributeFormat::kFloat3;
case VertexAttributeName::kTexCoord0:
return VertexAttributeFormat::kFloat2;
case VertexAttributeName::kTexCoord1:
return VertexAttributeFormat::kFloat2;
case VertexAttributeName::kColor:
return VertexAttributeFormat::kFloat4;
default:
return VertexAttributeFormat::kFloat;
};
}
inline constexpr const UniformFormat uniform_format(UniformName name) noexcept
{
switch (name) {
case UniformName::kTime:
return UniformFormat::kFloat;
case UniformName::kModelView:
return UniformFormat::kMat4;
case UniformName::kProjection:
return UniformFormat::kMat4;
case UniformName::kTexCoord0Transform:
return UniformFormat::kMat3;
default:
return UniformFormat::kFloat;
}
}
struct VertexBufferLayoutDesc {
uint32_t stride;
};
struct VertexAttributeLayoutDesc {
VertexAttributeName name;
uint32_t buffer_index;
uint32_t offset;
};
// constexpr const size_t kMaxVertexBufferBindings = 4;
struct VertexInputDesc {
std::vector<VertexBufferLayoutDesc> buffer_layouts;
std::vector<VertexAttributeLayoutDesc> attr_layouts;
};
struct UniformInputDesc {
srb2::StaticVec<srb2::StaticVec<UniformName, 16>, 4> enabled_uniforms;
};
struct SamplerInputDesc {
std::vector<SamplerName> enabled_samplers;
};
struct ColorMask {
bool r;
bool g;
bool b;
bool a;
};
struct BlendDesc {
BlendFactor source_factor_color;
BlendFactor dest_factor_color;
BlendFunction color_function;
BlendFactor source_factor_alpha;
BlendFactor dest_factor_alpha;
BlendFunction alpha_function;
};
struct PipelineDepthAttachmentDesc {
PixelFormat format;
CompareFunc func;
bool write;
};
struct PipelineColorAttachmentDesc {
PixelFormat format;
std::optional<BlendDesc> blend;
ColorMask color_mask;
};
struct PipelineDesc {
PipelineProgram program;
VertexInputDesc vertex_input;
UniformInputDesc uniform_input;
SamplerInputDesc sampler_input;
std::optional<PipelineDepthAttachmentDesc> depth_attachment;
// std::optional<StencilAttachmentDesc> stencil_attachment;
PipelineColorAttachmentDesc color_attachment;
PrimitiveType primitive;
CullMode cull;
FaceWinding winding;
Color blend_color;
};
struct RenderPassDesc {
std::optional<PixelFormat> depth_format;
PixelFormat color_format;
AttachmentLoadOp load_op;
AttachmentStoreOp store_op;
};
struct RenderbufferDesc {
PixelFormat format;
uint32_t width;
uint32_t height;
};
struct TextureDesc {
TextureFormat format;
uint32_t width;
uint32_t height;
};
struct BufferDesc {
uint32_t size;
BufferType type;
BufferUsage usage;
};
struct RenderPassBeginInfo {
Handle<RenderPass> render_pass;
TextureOrRenderbuffer color_attachment;
std::optional<TextureOrRenderbuffer> depth_attachment;
Color clear_color;
};
using UniformVariant = std::variant<
float,
std::array<float, 2>,
std::array<float, 3>,
std::array<float, 4>,
int32_t,
std::array<int32_t, 2>,
std::array<int32_t, 3>,
std::array<int32_t, 4>,
// The indexing order of matrices is [row][column].
std::array<std::array<float, 2>, 2>,
std::array<std::array<float, 3>, 3>,
std::array<std::array<float, 4>, 4>
>;
inline constexpr UniformFormat uniform_variant_format(const UniformVariant& variant)
{
struct Visitor
{
UniformFormat operator()(const float&) const noexcept { return UniformFormat::kFloat; }
UniformFormat operator()(const std::array<float, 2>&) const noexcept { return UniformFormat::kFloat2; }
UniformFormat operator()(const std::array<float, 3>&) const noexcept { return UniformFormat::kFloat3; }
UniformFormat operator()(const std::array<float, 4>&) const noexcept { return UniformFormat::kFloat4; }
UniformFormat operator()(const int32_t&) const noexcept { return UniformFormat::kInt; }
UniformFormat operator()(const std::array<int32_t, 2>&) const noexcept { return UniformFormat::kInt2; }
UniformFormat operator()(const std::array<int32_t, 3>&) const noexcept { return UniformFormat::kInt3; }
UniformFormat operator()(const std::array<int32_t, 4>&) const noexcept { return UniformFormat::kInt4; }
UniformFormat operator()(const std::array<std::array<float, 2>, 2>&) const noexcept { return UniformFormat::kMat2; }
UniformFormat operator()(const std::array<std::array<float, 3>, 3>&) const noexcept { return UniformFormat::kMat3; }
UniformFormat operator()(const std::array<std::array<float, 4>, 4>&) const noexcept { return UniformFormat::kMat4; }
};
return std::visit(Visitor{}, variant);
}
struct VertexAttributeBufferBinding {
uint32_t attribute_index;
Handle<Buffer> vertex_buffer;
};
struct TextureBinding {
SamplerName name;
Handle<Texture> texture;
};
struct CreateUniformSetInfo {
tcb::span<UniformVariant> uniforms;
};
struct CreateBindingSetInfo {
tcb::span<VertexAttributeBufferBinding> vertex_buffers;
tcb::span<TextureBinding> sampler_textures;
};
struct UniformSet {};
struct BindingSet {};
struct TransferContext {};
struct GraphicsContext {};
/// @brief An active handle to a rendering device.
struct Rhi {
virtual ~Rhi();
virtual Handle<RenderPass> create_render_pass(const RenderPassDesc& desc) = 0;
virtual void destroy_render_pass(Handle<RenderPass> handle) = 0;
virtual Handle<Pipeline> create_pipeline(const PipelineDesc& desc) = 0;
virtual void destroy_pipeline(Handle<Pipeline> handle) = 0;
virtual Handle<Texture> create_texture(const TextureDesc& desc) = 0;
virtual void destroy_texture(Handle<Texture> handle) = 0;
virtual Handle<Buffer> create_buffer(const BufferDesc& desc) = 0;
virtual void destroy_buffer(Handle<Buffer> handle) = 0;
virtual Handle<Renderbuffer> create_renderbuffer(const RenderbufferDesc& desc) = 0;
virtual void destroy_renderbuffer(Handle<Renderbuffer> handle) = 0;
virtual Handle<TransferContext> begin_transfer() = 0;
virtual void end_transfer(Handle<TransferContext> handle) = 0;
// Transfer Context functions
virtual void update_buffer_contents(Handle<TransferContext> ctx, Handle<Buffer> buffer, uint32_t offset, tcb::span<const std::byte> data) = 0;
virtual void update_texture(Handle<TransferContext> ctx, Handle<Texture> texture, Rect region, srb2::rhi::PixelFormat data_format, tcb::span<const std::byte> data) = 0;
virtual Handle<UniformSet> create_uniform_set(Handle<TransferContext> ctx, const CreateUniformSetInfo& info) = 0;
virtual Handle<BindingSet> create_binding_set(Handle<TransferContext> ctx, Handle<Pipeline> pipeline, const CreateBindingSetInfo& info) = 0;
virtual Handle<GraphicsContext> begin_graphics() = 0;
virtual void end_graphics(Handle<GraphicsContext> ctx) = 0;
// Graphics context functions
virtual void begin_default_render_pass(Handle<GraphicsContext> ctx, bool clear) = 0;
virtual void begin_render_pass(Handle<GraphicsContext> ctx, const RenderPassBeginInfo& info) = 0;
virtual void end_render_pass(Handle<GraphicsContext> ctx) = 0;
virtual void bind_pipeline(Handle<GraphicsContext> ctx, Handle<Pipeline> pipeline) = 0;
virtual void bind_uniform_set(Handle<GraphicsContext> ctx, uint32_t slot, Handle<UniformSet> set) = 0;
virtual void bind_binding_set(Handle<GraphicsContext> ctx, Handle<BindingSet> set) = 0;
virtual void bind_index_buffer(Handle<GraphicsContext> ctx, Handle<Buffer> buffer) = 0;
virtual void set_scissor(Handle<GraphicsContext> ctx, const Rect& rect) = 0;
virtual void set_viewport(Handle<GraphicsContext> ctx, const Rect& rect) = 0;
virtual void draw(Handle<GraphicsContext> ctx, uint32_t vertex_count, uint32_t first_vertex) = 0;
virtual void draw_indexed(Handle<GraphicsContext> ctx, uint32_t index_count, uint32_t first_index) = 0;
virtual void read_pixels(Handle<GraphicsContext> ctx, const Rect& rect, tcb::span<std::byte> out) = 0;
virtual void present() = 0;
virtual void finish() = 0;
};
} // namespace srb2::rhi
#endif // __SRB2_RHI_RHI_HPP__

View file

@ -57,6 +57,8 @@ struct viddef_t
size_t rowbytes; // bytes per scanline of the VIDEO mode
INT32 width; // PIXELS per scanline
INT32 height;
UINT32 realwidth; // real pixel width of window/screen
UINT32 realheight; // real pixel height of window/screen
union { // don't need numpages for OpenGL, so we can use it for fullscreen/windowed mode
INT32 numpages; // always 1, page flipping todo
INT32 windowed; // windowed or fullscren mode?

View file

@ -3,6 +3,8 @@
target_sources(SRB2SDL2 PRIVATE
new_sound.cpp
ogl_sdl.c
rhi_gl3_core_platform.cpp
rhi_gl3_core_platform.hpp
i_threads.c
i_net.c
i_system.c

File diff suppressed because it is too large Load diff

View file

@ -359,7 +359,8 @@ void I_InitMusic(void)
SdlAudioLockHandle _;
*music_player = audio::MusicPlayer();
if (music_player != nullptr)
*music_player = audio::MusicPlayer();
}
void I_ShutdownMusic(void)

View file

@ -32,7 +32,6 @@ boolean OglSdlSurface(INT32 w, INT32 h);
void OglSdlFinishUpdate(boolean vidwait);
extern SDL_Renderer *renderer;
extern SDL_GLContext sdlglcontext;
extern Uint16 realwidth;
extern Uint16 realheight;

View file

@ -0,0 +1,56 @@
#include "rhi_gl3_core_platform.hpp"
#include <SDL.h>
#include "../cxxutil.hpp"
#include "../w_wad.h"
#include "../z_zone.h"
using namespace srb2;
using namespace srb2::rhi;
SdlGlCorePlatform::~SdlGlCorePlatform() = default;
void SdlGlCorePlatform::present() {
SRB2_ASSERT(window != nullptr);
SRB2_ASSERT(SDL_GetWindowID(window) != 0);
SDL_GL_SwapWindow(window);
}
std::tuple<std::string, std::string> SdlGlCorePlatform::find_shader_sources(rhi::PipelineProgram program) {
const char* vertex_lump_name = nullptr;
const char* fragment_lump_name = nullptr;
switch (program) {
case rhi::PipelineProgram::kUnshaded:
vertex_lump_name = "rhi_glcore_vertex_unshaded";
fragment_lump_name = "rhi_glcore_fragment_unshaded";
break;
case rhi::PipelineProgram::kUnshadedPaletted:
vertex_lump_name = "rhi_glcore_vertex_unshadedpaletted";
fragment_lump_name = "rhi_glcore_fragment_unshadedpaletted";
break;
default:
std::terminate();
}
lumpnum_t vertex_lump_num = W_GetNumForLongName(vertex_lump_name);
lumpnum_t fragment_lump_num = W_GetNumForLongName(fragment_lump_name);
size_t vertex_lump_length = W_LumpLength(vertex_lump_num);
size_t fragment_lump_length = W_LumpLength(fragment_lump_num);
void* vertex_lump = W_CacheLumpNum(vertex_lump_num, PU_CACHE);
void* fragment_lump = W_CacheLumpNum(fragment_lump_num, PU_CACHE);
std::string vertex_shader(static_cast<const char*>(vertex_lump), vertex_lump_length);
std::string fragment_shader(static_cast<const char*>(fragment_lump), fragment_lump_length);
return std::make_tuple(std::move(vertex_shader), std::move(fragment_shader));
}
rhi::Rect SdlGlCorePlatform::get_default_framebuffer_dimensions() {
SRB2_ASSERT(window != nullptr);
int w;
int h;
SDL_GL_GetDrawableSize(window, &w, &h);
return {0, 0, static_cast<uint32_t>(w), static_cast<uint32_t>(h)};
}

View file

@ -0,0 +1,23 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/rhi.hpp"
#include "../rhi/gl3_core/gl3_core_rhi.hpp"
#include <SDL.h>
namespace srb2::rhi {
struct SdlGlCorePlatform final : public GlCorePlatform {
SDL_Window* window = nullptr;
virtual ~SdlGlCorePlatform();
virtual void present() override;
virtual std::tuple<std::string, std::string> find_shader_sources(PipelineProgram program) override;
virtual Rect get_default_framebuffer_dimensions() override;
};
} // namespace srb2::rhi
#endif // __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__

View file

@ -0,0 +1,56 @@
#include "rhi_gles2_platform.hpp"
#include <SDL.h>
#include "../cxxutil.hpp"
#include "../w_wad.h"
#include "../z_zone.h"
using namespace srb2;
using namespace srb2::rhi;
SdlGles2Platform::~SdlGles2Platform() = default;
void SdlGles2Platform::present() {
SRB2_ASSERT(window != nullptr);
SRB2_ASSERT(SDL_GetWindowID(window) != 0);
SDL_GL_SwapWindow(window);
}
std::tuple<std::string, std::string> SdlGles2Platform::find_shader_sources(rhi::PipelineProgram program) {
const char* vertex_lump_name = nullptr;
const char* fragment_lump_name = nullptr;
switch (program) {
case rhi::PipelineProgram::kUnshaded:
vertex_lump_name = "rhi_glsles_vertex_unshaded";
fragment_lump_name = "rhi_glsles_fragment_unshaded";
break;
case rhi::PipelineProgram::kUnshadedPaletted:
vertex_lump_name = "rhi_glsles_vertex_unshadedpaletted";
fragment_lump_name = "rhi_glsles_fragment_unshadedpaletted";
break;
default:
std::terminate();
}
lumpnum_t vertex_lump_num = W_GetNumForLongName(vertex_lump_name);
lumpnum_t fragment_lump_num = W_GetNumForLongName(fragment_lump_name);
size_t vertex_lump_length = W_LumpLength(vertex_lump_num);
size_t fragment_lump_length = W_LumpLength(fragment_lump_num);
void* vertex_lump = W_CacheLumpNum(vertex_lump_num, PU_CACHE);
void* fragment_lump = W_CacheLumpNum(fragment_lump_num, PU_CACHE);
std::string vertex_shader(static_cast<const char*>(vertex_lump), vertex_lump_length);
std::string fragment_shader(static_cast<const char*>(fragment_lump), fragment_lump_length);
return std::make_tuple(std::move(vertex_shader), std::move(fragment_shader));
}
rhi::Rect SdlGles2Platform::get_default_framebuffer_dimensions() {
SRB2_ASSERT(window != nullptr);
int w;
int h;
SDL_GL_GetDrawableSize(window, &w, &h);
return {0, 0, static_cast<uint32_t>(w), static_cast<uint32_t>(h)};
}

View file

@ -0,0 +1,23 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/rhi.hpp"
#include "../rhi/gles2/gles2_rhi.hpp"
#include <SDL.h>
namespace srb2::rhi {
struct SdlGles2Platform final : public Gles2Platform {
SDL_Window* window = nullptr;
virtual ~SdlGles2Platform();
virtual void present() override;
virtual std::tuple<std::string, std::string> find_shader_sources(PipelineProgram program) override;
virtual Rect get_default_framebuffer_dimensions() override;
};
} // namespace srb2::rhi
#endif // __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__

View file

@ -20,6 +20,9 @@ endif()
include("cpm-rapidjson.cmake")
include("cpm-discordrpc.cmake")
include("cpm-xmp-lite.cmake")
include("cpm-fmt.cmake")
include("cpm-imgui.cmake")
add_subdirectory(tcbrindle_span)
add_subdirectory(stb_vorbis)
add_subdirectory(glad)

6
thirdparty/cpm-fmt.cmake vendored Normal file
View file

@ -0,0 +1,6 @@
CPMAddPackage(
NAME fmt
VERSION 9.1.0
URL "https://github.com/fmtlib/fmt/releases/download/9.1.0/fmt-9.1.0.zip"
EXCLUDE_FROM_ALL ON
)

34
thirdparty/cpm-imgui.cmake vendored Normal file
View file

@ -0,0 +1,34 @@
CPMAddPackage(
NAME imgui
VERSION 1.89.2
URL "https://github.com/ocornut/imgui/archive/refs/tags/v1.89.2.zip"
EXCLUDE_FROM_ALL ON
)
if(imgui_ADDED)
set(imgui_SOURCES
imgui.cpp
imgui.h
imgui_demo.cpp
imgui_draw.cpp
imgui_internal.h
imgui_tables.cpp
imgui_widgets.cpp
imstb_rectpack.h
imstb_textedit.h
imstb_truetype.h
)
list(TRANSFORM imgui_SOURCES PREPEND "${imgui_SOURCE_DIR}/")
add_custom_command(
OUTPUT "${imgui_BINARY_DIR}/include/imgui.h" "${imgui_BINARY_DIR}/include/imconfig.h"
COMMAND ${CMAKE_COMMAND} -E copy "${imgui_SOURCE_DIR}/imgui.h" "${imgui_SOURCE_DIR}/imconfig.h" "${imgui_BINARY_DIR}/include"
DEPENDS "${imgui_SOURCE_DIR}/imgui.h" "${imgui_SOURCE_DIR}/imconfig.h"
VERBATIM
)
list(APPEND imgui_SOURCES "${imgui_BINARY_DIR}/include/imgui.h" "${imgui_BINARY_DIR}/include/imconfig.h" "${CMAKE_CURRENT_SOURCE_DIR}/imgui_config/srb2_imconfig.h")
add_library(imgui STATIC ${imgui_SOURCES})
target_include_directories(imgui PUBLIC "${imgui_BINARY_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/imgui_config")
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="srb2_imconfig.h")
target_compile_features(imgui PUBLIC cxx_std_11)
add_library(imgui::imgui ALIAS imgui)
endif()

3
thirdparty/glad/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,3 @@
add_library(glad STATIC src/gles2.c src/gl.c include/glad/gles2.h include/glad/gl.h include/KHR/khrplatform.h)
add_library(glad::glad ALIAS glad)
target_include_directories(glad PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

View file

@ -0,0 +1,311 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

3795
thirdparty/glad/include/glad/gl.h vendored Normal file

File diff suppressed because it is too large Load diff

861
thirdparty/glad/include/glad/gles2.h vendored Normal file
View file

@ -0,0 +1,861 @@
/**
* Loader generated by glad 2.0.2 on Sun Jan 8 22:32:41 2023
*
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
*
* Generator: C/C++
* Specification: gl
* Extensions: 1
*
* APIs:
* - gles2=2.0
*
* Options:
* - ALIAS = True
* - DEBUG = False
* - HEADER_ONLY = False
* - LOADER = False
* - MX = True
* - ON_DEMAND = False
*
* Commandline:
* --api='gles2=2.0' --extensions='GL_OES_rgb8_rgba8' c --alias --mx
*
* Online:
* http://glad.sh/#api=gles2%3D2.0&extensions=GL_OES_rgb8_rgba8&generator=c&options=ALIAS%2CMX
*
*/
#ifndef GLAD_GLES2_H_
#define GLAD_GLES2_H_
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#endif
#ifdef __gl2_h_
#error OpenGL ES 2 header already included (API: gles2), remove previous include!
#endif
#define __gl2_h_ 1
#ifdef __gles2_gl2_h_
#error OpenGL ES 2 header already included (API: gles2), remove previous include!
#endif
#define __gles2_gl2_h_ 1
#ifdef __gl3_h_
#error OpenGL ES 3 header already included (API: gles2), remove previous include!
#endif
#define __gl3_h_ 1
#ifdef __gles2_gl3_h_
#error OpenGL ES 3 header already included (API: gles2), remove previous include!
#endif
#define __gles2_gl3_h_ 1
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#define GLAD_GLES2
#define GLAD_OPTION_GLES2_ALIAS
#define GLAD_OPTION_GLES2_MX
#ifdef __cplusplus
extern "C" {
#endif
#ifndef GLAD_PLATFORM_H_
#define GLAD_PLATFORM_H_
#ifndef GLAD_PLATFORM_WIN32
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)
#define GLAD_PLATFORM_WIN32 1
#else
#define GLAD_PLATFORM_WIN32 0
#endif
#endif
#ifndef GLAD_PLATFORM_APPLE
#ifdef __APPLE__
#define GLAD_PLATFORM_APPLE 1
#else
#define GLAD_PLATFORM_APPLE 0
#endif
#endif
#ifndef GLAD_PLATFORM_EMSCRIPTEN
#ifdef __EMSCRIPTEN__
#define GLAD_PLATFORM_EMSCRIPTEN 1
#else
#define GLAD_PLATFORM_EMSCRIPTEN 0
#endif
#endif
#ifndef GLAD_PLATFORM_UWP
#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY)
#ifdef __has_include
#if __has_include(<winapifamily.h>)
#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
#endif
#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_
#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1
#endif
#endif
#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY
#include <winapifamily.h>
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#define GLAD_PLATFORM_UWP 1
#endif
#endif
#ifndef GLAD_PLATFORM_UWP
#define GLAD_PLATFORM_UWP 0
#endif
#endif
#ifdef __GNUC__
#define GLAD_GNUC_EXTENSION __extension__
#else
#define GLAD_GNUC_EXTENSION
#endif
#define GLAD_UNUSED(x) (void)(x)
#ifndef GLAD_API_CALL
#if defined(GLAD_API_CALL_EXPORT)
#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__)
#if defined(GLAD_API_CALL_EXPORT_BUILD)
#if defined(__GNUC__)
#define GLAD_API_CALL __attribute__ ((dllexport)) extern
#else
#define GLAD_API_CALL __declspec(dllexport) extern
#endif
#else
#if defined(__GNUC__)
#define GLAD_API_CALL __attribute__ ((dllimport)) extern
#else
#define GLAD_API_CALL __declspec(dllimport) extern
#endif
#endif
#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD)
#define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern
#else
#define GLAD_API_CALL extern
#endif
#else
#define GLAD_API_CALL extern
#endif
#endif
#ifdef APIENTRY
#define GLAD_API_PTR APIENTRY
#elif GLAD_PLATFORM_WIN32
#define GLAD_API_PTR __stdcall
#else
#define GLAD_API_PTR
#endif
#ifndef GLAPI
#define GLAPI GLAD_API_CALL
#endif
#ifndef GLAPIENTRY
#define GLAPIENTRY GLAD_API_PTR
#endif
#define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor)
#define GLAD_VERSION_MAJOR(version) (version / 10000)
#define GLAD_VERSION_MINOR(version) (version % 10000)
#define GLAD_GENERATOR_VERSION "2.0.2"
typedef void (*GLADapiproc)(void);
typedef GLADapiproc (*GLADloadfunc)(const char *name);
typedef GLADapiproc (*GLADuserptrloadfunc)(void *userptr, const char *name);
typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...);
typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...);
#endif /* GLAD_PLATFORM_H_ */
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_ACTIVE_TEXTURE 0x84E0
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALPHA 0x1906
#define GL_ALPHA_BITS 0x0D55
#define GL_ALWAYS 0x0207
#define GL_ARRAY_BUFFER 0x8892
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_BACK 0x0405
#define GL_BLEND 0x0BE2
#define GL_BLEND_COLOR 0x8005
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_EQUATION 0x8009
#define GL_BLEND_EQUATION_ALPHA 0x883D
#define GL_BLEND_EQUATION_RGB 0x8009
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLUE_BITS 0x0D54
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_BYTE 0x1400
#define GL_CCW 0x0901
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_COLOR_CLEAR_VALUE 0x0C22
#define GL_COLOR_WRITEMASK 0x0C23
#define GL_COMPILE_STATUS 0x8B81
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
#define GL_CONSTANT_ALPHA 0x8003
#define GL_CONSTANT_COLOR 0x8001
#define GL_CULL_FACE 0x0B44
#define GL_CULL_FACE_MODE 0x0B45
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
#define GL_CW 0x0900
#define GL_DECR 0x1E03
#define GL_DECR_WRAP 0x8508
#define GL_DELETE_STATUS 0x8B80
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_DEPTH_BITS 0x0D56
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_DEPTH_CLEAR_VALUE 0x0B73
#define GL_DEPTH_COMPONENT 0x1902
#define GL_DEPTH_COMPONENT16 0x81A5
#define GL_DEPTH_FUNC 0x0B74
#define GL_DEPTH_RANGE 0x0B70
#define GL_DEPTH_TEST 0x0B71
#define GL_DEPTH_WRITEMASK 0x0B72
#define GL_DITHER 0x0BD0
#define GL_DONT_CARE 0x1100
#define GL_DST_ALPHA 0x0304
#define GL_DST_COLOR 0x0306
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_EQUAL 0x0202
#define GL_EXTENSIONS 0x1F03
#define GL_FALSE 0
#define GL_FASTEST 0x1101
#define GL_FIXED 0x140C
#define GL_FLOAT 0x1406
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_FRAMEBUFFER 0x8D40
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
#define GL_FRAMEBUFFER_BINDING 0x8CA6
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_FRONT 0x0404
#define GL_FRONT_AND_BACK 0x0408
#define GL_FRONT_FACE 0x0B46
#define GL_FUNC_ADD 0x8006
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
#define GL_FUNC_SUBTRACT 0x800A
#define GL_GENERATE_MIPMAP_HINT 0x8192
#define GL_GEQUAL 0x0206
#define GL_GREATER 0x0204
#define GL_GREEN_BITS 0x0D53
#define GL_HIGH_FLOAT 0x8DF2
#define GL_HIGH_INT 0x8DF5
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
#define GL_INCR 0x1E02
#define GL_INCR_WRAP 0x8507
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_INT 0x1404
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_INVALID_ENUM 0x0500
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
#define GL_INVALID_OPERATION 0x0502
#define GL_INVALID_VALUE 0x0501
#define GL_INVERT 0x150A
#define GL_KEEP 0x1E00
#define GL_LEQUAL 0x0203
#define GL_LESS 0x0201
#define GL_LINEAR 0x2601
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
#define GL_LINES 0x0001
#define GL_LINE_LOOP 0x0002
#define GL_LINE_STRIP 0x0003
#define GL_LINE_WIDTH 0x0B21
#define GL_LINK_STATUS 0x8B82
#define GL_LOW_FLOAT 0x8DF0
#define GL_LOW_INT 0x8DF3
#define GL_LUMINANCE 0x1909
#define GL_LUMINANCE_ALPHA 0x190A
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GL_MEDIUM_FLOAT 0x8DF1
#define GL_MEDIUM_INT 0x8DF4
#define GL_MIRRORED_REPEAT 0x8370
#define GL_NEAREST 0x2600
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
#define GL_NEVER 0x0200
#define GL_NICEST 0x1102
#define GL_NONE 0
#define GL_NOTEQUAL 0x0205
#define GL_NO_ERROR 0
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
#define GL_ONE 1
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_ONE_MINUS_DST_ALPHA 0x0305
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_ONE_MINUS_SRC_COLOR 0x0301
#define GL_OUT_OF_MEMORY 0x0505
#define GL_PACK_ALIGNMENT 0x0D05
#define GL_POINTS 0x0000
#define GL_POLYGON_OFFSET_FACTOR 0x8038
#define GL_POLYGON_OFFSET_FILL 0x8037
#define GL_POLYGON_OFFSET_UNITS 0x2A00
#define GL_RED_BITS 0x0D52
#define GL_RENDERBUFFER 0x8D41
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
#define GL_RENDERBUFFER_BINDING 0x8CA7
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
#define GL_RENDERBUFFER_HEIGHT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_RENDERBUFFER_WIDTH 0x8D42
#define GL_RENDERER 0x1F01
#define GL_REPEAT 0x2901
#define GL_REPLACE 0x1E01
#define GL_RGB 0x1907
#define GL_RGB565 0x8D62
#define GL_RGB5_A1 0x8057
#define GL_RGB8_OES 0x8051
#define GL_RGBA 0x1908
#define GL_RGBA4 0x8056
#define GL_RGBA8_OES 0x8058
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_CUBE 0x8B60
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLE_COVERAGE 0x80A0
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SCISSOR_BOX 0x0C10
#define GL_SCISSOR_TEST 0x0C11
#define GL_SHADER_BINARY_FORMATS 0x8DF8
#define GL_SHADER_COMPILER 0x8DFA
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_SHADER_TYPE 0x8B4F
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_SHORT 0x1402
#define GL_SRC_ALPHA 0x0302
#define GL_SRC_ALPHA_SATURATE 0x0308
#define GL_SRC_COLOR 0x0300
#define GL_STATIC_DRAW 0x88E4
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_STENCIL_BACK_FAIL 0x8801
#define GL_STENCIL_BACK_FUNC 0x8800
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
#define GL_STENCIL_BACK_REF 0x8CA3
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_STENCIL_BITS 0x0D57
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_STENCIL_CLEAR_VALUE 0x0B91
#define GL_STENCIL_FAIL 0x0B94
#define GL_STENCIL_FUNC 0x0B92
#define GL_STENCIL_INDEX8 0x8D48
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
#define GL_STENCIL_REF 0x0B97
#define GL_STENCIL_TEST 0x0B90
#define GL_STENCIL_VALUE_MASK 0x0B93
#define GL_STENCIL_WRITEMASK 0x0B98
#define GL_STREAM_DRAW 0x88E0
#define GL_SUBPIXEL_BITS 0x0D50
#define GL_TEXTURE 0x1702
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE10 0x84CA
#define GL_TEXTURE11 0x84CB
#define GL_TEXTURE12 0x84CC
#define GL_TEXTURE13 0x84CD
#define GL_TEXTURE14 0x84CE
#define GL_TEXTURE15 0x84CF
#define GL_TEXTURE16 0x84D0
#define GL_TEXTURE17 0x84D1
#define GL_TEXTURE18 0x84D2
#define GL_TEXTURE19 0x84D3
#define GL_TEXTURE2 0x84C2
#define GL_TEXTURE20 0x84D4
#define GL_TEXTURE21 0x84D5
#define GL_TEXTURE22 0x84D6
#define GL_TEXTURE23 0x84D7
#define GL_TEXTURE24 0x84D8
#define GL_TEXTURE25 0x84D9
#define GL_TEXTURE26 0x84DA
#define GL_TEXTURE27 0x84DB
#define GL_TEXTURE28 0x84DC
#define GL_TEXTURE29 0x84DD
#define GL_TEXTURE3 0x84C3
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_TEXTURE4 0x84C4
#define GL_TEXTURE5 0x84C5
#define GL_TEXTURE6 0x84C6
#define GL_TEXTURE7 0x84C7
#define GL_TEXTURE8 0x84C8
#define GL_TEXTURE9 0x84C9
#define GL_TEXTURE_2D 0x0DE1
#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
#define GL_TRIANGLES 0x0004
#define GL_TRIANGLE_FAN 0x0006
#define GL_TRIANGLE_STRIP 0x0005
#define GL_TRUE 1
#define GL_UNPACK_ALIGNMENT 0x0CF5
#define GL_UNSIGNED_BYTE 0x1401
#define GL_UNSIGNED_INT 0x1405
#define GL_UNSIGNED_SHORT 0x1403
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GL_VALIDATE_STATUS 0x8B83
#define GL_VENDOR 0x1F00
#define GL_VERSION 0x1F02
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_SHADER 0x8B31
#define GL_VIEWPORT 0x0BA2
#define GL_ZERO 0
#include <KHR/khrplatform.h>
typedef unsigned int GLenum;
typedef unsigned char GLboolean;
typedef unsigned int GLbitfield;
typedef void GLvoid;
typedef khronos_int8_t GLbyte;
typedef khronos_uint8_t GLubyte;
typedef khronos_int16_t GLshort;
typedef khronos_uint16_t GLushort;
typedef int GLint;
typedef unsigned int GLuint;
typedef khronos_int32_t GLclampx;
typedef int GLsizei;
typedef khronos_float_t GLfloat;
typedef khronos_float_t GLclampf;
typedef double GLdouble;
typedef double GLclampd;
typedef void *GLeglClientBufferEXT;
typedef void *GLeglImageOES;
typedef char GLchar;
typedef char GLcharARB;
#ifdef __APPLE__
typedef void *GLhandleARB;
#else
typedef unsigned int GLhandleARB;
#endif
typedef khronos_uint16_t GLhalf;
typedef khronos_uint16_t GLhalfARB;
typedef khronos_int32_t GLfixed;
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptr;
#else
typedef khronos_intptr_t GLintptr;
#endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_intptr_t GLintptrARB;
#else
typedef khronos_intptr_t GLintptrARB;
#endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptr;
#else
typedef khronos_ssize_t GLsizeiptr;
#endif
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
typedef khronos_ssize_t GLsizeiptrARB;
#else
typedef khronos_ssize_t GLsizeiptrARB;
#endif
typedef khronos_int64_t GLint64;
typedef khronos_int64_t GLint64EXT;
typedef khronos_uint64_t GLuint64;
typedef khronos_uint64_t GLuint64EXT;
typedef struct __GLsync *GLsync;
struct _cl_context;
struct _cl_event;
typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
typedef unsigned short GLhalfNV;
typedef GLintptr GLvdpauSurfaceNV;
typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void);
#define GL_ES_VERSION_2_0 1
#define GL_OES_rgb8_rgba8 1
typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture);
typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name);
typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode);
typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha);
typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage);
typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data);
typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask);
typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d);
typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s);
typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader);
typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data);
typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data);
typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void);
typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type);
typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode);
typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers);
typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers);
typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program);
typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers);
typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader);
typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures);
typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func);
typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag);
typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f);
typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap);
typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices);
typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap);
typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void);
typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void);
typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode);
typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers);
typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers);
typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers);
typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures);
typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target);
typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name);
typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders);
typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name);
typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data);
typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void);
typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data);
typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params);
typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data);
typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params);
typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog);
typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision);
typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source);
typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params);
typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name);
typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params);
typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params);
typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name);
typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params);
typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params);
typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer);
typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params);
typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params);
typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode);
typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer);
typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap);
typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer);
typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program);
typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer);
typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader);
typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture);
typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width);
typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program);
typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param);
typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units);
typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels);
typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void);
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert);
typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length);
typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length);
typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask);
typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask);
typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask);
typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask);
typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass);
typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels);
typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param);
typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params);
typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params);
typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels);
typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1);
typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2);
typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program);
typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v);
typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer);
typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
typedef struct GladGLES2Context {
void* userptr;
int ES_VERSION_2_0;
int OES_rgb8_rgba8;
PFNGLACTIVETEXTUREPROC ActiveTexture;
PFNGLATTACHSHADERPROC AttachShader;
PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation;
PFNGLBINDBUFFERPROC BindBuffer;
PFNGLBINDFRAMEBUFFERPROC BindFramebuffer;
PFNGLBINDRENDERBUFFERPROC BindRenderbuffer;
PFNGLBINDTEXTUREPROC BindTexture;
PFNGLBLENDCOLORPROC BlendColor;
PFNGLBLENDEQUATIONPROC BlendEquation;
PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate;
PFNGLBLENDFUNCPROC BlendFunc;
PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
PFNGLBUFFERDATAPROC BufferData;
PFNGLBUFFERSUBDATAPROC BufferSubData;
PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus;
PFNGLCLEARPROC Clear;
PFNGLCLEARCOLORPROC ClearColor;
PFNGLCLEARDEPTHFPROC ClearDepthf;
PFNGLCLEARSTENCILPROC ClearStencil;
PFNGLCOLORMASKPROC ColorMask;
PFNGLCOMPILESHADERPROC CompileShader;
PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D;
PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D;
PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D;
PFNGLCREATEPROGRAMPROC CreateProgram;
PFNGLCREATESHADERPROC CreateShader;
PFNGLCULLFACEPROC CullFace;
PFNGLDELETEBUFFERSPROC DeleteBuffers;
PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers;
PFNGLDELETEPROGRAMPROC DeleteProgram;
PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers;
PFNGLDELETESHADERPROC DeleteShader;
PFNGLDELETETEXTURESPROC DeleteTextures;
PFNGLDEPTHFUNCPROC DepthFunc;
PFNGLDEPTHMASKPROC DepthMask;
PFNGLDEPTHRANGEFPROC DepthRangef;
PFNGLDETACHSHADERPROC DetachShader;
PFNGLDISABLEPROC Disable;
PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray;
PFNGLDRAWARRAYSPROC DrawArrays;
PFNGLDRAWELEMENTSPROC DrawElements;
PFNGLENABLEPROC Enable;
PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
PFNGLFINISHPROC Finish;
PFNGLFLUSHPROC Flush;
PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer;
PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D;
PFNGLFRONTFACEPROC FrontFace;
PFNGLGENBUFFERSPROC GenBuffers;
PFNGLGENFRAMEBUFFERSPROC GenFramebuffers;
PFNGLGENRENDERBUFFERSPROC GenRenderbuffers;
PFNGLGENTEXTURESPROC GenTextures;
PFNGLGENERATEMIPMAPPROC GenerateMipmap;
PFNGLGETACTIVEATTRIBPROC GetActiveAttrib;
PFNGLGETACTIVEUNIFORMPROC GetActiveUniform;
PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders;
PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
PFNGLGETBOOLEANVPROC GetBooleanv;
PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv;
PFNGLGETERRORPROC GetError;
PFNGLGETFLOATVPROC GetFloatv;
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv;
PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
PFNGLGETPROGRAMIVPROC GetProgramiv;
PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv;
PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
PFNGLGETSHADERPRECISIONFORMATPROC GetShaderPrecisionFormat;
PFNGLGETSHADERSOURCEPROC GetShaderSource;
PFNGLGETSHADERIVPROC GetShaderiv;
PFNGLGETSTRINGPROC GetString;
PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv;
PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv;
PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
PFNGLGETUNIFORMFVPROC GetUniformfv;
PFNGLGETUNIFORMIVPROC GetUniformiv;
PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv;
PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv;
PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv;
PFNGLHINTPROC Hint;
PFNGLISBUFFERPROC IsBuffer;
PFNGLISENABLEDPROC IsEnabled;
PFNGLISFRAMEBUFFERPROC IsFramebuffer;
PFNGLISPROGRAMPROC IsProgram;
PFNGLISRENDERBUFFERPROC IsRenderbuffer;
PFNGLISSHADERPROC IsShader;
PFNGLISTEXTUREPROC IsTexture;
PFNGLLINEWIDTHPROC LineWidth;
PFNGLLINKPROGRAMPROC LinkProgram;
PFNGLPIXELSTOREIPROC PixelStorei;
PFNGLPOLYGONOFFSETPROC PolygonOffset;
PFNGLREADPIXELSPROC ReadPixels;
PFNGLRELEASESHADERCOMPILERPROC ReleaseShaderCompiler;
PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage;
PFNGLSAMPLECOVERAGEPROC SampleCoverage;
PFNGLSCISSORPROC Scissor;
PFNGLSHADERBINARYPROC ShaderBinary;
PFNGLSHADERSOURCEPROC ShaderSource;
PFNGLSTENCILFUNCPROC StencilFunc;
PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate;
PFNGLSTENCILMASKPROC StencilMask;
PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate;
PFNGLSTENCILOPPROC StencilOp;
PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate;
PFNGLTEXIMAGE2DPROC TexImage2D;
PFNGLTEXPARAMETERFPROC TexParameterf;
PFNGLTEXPARAMETERFVPROC TexParameterfv;
PFNGLTEXPARAMETERIPROC TexParameteri;
PFNGLTEXPARAMETERIVPROC TexParameteriv;
PFNGLTEXSUBIMAGE2DPROC TexSubImage2D;
PFNGLUNIFORM1FPROC Uniform1f;
PFNGLUNIFORM1FVPROC Uniform1fv;
PFNGLUNIFORM1IPROC Uniform1i;
PFNGLUNIFORM1IVPROC Uniform1iv;
PFNGLUNIFORM2FPROC Uniform2f;
PFNGLUNIFORM2FVPROC Uniform2fv;
PFNGLUNIFORM2IPROC Uniform2i;
PFNGLUNIFORM2IVPROC Uniform2iv;
PFNGLUNIFORM3FPROC Uniform3f;
PFNGLUNIFORM3FVPROC Uniform3fv;
PFNGLUNIFORM3IPROC Uniform3i;
PFNGLUNIFORM3IVPROC Uniform3iv;
PFNGLUNIFORM4FPROC Uniform4f;
PFNGLUNIFORM4FVPROC Uniform4fv;
PFNGLUNIFORM4IPROC Uniform4i;
PFNGLUNIFORM4IVPROC Uniform4iv;
PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv;
PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv;
PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
PFNGLUSEPROGRAMPROC UseProgram;
PFNGLVALIDATEPROGRAMPROC ValidateProgram;
PFNGLVERTEXATTRIB1FPROC VertexAttrib1f;
PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv;
PFNGLVERTEXATTRIB2FPROC VertexAttrib2f;
PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv;
PFNGLVERTEXATTRIB3FPROC VertexAttrib3f;
PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv;
PFNGLVERTEXATTRIB4FPROC VertexAttrib4f;
PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv;
PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
PFNGLVIEWPORTPROC Viewport;
} GladGLES2Context;
GLAD_API_CALL int gladLoadGLES2ContextUserPtr(GladGLES2Context *context, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoadGLES2Context(GladGLES2Context *context, GLADloadfunc load);
#ifdef __cplusplus
}
#endif
#endif

2274
thirdparty/glad/src/gl.c vendored Normal file

File diff suppressed because it is too large Load diff

351
thirdparty/glad/src/gles2.c vendored Normal file
View file

@ -0,0 +1,351 @@
/**
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glad/gles2.h>
#ifndef GLAD_IMPL_UTIL_C_
#define GLAD_IMPL_UTIL_C_
#ifdef _MSC_VER
#define GLAD_IMPL_UTIL_SSCANF sscanf_s
#else
#define GLAD_IMPL_UTIL_SSCANF sscanf
#endif
#endif /* GLAD_IMPL_UTIL_C_ */
#ifdef __cplusplus
extern "C" {
#endif
static void glad_gl_load_GL_ES_VERSION_2_0(GladGLES2Context *context, GLADuserptrloadfunc load, void* userptr) {
if(!context->ES_VERSION_2_0) return;
context->ActiveTexture = (PFNGLACTIVETEXTUREPROC) load(userptr, "glActiveTexture");
context->AttachShader = (PFNGLATTACHSHADERPROC) load(userptr, "glAttachShader");
context->BindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load(userptr, "glBindAttribLocation");
context->BindBuffer = (PFNGLBINDBUFFERPROC) load(userptr, "glBindBuffer");
context->BindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load(userptr, "glBindFramebuffer");
context->BindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load(userptr, "glBindRenderbuffer");
context->BindTexture = (PFNGLBINDTEXTUREPROC) load(userptr, "glBindTexture");
context->BlendColor = (PFNGLBLENDCOLORPROC) load(userptr, "glBlendColor");
context->BlendEquation = (PFNGLBLENDEQUATIONPROC) load(userptr, "glBlendEquation");
context->BlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load(userptr, "glBlendEquationSeparate");
context->BlendFunc = (PFNGLBLENDFUNCPROC) load(userptr, "glBlendFunc");
context->BlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load(userptr, "glBlendFuncSeparate");
context->BufferData = (PFNGLBUFFERDATAPROC) load(userptr, "glBufferData");
context->BufferSubData = (PFNGLBUFFERSUBDATAPROC) load(userptr, "glBufferSubData");
context->CheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckFramebufferStatus");
context->Clear = (PFNGLCLEARPROC) load(userptr, "glClear");
context->ClearColor = (PFNGLCLEARCOLORPROC) load(userptr, "glClearColor");
context->ClearDepthf = (PFNGLCLEARDEPTHFPROC) load(userptr, "glClearDepthf");
context->ClearStencil = (PFNGLCLEARSTENCILPROC) load(userptr, "glClearStencil");
context->ColorMask = (PFNGLCOLORMASKPROC) load(userptr, "glColorMask");
context->CompileShader = (PFNGLCOMPILESHADERPROC) load(userptr, "glCompileShader");
context->CompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load(userptr, "glCompressedTexImage2D");
context->CompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load(userptr, "glCompressedTexSubImage2D");
context->CopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load(userptr, "glCopyTexImage2D");
context->CopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load(userptr, "glCopyTexSubImage2D");
context->CreateProgram = (PFNGLCREATEPROGRAMPROC) load(userptr, "glCreateProgram");
context->CreateShader = (PFNGLCREATESHADERPROC) load(userptr, "glCreateShader");
context->CullFace = (PFNGLCULLFACEPROC) load(userptr, "glCullFace");
context->DeleteBuffers = (PFNGLDELETEBUFFERSPROC) load(userptr, "glDeleteBuffers");
context->DeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load(userptr, "glDeleteFramebuffers");
context->DeleteProgram = (PFNGLDELETEPROGRAMPROC) load(userptr, "glDeleteProgram");
context->DeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load(userptr, "glDeleteRenderbuffers");
context->DeleteShader = (PFNGLDELETESHADERPROC) load(userptr, "glDeleteShader");
context->DeleteTextures = (PFNGLDELETETEXTURESPROC) load(userptr, "glDeleteTextures");
context->DepthFunc = (PFNGLDEPTHFUNCPROC) load(userptr, "glDepthFunc");
context->DepthMask = (PFNGLDEPTHMASKPROC) load(userptr, "glDepthMask");
context->DepthRangef = (PFNGLDEPTHRANGEFPROC) load(userptr, "glDepthRangef");
context->DetachShader = (PFNGLDETACHSHADERPROC) load(userptr, "glDetachShader");
context->Disable = (PFNGLDISABLEPROC) load(userptr, "glDisable");
context->DisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load(userptr, "glDisableVertexAttribArray");
context->DrawArrays = (PFNGLDRAWARRAYSPROC) load(userptr, "glDrawArrays");
context->DrawElements = (PFNGLDRAWELEMENTSPROC) load(userptr, "glDrawElements");
context->Enable = (PFNGLENABLEPROC) load(userptr, "glEnable");
context->EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load(userptr, "glEnableVertexAttribArray");
context->Finish = (PFNGLFINISHPROC) load(userptr, "glFinish");
context->Flush = (PFNGLFLUSHPROC) load(userptr, "glFlush");
context->FramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glFramebufferRenderbuffer");
context->FramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load(userptr, "glFramebufferTexture2D");
context->FrontFace = (PFNGLFRONTFACEPROC) load(userptr, "glFrontFace");
context->GenBuffers = (PFNGLGENBUFFERSPROC) load(userptr, "glGenBuffers");
context->GenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load(userptr, "glGenFramebuffers");
context->GenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load(userptr, "glGenRenderbuffers");
context->GenTextures = (PFNGLGENTEXTURESPROC) load(userptr, "glGenTextures");
context->GenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load(userptr, "glGenerateMipmap");
context->GetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load(userptr, "glGetActiveAttrib");
context->GetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load(userptr, "glGetActiveUniform");
context->GetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load(userptr, "glGetAttachedShaders");
context->GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load(userptr, "glGetAttribLocation");
context->GetBooleanv = (PFNGLGETBOOLEANVPROC) load(userptr, "glGetBooleanv");
context->GetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load(userptr, "glGetBufferParameteriv");
context->GetError = (PFNGLGETERRORPROC) load(userptr, "glGetError");
context->GetFloatv = (PFNGLGETFLOATVPROC) load(userptr, "glGetFloatv");
context->GetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetFramebufferAttachmentParameteriv");
context->GetIntegerv = (PFNGLGETINTEGERVPROC) load(userptr, "glGetIntegerv");
context->GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load(userptr, "glGetProgramInfoLog");
context->GetProgramiv = (PFNGLGETPROGRAMIVPROC) load(userptr, "glGetProgramiv");
context->GetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetRenderbufferParameteriv");
context->GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load(userptr, "glGetShaderInfoLog");
context->GetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load(userptr, "glGetShaderPrecisionFormat");
context->GetShaderSource = (PFNGLGETSHADERSOURCEPROC) load(userptr, "glGetShaderSource");
context->GetShaderiv = (PFNGLGETSHADERIVPROC) load(userptr, "glGetShaderiv");
context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString");
context->GetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load(userptr, "glGetTexParameterfv");
context->GetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load(userptr, "glGetTexParameteriv");
context->GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load(userptr, "glGetUniformLocation");
context->GetUniformfv = (PFNGLGETUNIFORMFVPROC) load(userptr, "glGetUniformfv");
context->GetUniformiv = (PFNGLGETUNIFORMIVPROC) load(userptr, "glGetUniformiv");
context->GetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load(userptr, "glGetVertexAttribPointerv");
context->GetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load(userptr, "glGetVertexAttribfv");
context->GetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load(userptr, "glGetVertexAttribiv");
context->Hint = (PFNGLHINTPROC) load(userptr, "glHint");
context->IsBuffer = (PFNGLISBUFFERPROC) load(userptr, "glIsBuffer");
context->IsEnabled = (PFNGLISENABLEDPROC) load(userptr, "glIsEnabled");
context->IsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load(userptr, "glIsFramebuffer");
context->IsProgram = (PFNGLISPROGRAMPROC) load(userptr, "glIsProgram");
context->IsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load(userptr, "glIsRenderbuffer");
context->IsShader = (PFNGLISSHADERPROC) load(userptr, "glIsShader");
context->IsTexture = (PFNGLISTEXTUREPROC) load(userptr, "glIsTexture");
context->LineWidth = (PFNGLLINEWIDTHPROC) load(userptr, "glLineWidth");
context->LinkProgram = (PFNGLLINKPROGRAMPROC) load(userptr, "glLinkProgram");
context->PixelStorei = (PFNGLPIXELSTOREIPROC) load(userptr, "glPixelStorei");
context->PolygonOffset = (PFNGLPOLYGONOFFSETPROC) load(userptr, "glPolygonOffset");
context->ReadPixels = (PFNGLREADPIXELSPROC) load(userptr, "glReadPixels");
context->ReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load(userptr, "glReleaseShaderCompiler");
context->RenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load(userptr, "glRenderbufferStorage");
context->SampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load(userptr, "glSampleCoverage");
context->Scissor = (PFNGLSCISSORPROC) load(userptr, "glScissor");
context->ShaderBinary = (PFNGLSHADERBINARYPROC) load(userptr, "glShaderBinary");
context->ShaderSource = (PFNGLSHADERSOURCEPROC) load(userptr, "glShaderSource");
context->StencilFunc = (PFNGLSTENCILFUNCPROC) load(userptr, "glStencilFunc");
context->StencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load(userptr, "glStencilFuncSeparate");
context->StencilMask = (PFNGLSTENCILMASKPROC) load(userptr, "glStencilMask");
context->StencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load(userptr, "glStencilMaskSeparate");
context->StencilOp = (PFNGLSTENCILOPPROC) load(userptr, "glStencilOp");
context->StencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load(userptr, "glStencilOpSeparate");
context->TexImage2D = (PFNGLTEXIMAGE2DPROC) load(userptr, "glTexImage2D");
context->TexParameterf = (PFNGLTEXPARAMETERFPROC) load(userptr, "glTexParameterf");
context->TexParameterfv = (PFNGLTEXPARAMETERFVPROC) load(userptr, "glTexParameterfv");
context->TexParameteri = (PFNGLTEXPARAMETERIPROC) load(userptr, "glTexParameteri");
context->TexParameteriv = (PFNGLTEXPARAMETERIVPROC) load(userptr, "glTexParameteriv");
context->TexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load(userptr, "glTexSubImage2D");
context->Uniform1f = (PFNGLUNIFORM1FPROC) load(userptr, "glUniform1f");
context->Uniform1fv = (PFNGLUNIFORM1FVPROC) load(userptr, "glUniform1fv");
context->Uniform1i = (PFNGLUNIFORM1IPROC) load(userptr, "glUniform1i");
context->Uniform1iv = (PFNGLUNIFORM1IVPROC) load(userptr, "glUniform1iv");
context->Uniform2f = (PFNGLUNIFORM2FPROC) load(userptr, "glUniform2f");
context->Uniform2fv = (PFNGLUNIFORM2FVPROC) load(userptr, "glUniform2fv");
context->Uniform2i = (PFNGLUNIFORM2IPROC) load(userptr, "glUniform2i");
context->Uniform2iv = (PFNGLUNIFORM2IVPROC) load(userptr, "glUniform2iv");
context->Uniform3f = (PFNGLUNIFORM3FPROC) load(userptr, "glUniform3f");
context->Uniform3fv = (PFNGLUNIFORM3FVPROC) load(userptr, "glUniform3fv");
context->Uniform3i = (PFNGLUNIFORM3IPROC) load(userptr, "glUniform3i");
context->Uniform3iv = (PFNGLUNIFORM3IVPROC) load(userptr, "glUniform3iv");
context->Uniform4f = (PFNGLUNIFORM4FPROC) load(userptr, "glUniform4f");
context->Uniform4fv = (PFNGLUNIFORM4FVPROC) load(userptr, "glUniform4fv");
context->Uniform4i = (PFNGLUNIFORM4IPROC) load(userptr, "glUniform4i");
context->Uniform4iv = (PFNGLUNIFORM4IVPROC) load(userptr, "glUniform4iv");
context->UniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load(userptr, "glUniformMatrix2fv");
context->UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load(userptr, "glUniformMatrix3fv");
context->UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load(userptr, "glUniformMatrix4fv");
context->UseProgram = (PFNGLUSEPROGRAMPROC) load(userptr, "glUseProgram");
context->ValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load(userptr, "glValidateProgram");
context->VertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load(userptr, "glVertexAttrib1f");
context->VertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load(userptr, "glVertexAttrib1fv");
context->VertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load(userptr, "glVertexAttrib2f");
context->VertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load(userptr, "glVertexAttrib2fv");
context->VertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load(userptr, "glVertexAttrib3f");
context->VertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load(userptr, "glVertexAttrib3fv");
context->VertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load(userptr, "glVertexAttrib4f");
context->VertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load(userptr, "glVertexAttrib4fv");
context->VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load(userptr, "glVertexAttribPointer");
context->Viewport = (PFNGLVIEWPORTPROC) load(userptr, "glViewport");
}
static void glad_gl_resolve_aliases(GladGLES2Context *context) {
}
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
#define GLAD_GL_IS_SOME_NEW_VERSION 1
#else
#define GLAD_GL_IS_SOME_NEW_VERSION 0
#endif
static int glad_gl_get_extensions(GladGLES2Context *context, int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) {
#if GLAD_GL_IS_SOME_NEW_VERSION
if(GLAD_VERSION_MAJOR(version) < 3) {
#else
GLAD_UNUSED(version);
GLAD_UNUSED(out_num_exts_i);
GLAD_UNUSED(out_exts_i);
#endif
if (context->GetString == NULL) {
return 0;
}
*out_exts = (const char *)context->GetString(GL_EXTENSIONS);
#if GLAD_GL_IS_SOME_NEW_VERSION
} else {
unsigned int index = 0;
unsigned int num_exts_i = 0;
char **exts_i = NULL;
if (context->GetStringi == NULL || context->GetIntegerv == NULL) {
return 0;
}
context->GetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i);
if (num_exts_i > 0) {
exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i));
}
if (exts_i == NULL) {
return 0;
}
for(index = 0; index < num_exts_i; index++) {
const char *gl_str_tmp = (const char*) context->GetStringi(GL_EXTENSIONS, index);
size_t len = strlen(gl_str_tmp) + 1;
char *local_str = (char*) malloc(len * sizeof(char));
if(local_str != NULL) {
memcpy(local_str, gl_str_tmp, len * sizeof(char));
}
exts_i[index] = local_str;
}
*out_num_exts_i = num_exts_i;
*out_exts_i = exts_i;
}
#endif
return 1;
}
static void glad_gl_free_extensions(char **exts_i, unsigned int num_exts_i) {
if (exts_i != NULL) {
unsigned int index;
for(index = 0; index < num_exts_i; index++) {
free((void *) (exts_i[index]));
}
free((void *)exts_i);
exts_i = NULL;
}
}
static int glad_gl_has_extension(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) {
if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) {
const char *extensions;
const char *loc;
const char *terminator;
extensions = exts;
if(extensions == NULL || ext == NULL) {
return 0;
}
while(1) {
loc = strstr(extensions, ext);
if(loc == NULL) {
return 0;
}
terminator = loc + strlen(ext);
if((loc == extensions || *(loc - 1) == ' ') &&
(*terminator == ' ' || *terminator == '\0')) {
return 1;
}
extensions = terminator;
}
} else {
unsigned int index;
for(index = 0; index < num_exts_i; index++) {
const char *e = exts_i[index];
if(strcmp(e, ext) == 0) {
return 1;
}
}
}
return 0;
}
static GLADapiproc glad_gl_get_proc_from_userptr(void *userptr, const char* name) {
return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name);
}
static int glad_gl_find_extensions_gles2(GladGLES2Context *context, int version) {
const char *exts = NULL;
unsigned int num_exts_i = 0;
char **exts_i = NULL;
if (!glad_gl_get_extensions(context, version, &exts, &num_exts_i, &exts_i)) return 0;
context->OES_rgb8_rgba8 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_rgb8_rgba8");
glad_gl_free_extensions(exts_i, num_exts_i);
return 1;
}
static int glad_gl_find_core_gles2(GladGLES2Context *context) {
int i;
const char* version;
const char* prefixes[] = {
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
"OpenGL SC ",
NULL
};
int major = 0;
int minor = 0;
version = (const char*) context->GetString(GL_VERSION);
if (!version) return 0;
for (i = 0; prefixes[i]; i++) {
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0) {
version += length;
break;
}
}
GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor);
context->ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2;
return GLAD_MAKE_VERSION(major, minor);
}
int gladLoadGLES2ContextUserPtr(GladGLES2Context *context, GLADuserptrloadfunc load, void *userptr) {
int version;
context->GetString = (PFNGLGETSTRINGPROC) load(userptr, "glGetString");
if(context->GetString == NULL) return 0;
if(context->GetString(GL_VERSION) == NULL) return 0;
version = glad_gl_find_core_gles2(context);
glad_gl_load_GL_ES_VERSION_2_0(context, load, userptr);
if (!glad_gl_find_extensions_gles2(context, version)) return 0;
glad_gl_resolve_aliases(context);
return version;
}
int gladLoadGLES2Context(GladGLES2Context *context, GLADloadfunc load) {
return gladLoadGLES2ContextUserPtr(context, glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
}
#ifdef __cplusplus
}
#endif

38
thirdparty/imgui_config/srb2_imconfig.h vendored Normal file
View file

@ -0,0 +1,38 @@
#ifndef __SRB2_IMCONFIG_H__
#define __SRB2_IMCONFIG_H__
#include <stdint.h>
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IMGUI_DISABLE_OBSOLETE_KEYIO
// We provide needed functionalities provided by default win32 impls through the interface layer
#define IMGUI_DISABLE_WIN32_FUNCTIONS
// RHI Handles are essentially 64-bit integers
#define ImTextureID uint64_t
// RHI does not support integer vectors
#define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT \
struct ImVec3 \
{ \
float x, y, z; \
constexpr ImVec3() : x(0.0f), y(0.0f), z(0.0f) { } \
constexpr ImVec3(float _x, float _y) : x(_x), y(_y), z(0.0f) { } \
constexpr ImVec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { } \
constexpr ImVec3(const ImVec2& rhs) : x(rhs.x), y(rhs.y), z(0.f) { } \
ImVec3& operator=(const ImVec2& rhs) { x = rhs.x; y = rhs.y; return *this; } \
operator ImVec2() const { return ImVec2(x, y); } \
float operator[](size_t index) const { switch (index) {case 0: return x; case 1: return y; case 2: return z; default: return 0.f;} } \
float operator[](size_t index) { switch (index) {case 0: return x; case 1: return y; case 2: return z; default: return 0.f;} } \
\
}; \
struct ImDrawVert \
{ \
ImVec3 pos; \
ImVec2 uv; \
ImU32 col; \
float colf[4]; \
};
#endif // __SRB2_IMCONFIG_H__