Merge branch 'hwr2' into 'master'

Render Hardware Interface Part 1: A New Hope

See merge request KartKrew/Kart!891
This commit is contained in:
Eidolon 2023-01-15 19:39:11 +00:00
commit 128c3b063a
43 changed files with 13302 additions and 421 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
)

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

@ -0,0 +1,230 @@
#ifndef __SRB2_CORE_STATIC_VEC_HPP__
#define __SRB2_CORE_STATIC_VEC_HPP__
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <initializer_list>
#include <iterator>
#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

@ -1140,6 +1140,7 @@ static void IdentifyVersion(void)
#if defined(DEVELOP) && defined(UNLOCKTESTING)
D_AddFile(startupiwads, va(pandf,srb2waddir,UNLOCKNAME));
#endif
D_AddFile(startupiwads, va(pandf,srb2waddir,"shaders.pk3"));
////
#undef TEXTURESNAME
#undef MAPSNAME
@ -1465,6 +1466,7 @@ void D_SRB2Main(void)
#endif
#endif //ifndef DEVELOP
mainwads++; // shaders.pk3
// Do it before P_InitMapData because PNG patch
// conversion sometimes needs the palette

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);

171
src/i_video_common.cpp Normal file
View file

@ -0,0 +1,171 @@
#include "i_video.h"
#include <algorithm>
#include <array>
#include <vector>
#include <imgui.h>
#include "cxxutil.hpp"
#include "hwr2/pass_imgui.hpp"
#include "hwr2/pass_software.hpp"
#include "v_video.h"
// KILL THIS WHEN WE KILL OLD OGL SUPPORT PLEASE
#include "sdl/ogl_sdl.h"
#include "st_stuff.h" // kill
#include "d_netcmd.h" // kill
#include "doomstat.h" // kill
#include "s_sound.h" // kill
#include "discord.h" // kill
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;
}
#ifdef HWRENDER
static void finish_legacy_ogl_update()
{
int player;
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 (
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
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
void I_FinishUpdate(void)
{
if (rendermode == render_none)
{
return;
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
finish_legacy_ogl_update();
return;
}
#endif
// 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

@ -1125,40 +1125,6 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap)
}
#endif
//
// build a table for quick conversion from 8bpp to 15bpp
//
//
// added "static inline" keywords, linking with the debug version
// of allegro, it have a makecol15 function of it's own, now
// with "static inline" keywords,it sloves this problem ;)
//
FUNCMATH static inline int makecol15(int r, int g, int b)
{
return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)));
}
static void R_Init8to16(void)
{
UINT8 *palette;
int i;
palette = W_CacheLumpName("PLAYPAL",PU_CACHE);
for (i = 0; i < 256; i++)
{
// PLAYPAL uses 8 bit values
color8to16[i] = (INT16)makecol15(palette[0], palette[1], palette[2]);
palette += 3;
}
// test a big colormap
hicolormaps = Z_Malloc(16384*sizeof(*hicolormaps), PU_STATIC, NULL);
for (i = 0; i < 16384; i++)
hicolormaps[i] = (INT16)(i<<1);
}
//
// R_InitTextureData
//
@ -1167,12 +1133,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,227 @@
#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;
};
struct GlCoreTexture : public rhi::Texture
{
uint32_t texture;
rhi::TextureDesc desc;
};
struct GlCoreBuffer : public rhi::Buffer
{
uint32_t buffer;
rhi::BufferDesc desc;
};
struct GlCoreRenderPass : public rhi::RenderPass
{
rhi::RenderPassDesc desc;
};
struct GlCoreRenderbuffer : public rhi::Renderbuffer
{
uint32_t renderbuffer;
};
struct GlCoreUniformSet : public rhi::UniformSet
{
std::vector<rhi::UniformVariant> uniforms;
};
struct GlCoreBindingSet : public rhi::BindingSet
{
uint32_t vao;
std::unordered_map<rhi::SamplerName, uint32_t> textures {4};
};
struct GlCorePipeline : public rhi::Pipeline
{
uint32_t vertex_shader = 0;
uint32_t fragment_shader = 0;
uint32_t program = 0;
std::unordered_map<rhi::VertexAttributeName, uint32_t> attrib_locations {2};
std::unordered_map<rhi::UniformName, uint32_t> uniform_locations {2};
std::unordered_map<rhi::SamplerName, uint32_t> sampler_locations {2};
rhi::PipelineDesc desc;
};
struct GlCoreGraphicsContext : public rhi::GraphicsContext
{
};
struct GlCoreTransferContext : public rhi::TransferContext
{
};
struct GlCoreActiveUniform
{
uint32_t type;
uint32_t location;
};
class GlCoreRhi final : public Rhi
{
std::unique_ptr<GlCorePlatform> platform_;
std::unique_ptr<GladGLContext> gl_;
Slab<GlCoreRenderPass> render_pass_slab_;
Slab<GlCoreTexture> texture_slab_;
Slab<GlCoreBuffer> buffer_slab_;
Slab<GlCoreRenderbuffer> renderbuffer_slab_;
Slab<GlCorePipeline> pipeline_slab_;
Slab<GlCoreUniformSet> uniform_set_slab_;
Slab<GlCoreBindingSet> 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 :)

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

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,151 @@
#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__

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

@ -0,0 +1,318 @@
#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& operator=(const Handle<U>& rhs) noexcept
{
id_ = rhs.id_;
generation_ = rhs.generation_;
}
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; }
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
{
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(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_);
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
T remove(Handle<U> handle)
{
uint32_t handle_id = handle.id();
uint32_t handle_gen = handle.generation();
if (handle_id >= vec_.size())
{
return T();
}
SlabStorage& storage = vec_[handle_id];
if (storage.gen > handle_gen)
{
return T();
}
T ret = std::move(storage.item);
storage.item = T();
free_list_.push_back(handle_id);
gen_ += 1;
if (gen_ == 0)
{
gen_ = 1;
}
return ret;
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
bool is_valid(Handle<U> 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;
}
}
template <typename U, typename std::enable_if_t<std::is_base_of_v<U, T>, bool> = true>
T& operator[](Handle<U> 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__

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

@ -0,0 +1,41 @@
#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();
}
}

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

@ -0,0 +1,554 @@
#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

View file

@ -21,9 +21,16 @@
#include <stdlib.h>
#include <errno.h>
#include <memory>
#include <signal.h>
#include <imgui.h>
#include "../rhi/rhi.hpp"
#include "../rhi/gl3_core/gl3_core_rhi.hpp"
#include "rhi_gl3_core_platform.hpp"
#ifdef _MSC_VER
#pragma warning(disable : 4214 4244)
#endif
@ -93,6 +100,8 @@
// maximum number of windowed modes (see windowedModes[][])
#define MAXWINMODES (18)
using namespace srb2;
/** \brief
*/
static INT32 numVidModes = -1;
@ -104,9 +113,6 @@ static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none; // set by command line arguments
boolean highcolor = false;
// synchronize page flipping with screen refresh
consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "Off", CV_SAVE, CV_OnOff, NULL);
static consvar_t cv_stretch = CVAR_INIT ("stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL);
@ -134,27 +140,21 @@ static SDL_Surface *vidSurface = NULL;
static SDL_Surface *bufSurface = NULL;
static SDL_Surface *icoSurface = NULL;
static SDL_Color localPalette[256];
#if 0
static SDL_Rect **modeList = NULL;
static Uint8 BitsPerPixel = 16;
#endif
Uint16 realwidth = BASEVIDWIDTH;
Uint16 realheight = BASEVIDHEIGHT;
static SDL_bool mousegrabok = SDL_TRUE;
static SDL_bool wrapmouseok = SDL_FALSE;
#define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
static SDL_bool videoblitok = SDL_FALSE;
static SDL_bool exposevideo = SDL_FALSE;
static SDL_bool usesdl2soft = SDL_FALSE;
static SDL_bool borderlesswindow = SDL_FALSE;
// SDL2 vars
SDL_Window *window;
SDL_Renderer *renderer;
static SDL_Texture *texture;
static SDL_bool havefocus = SDL_TRUE;
static const char *fallback_resolution_name = "Fallback";
static std::unique_ptr<rhi::Rhi> g_rhi;
static uint32_t g_rhi_generation = 0;
// windowed video modes from which to choose from.
static INT32 windowedModes[MAXWINMODES][2] =
{
@ -178,35 +178,14 @@ static INT32 windowedModes[MAXWINMODES][2] =
{ 320, 200}, // 1.60,1.00
};
static void Impl_VideoSetupSDLBuffer(void);
static void Impl_VideoSetupBuffer(void);
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
//static void Impl_SetWindowName(const char *title);
static void Impl_SetWindowIcon(void);
static void Impl_SetSoftwareVsync(int vsync)
{
#if SDL_VERSION_ATLEAST(2,0,18)
static int oldvsync = 0;
if (oldvsync != vsync)
{
SDL_RenderSetVSync(renderer, vsync);
}
oldvsync = vsync;
#else
(void)vsync;
#endif
}
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool reposition)
{
static SDL_bool wasfullscreen = SDL_FALSE;
Uint32 rmask;
Uint32 gmask;
Uint32 bmask;
Uint32 amask;
int bpp = 16;
int sw_texture_format = SDL_PIXELFORMAT_ABGR8888;
realwidth = vid.width;
realheight = vid.height;
@ -254,44 +233,9 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool
}
#endif
if (rendermode == render_soft)
{
SDL_RenderClear(renderer);
SDL_RenderSetLogicalSize(renderer, width, height);
// Set up Texture
realwidth = width;
realheight = height;
if (texture != NULL)
{
SDL_DestroyTexture(texture);
}
if (!usesdl2soft)
{
sw_texture_format = SDL_PIXELFORMAT_RGB565;
}
else
{
bpp = 32;
sw_texture_format = SDL_PIXELFORMAT_RGBA8888;
}
texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height);
// Set up SW surface
if (vidSurface != NULL)
{
SDL_FreeSurface(vidSurface);
}
if (vid.buffer)
{
free(vid.buffer);
vid.buffer = NULL;
}
SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask);
vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask);
Impl_SetSoftwareVsync(cv_vidwait.value);
}
SDL_GetWindowSize(window, &width, &height);
vid.realwidth = static_cast<uint32_t>(width);
vid.realheight = static_cast<uint32_t>(height);
}
static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
@ -458,51 +402,8 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText)
static void VID_Command_Info_f (void)
{
#if 0
SDL2STUB();
#else
#if 0
const SDL_VideoInfo *videoInfo;
videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check
if (videoInfo)
{
CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n"));
if (videoInfo->hw_available)
CONS_Printf("%s", M_GetText(" Hardware surfaces\n"));
if (videoInfo->wm_available)
CONS_Printf("%s", M_GetText(" Window manager\n"));
//UnusedBits1 :6
//UnusedBits2 :1
if (videoInfo->blit_hw)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n"));
if (videoInfo->blit_hw_CC)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n"));
if (videoInfo->wm_available)
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n"));
if (videoInfo->blit_sw)
{
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n"));
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
}
if (videoInfo->blit_sw_CC)
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n"));
if (videoInfo->blit_sw_A)
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n"));
if (videoInfo->blit_fill)
CONS_Printf("%s", M_GetText(" Accelerated Color filling\n"));
//UnusedBits3 :16
if (videoInfo->video_mem)
CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem);
else
CONS_Printf("%s", M_GetText(" There no video memory for SDL\n"));
//*vfmt
}
#else
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
#endif
SurfaceInfo(bufSurface, M_GetText("Current Engine Mode"));
SurfaceInfo(vidSurface, M_GetText("Current Video Mode"));
#endif
}
static void VID_Command_ModeList_f(void)
@ -875,6 +776,204 @@ static void Impl_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint
}
}
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
{
switch (keycode)
{
case SDLK_TAB: return ImGuiKey_Tab;
case SDLK_LEFT: return ImGuiKey_LeftArrow;
case SDLK_RIGHT: return ImGuiKey_RightArrow;
case SDLK_UP: return ImGuiKey_UpArrow;
case SDLK_DOWN: return ImGuiKey_DownArrow;
case SDLK_PAGEUP: return ImGuiKey_PageUp;
case SDLK_PAGEDOWN: return ImGuiKey_PageDown;
case SDLK_HOME: return ImGuiKey_Home;
case SDLK_END: return ImGuiKey_End;
case SDLK_INSERT: return ImGuiKey_Insert;
case SDLK_DELETE: return ImGuiKey_Delete;
case SDLK_BACKSPACE: return ImGuiKey_Backspace;
case SDLK_SPACE: return ImGuiKey_Space;
case SDLK_RETURN: return ImGuiKey_Enter;
case SDLK_ESCAPE: return ImGuiKey_Escape;
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
case SDLK_COMMA: return ImGuiKey_Comma;
case SDLK_MINUS: return ImGuiKey_Minus;
case SDLK_PERIOD: return ImGuiKey_Period;
case SDLK_SLASH: return ImGuiKey_Slash;
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
case SDLK_EQUALS: return ImGuiKey_Equal;
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
case SDLK_PAUSE: return ImGuiKey_Pause;
case SDLK_KP_0: return ImGuiKey_Keypad0;
case SDLK_KP_1: return ImGuiKey_Keypad1;
case SDLK_KP_2: return ImGuiKey_Keypad2;
case SDLK_KP_3: return ImGuiKey_Keypad3;
case SDLK_KP_4: return ImGuiKey_Keypad4;
case SDLK_KP_5: return ImGuiKey_Keypad5;
case SDLK_KP_6: return ImGuiKey_Keypad6;
case SDLK_KP_7: return ImGuiKey_Keypad7;
case SDLK_KP_8: return ImGuiKey_Keypad8;
case SDLK_KP_9: return ImGuiKey_Keypad9;
case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
case SDLK_LSHIFT: return ImGuiKey_LeftShift;
case SDLK_LALT: return ImGuiKey_LeftAlt;
case SDLK_LGUI: return ImGuiKey_LeftSuper;
case SDLK_RCTRL: return ImGuiKey_RightCtrl;
case SDLK_RSHIFT: return ImGuiKey_RightShift;
case SDLK_RALT: return ImGuiKey_RightAlt;
case SDLK_RGUI: return ImGuiKey_RightSuper;
case SDLK_APPLICATION: return ImGuiKey_Menu;
case SDLK_0: return ImGuiKey_0;
case SDLK_1: return ImGuiKey_1;
case SDLK_2: return ImGuiKey_2;
case SDLK_3: return ImGuiKey_3;
case SDLK_4: return ImGuiKey_4;
case SDLK_5: return ImGuiKey_5;
case SDLK_6: return ImGuiKey_6;
case SDLK_7: return ImGuiKey_7;
case SDLK_8: return ImGuiKey_8;
case SDLK_9: return ImGuiKey_9;
case SDLK_a: return ImGuiKey_A;
case SDLK_b: return ImGuiKey_B;
case SDLK_c: return ImGuiKey_C;
case SDLK_d: return ImGuiKey_D;
case SDLK_e: return ImGuiKey_E;
case SDLK_f: return ImGuiKey_F;
case SDLK_g: return ImGuiKey_G;
case SDLK_h: return ImGuiKey_H;
case SDLK_i: return ImGuiKey_I;
case SDLK_j: return ImGuiKey_J;
case SDLK_k: return ImGuiKey_K;
case SDLK_l: return ImGuiKey_L;
case SDLK_m: return ImGuiKey_M;
case SDLK_n: return ImGuiKey_N;
case SDLK_o: return ImGuiKey_O;
case SDLK_p: return ImGuiKey_P;
case SDLK_q: return ImGuiKey_Q;
case SDLK_r: return ImGuiKey_R;
case SDLK_s: return ImGuiKey_S;
case SDLK_t: return ImGuiKey_T;
case SDLK_u: return ImGuiKey_U;
case SDLK_v: return ImGuiKey_V;
case SDLK_w: return ImGuiKey_W;
case SDLK_x: return ImGuiKey_X;
case SDLK_y: return ImGuiKey_Y;
case SDLK_z: return ImGuiKey_Z;
case SDLK_F1: return ImGuiKey_F1;
case SDLK_F2: return ImGuiKey_F2;
case SDLK_F3: return ImGuiKey_F3;
case SDLK_F4: return ImGuiKey_F4;
case SDLK_F5: return ImGuiKey_F5;
case SDLK_F6: return ImGuiKey_F6;
case SDLK_F7: return ImGuiKey_F7;
case SDLK_F8: return ImGuiKey_F8;
case SDLK_F9: return ImGuiKey_F9;
case SDLK_F10: return ImGuiKey_F10;
case SDLK_F11: return ImGuiKey_F11;
case SDLK_F12: return ImGuiKey_F12;
}
return ImGuiKey_None;
}
static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
{
ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent(ImGuiMod_Ctrl, (sdl_key_mods & KMOD_CTRL) != 0);
io.AddKeyEvent(ImGuiMod_Shift, (sdl_key_mods & KMOD_SHIFT) != 0);
io.AddKeyEvent(ImGuiMod_Alt, (sdl_key_mods & KMOD_ALT) != 0);
io.AddKeyEvent(ImGuiMod_Super, (sdl_key_mods & KMOD_GUI) != 0);
}
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
{
ImGuiIO& io = ImGui::GetIO();
switch (event->type)
{
case SDL_MOUSEMOTION:
{
io.AddMousePosEvent((float)event->motion.x, (float)event->motion.y);
return true;
}
case SDL_MOUSEWHEEL:
{
float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f;
float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f;
io.AddMouseWheelEvent(wheel_x, wheel_y);
return true;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
int mouse_button = -1;
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
if (event->button.button == SDL_BUTTON_X1) { mouse_button = 3; }
if (event->button.button == SDL_BUTTON_X2) { mouse_button = 4; }
if (mouse_button == -1)
break;
io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN));
// bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
return true;
}
case SDL_TEXTINPUT:
{
io.AddInputCharactersUTF8(event->text.text);
return true;
}
case SDL_KEYDOWN:
case SDL_KEYUP:
{
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
return true;
}
case SDL_WINDOWEVENT:
{
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
// - However we won't get a correct LEAVE event for a captured window.
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
// causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
// we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
Uint8 window_event = event->window.event;
if (window_event == SDL_WINDOWEVENT_ENTER)
(void)0;
// bd->PendingMouseLeaveFrame = 0;
if (window_event == SDL_WINDOWEVENT_LEAVE)
(void)0;
// bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
io.AddFocusEvent(true);
else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
io.AddFocusEvent(false);
return true;
}
}
return false;
}
void I_GetEvent(void)
{
SDL_Event evt;
@ -892,8 +991,16 @@ void I_GetEvent(void)
mousemovex = mousemovey = 0;
ImGuiIO& io = ImGui::GetIO();
while (SDL_PollEvent(&evt))
{
ImGui_ImplSDL2_ProcessEvent(&evt);
if (io.WantCaptureMouse || io.WantCaptureKeyboard)
{
continue;
}
switch (evt.type)
{
case SDL_WINDOWEVENT:
@ -1093,6 +1200,13 @@ void I_GetEvent(void)
}
}
static void half_warp_mouse(uint16_t x, uint16_t y) {
if (wrapmouseok)
{
SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2));
}
}
void I_StartupMouse(void)
{
static SDL_bool firsttimeonmouse = SDL_TRUE;
@ -1102,7 +1216,7 @@ void I_StartupMouse(void)
if (!firsttimeonmouse)
{
HalfWarpMouse(realwidth, realheight); // warp to center
half_warp_mouse(realwidth, realheight); // warp to center
}
else
firsttimeonmouse = SDL_FALSE;
@ -1154,140 +1268,16 @@ void I_UpdateNoBlit(void)
{
OglSdlFinishUpdate(cv_vidwait.value);
}
else
#endif
if (rendermode == render_soft)
{
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
}
exposevideo = SDL_FALSE;
}
// I_SkipFrame
//
// Returns true if it thinks we can afford to skip this frame
// from PrBoom's src/SDL/i_video.c
static inline boolean I_SkipFrame(void)
{
#if 1
// While I fixed the FPS counter bugging out with this,
// I actually really like being able to pause and
// use perfstats to measure rendering performance
// without game logic changes.
return false;
#else
static boolean skip = false;
skip = !skip;
switch (gamestate)
{
case GS_LEVEL:
if (!paused)
return false;
/* FALLTHRU */
case GS_WAITINGPLAYERS:
return skip; // Skip odd frames
default:
return false;
}
#endif
}
//
// I_FinishUpdate
//
static SDL_Rect src_rect = { 0, 0, 0, 0 };
void I_FinishUpdate(void)
{
int player;
if (rendermode == render_none)
return; //Alam: No software or OpenGl surface
SCR_CalculateFPS();
if (I_SkipFrame())
return;
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 (
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
if (rendermode == render_soft && screens[0])
{
if (!bufSurface) //Double-Check
{
Impl_VideoSetupSDLBuffer();
}
if (bufSurface)
{
SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect);
// Fury -- there's no way around UpdateTexture, the GL backend uses it anyway
SDL_LockSurface(vidSurface);
SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch);
SDL_UnlockSurface(vidSurface);
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, &src_rect, NULL);
SDL_RenderPresent(renderer);
Impl_SetSoftwareVsync(cv_vidwait.value);
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
exposevideo = SDL_FALSE;
}
//
// I_UpdateNoVsync
//
@ -1324,9 +1314,6 @@ void I_SetPalette(RGBA_t *palette)
localPalette[i].g = palette[i].s.green;
localPalette[i].b = palette[i].s.blue;
}
//if (vidSurface) SDL_SetPaletteColors(vidSurface->format->palette, localPalette, 0, 256);
// Fury -- SDL2 vidSurface is a 32-bit surface buffer copied to the texture. It's not palletized, like bufSurface.
if (bufSurface) SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
}
// return number of fullscreen + X11 modes
@ -1478,12 +1465,27 @@ void VID_PrepareModeList(void)
#endif
}
static void init_imgui()
{
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.IniFilename = NULL;
io.BackendFlags = 0;
io.BackendRendererName = "SRB2 SDL 2 RHI";
io.Fonts->AddFontDefault();
{
unsigned char* pixels;
int width;
int height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
}
ImGui::StyleColorsDark();
}
static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
if ((rendermode == render_opengl)
&& (vid.glstate != VID_GL_LIBRARY_ERROR))
if (rendermode == render_opengl)
{
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
@ -1492,32 +1494,33 @@ static SDL_bool Impl_CreateContext(void)
SDL_DestroyWindow(window);
I_Error("Failed to create a GL context: %s\n", SDL_GetError());
}
init_imgui();
SDL_GL_MakeCurrent(window, sdlglcontext);
return SDL_TRUE;
}
else
#endif
if (rendermode == render_soft)
// RHI always uses OpenGL 3.2 Core (for now)
if (!sdlglcontext)
{
int flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
// 3 August 2022
// Possibly a Windows 11 issue; the default
// "direct3d" driver (D3D9) causes Drmingw exchndl
// to not write RPT files. Every other driver
// seems fine.
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
if (!renderer)
renderer = SDL_CreateRenderer(window, -1, flags);
if (renderer == NULL)
{
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
return SDL_FALSE;
}
SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
sdlglcontext = SDL_GL_CreateContext(window);
}
if (sdlglcontext == NULL)
{
SDL_DestroyWindow(window);
I_Error("Failed to create a GL context: %s\n", SDL_GetError());
}
init_imgui();
SDL_GL_MakeCurrent(window, sdlglcontext);
std::unique_ptr<rhi::SdlGlCorePlatform> platform = std::make_unique<rhi::SdlGlCorePlatform>();
platform->window = window;
g_rhi = std::make_unique<rhi::GlCoreRhi>(std::move(platform), reinterpret_cast<rhi::GlLoadFunc>(SDL_GL_GetProcAddress));
g_rhi_generation += 1;
return SDL_TRUE;
}
@ -1577,13 +1580,6 @@ boolean VID_CheckRenderer(void)
window = NULL;
}
// Destroy the current window rendering context, if that also exists.
if (renderer)
{
SDL_DestroyRenderer(renderer);
renderer = NULL;
}
// Create a new window.
Impl_CreateWindow(static_cast<SDL_bool>(USE_FULLSCREEN));
@ -1607,12 +1603,6 @@ boolean VID_CheckRenderer(void)
if (rendermode == render_soft)
{
if (bufSurface)
{
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
SCR_SetDrawFuncs();
}
#ifdef HWRENDER
@ -1661,6 +1651,8 @@ INT32 VID_SetMode(INT32 modeNum)
vid.width = windowedModes[modeNum][0];
vid.height = windowedModes[modeNum][1];
vid.realwidth = vid.width;
vid.realheight = vid.height;
vid.modenum = modeNum;
src_rect.w = vid.width;
@ -1668,7 +1660,6 @@ INT32 VID_SetMode(INT32 modeNum)
refresh_rate = VID_GetRefreshRate();
//Impl_SetWindowName("Dr. Robotnik's Ring Racers "VERSIONSTRING);
VID_CheckRenderer();
return SDL_TRUE;
}
@ -1689,16 +1680,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
if (borderlesswindow)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (vid.glstate == VID_GL_LIBRARY_LOADED)
flags |= SDL_WINDOW_OPENGL;
#endif
// RHI: always create window as OPENGL
flags |= SDL_WINDOW_OPENGL;
// Create a window
window = SDL_CreateWindow("Dr. Robotnik's Ring Racers " VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
realwidth, realheight, flags);
if (window == NULL)
{
CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError());
@ -1710,51 +1698,12 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
return Impl_CreateContext();
}
/*
static void Impl_SetWindowName(const char *title)
{
if (window == NULL)
{
return;
}
SDL_SetWindowTitle(window, title);
}
*/
static void Impl_SetWindowIcon(void)
{
if (window && icoSurface)
SDL_SetWindowIcon(window, icoSurface);
}
static void Impl_VideoSetupSDLBuffer(void)
{
if (bufSurface != NULL)
{
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
// Set up the SDL palletized buffer (copied to vidbuffer before being rendered to texture)
if (vid.bpp == 1)
{
bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,8,
(int)vid.rowbytes,0x00000000,0x00000000,0x00000000,0x00000000); // 256 mode
}
else if (vid.bpp == 2) // Fury -- don't think this is used at all anymore
{
bufSurface = SDL_CreateRGBSurfaceFrom(screens[0],vid.width,vid.height,15,
(int)vid.rowbytes,0x00007C00,0x000003E0,0x0000001F,0x00000000); // 555 mode
}
if (bufSurface)
{
SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256);
}
else
{
I_Error("%s", M_GetText("No system memory for SDL buffer surface\n"));
}
}
static void Impl_VideoSetupBuffer(void)
{
// Set up game's software render buffer
@ -1799,17 +1748,6 @@ void I_StartupGraphics(void)
return;
}
#endif
{
const char *vd = SDL_GetCurrentVideoDriver();
//CONS_Printf(M_GetText("Starting up with video driver: %s\n"), vd);
if (vd && (
strncasecmp(vd, "gcvideo", 8) == 0 ||
strncasecmp(vd, "fbcon", 6) == 0 ||
strncasecmp(vd, "wii", 4) == 0 ||
strncasecmp(vd, "psl1ght", 8) == 0
))
framebuffer = SDL_TRUE;
}
// Renderer choices
// Takes priority over the config.
@ -1850,10 +1788,8 @@ void I_StartupGraphics(void)
if (chosenrendermode != render_none)
rendermode = chosenrendermode;
usesdl2soft = M_CheckParm("-softblit") ? SDL_TRUE : SDL_FALSE;
borderlesswindow = M_CheckParm("-borderless") ? SDL_TRUE : SDL_FALSE;
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f();
#ifdef HWRENDER
@ -1861,17 +1797,6 @@ void I_StartupGraphics(void)
VID_StartupOpenGL();
#endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
// Fury: we do window initialization after GL setup to allow
// SDL_GL_LoadLibrary to work well on Windows
// Create window
//Impl_CreateWindow(USE_FULLSCREEN);
//Impl_SetWindowName("Dr. Robotnik's Ring Racers "VERSIONSTRING);
VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));
vid.width = BASEVIDWIDTH; // Default size for startup
@ -1881,24 +1806,10 @@ void I_StartupGraphics(void)
vid.bpp = 1; // This is the game engine's Bpp
vid.WndParent = NULL; //For the window?
#ifdef HAVE_TTF
I_ShutdownTTF();
#endif
VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));
if (M_CheckParm("-nomousegrab"))
mousegrabok = SDL_FALSE;
#if 0 // defined (_DEBUG)
else
{
char videodriver[4] = {'S','D','L',0};
if (!M_CheckParm("-mousegrab") &&
*strncpy(videodriver, SDL_GetCurrentVideoDriver(), 4) != '\0' &&
strncasecmp("x11",videodriver,4) == 0)
mousegrabok = SDL_FALSE; //X11's XGrabPointer not good
}
#endif
realwidth = (Uint16)vid.width;
realheight = (Uint16)vid.height;
@ -1972,31 +1883,18 @@ void VID_StartupOpenGL(void)
void I_ShutdownGraphics(void)
{
const rendermode_t oldrendermode = rendermode;
rendermode = render_none;
if (icoSurface) SDL_FreeSurface(icoSurface);
icoSurface = NULL;
if (oldrendermode == render_soft)
{
if (vidSurface) SDL_FreeSurface(vidSurface);
vidSurface = NULL;
if (vid.buffer) free(vid.buffer);
vid.buffer = NULL;
if (bufSurface) SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
I_OutputMsg("I_ShutdownGraphics(): ");
// was graphics initialized anyway?
if (!graphics_started)
{
I_OutputMsg("graphics never started\n");
return;
}
graphics_started = false;
I_OutputMsg("shut down\n");
#ifdef HWRENDER
if (GLUhandle)
@ -2009,6 +1907,13 @@ void I_ShutdownGraphics(void)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
framebuffer = SDL_FALSE;
}
rhi::Rhi* srb2::sys::get_rhi(rhi::Handle<rhi::Rhi> handle)
{
// TODO actually use handle...
return g_rhi.get();
}
#endif
UINT32 I_GetRefreshRate(void)

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

@ -20,6 +20,8 @@
#ifndef __SDL_OGL_SDL_H__
#define __SDL_OGL_SDL_H__
#include <SDL.h>
#include "../v_video.h"
#ifdef __cplusplus
@ -32,7 +34,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,60 @@
#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,25 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/gl3_core/gl3_core_rhi.hpp"
#include "../rhi/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,60 @@
#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,25 @@
#ifndef __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#define __SRB2_SDL_RHI_GLES2_PLATFORM_HPP__
#include "../rhi/gles2/gles2_rhi.hpp"
#include "../rhi/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__