Restructuring for platform independent rendering

This commit is contained in:
Ronja Enseleit 2023-07-01 20:38:43 +02:00
parent 5c86b9bc20
commit fca5628279
16 changed files with 552 additions and 315 deletions

View File

@ -8,8 +8,8 @@
/* Begin PBXBuildFile section */
FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A74F2A50790A00F960DA /* AppDelegate.m */; };
FBA9A7532A50790A00F960DA /* Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7522A50790A00F960DA /* Renderer.m */; };
FBA9A7562A50790A00F960DA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7552A50790A00F960DA /* GameViewController.m */; };
FBA9A7532A50790A00F960DA /* MetalViewDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */; };
FBA9A7562A50790A00F960DA /* GameViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7552A50790A00F960DA /* GameViewController.mm */; };
FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7572A50790A00F960DA /* Shaders.metal */; };
FBA9A75C2A50790A00F960DA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FBA9A75A2A50790A00F960DA /* Main.storyboard */; };
FBA9A75E2A50790A00F960DA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FBA9A75D2A50790A00F960DA /* Assets.xcassets */; };
@ -19,6 +19,11 @@
FBA9A7692A50795400F960DA /* AssetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73D2A5078B800F960DA /* AssetManager.cpp */; };
FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73A2A5078B800F960DA /* Hash.cpp */; };
FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73F2A5078D800F960DA /* Texture.cpp */; };
FBA9A7702A5098E800F960DA /* MetalGfxInterface.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */; };
FBA9A7762A50A58000F960DA /* Renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7722A509C6500F960DA /* Renderer.cpp */; };
FBA9A7802A50A82500F960DA /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBA9A77E2A50A82400F960DA /* Metal.framework */; };
FBA9A7812A50A82500F960DA /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBA9A77F2A50A82400F960DA /* MetalKit.framework */; };
FBA9A7832A50A82D00F960DA /* ModelIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBA9A7822A50A82C00F960DA /* ModelIO.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -41,16 +46,26 @@
FBA9A74B2A50790A00F960DA /* KDE.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KDE.app; sourceTree = BUILT_PRODUCTS_DIR; };
FBA9A74E2A50790A00F960DA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
FBA9A74F2A50790A00F960DA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
FBA9A7512A50790A00F960DA /* Renderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Renderer.h; sourceTree = "<group>"; };
FBA9A7522A50790A00F960DA /* Renderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Renderer.m; sourceTree = "<group>"; };
FBA9A7512A50790A00F960DA /* MetalViewDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MetalViewDelegate.h; sourceTree = "<group>"; };
FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalViewDelegate.mm; sourceTree = "<group>"; };
FBA9A7542A50790A00F960DA /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = "<group>"; };
FBA9A7552A50790A00F960DA /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = "<group>"; };
FBA9A7552A50790A00F960DA /* GameViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GameViewController.mm; sourceTree = "<group>"; };
FBA9A7572A50790A00F960DA /* Shaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = "<group>"; };
FBA9A7592A50790A00F960DA /* ShaderTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShaderTypes.h; sourceTree = "<group>"; };
FBA9A75B2A50790A00F960DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
FBA9A75D2A50790A00F960DA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
FBA9A7602A50790A00F960DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
FBA9A7622A50790A00F960DA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
FBA9A76C2A5096C500F960DA /* MetalGfxInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MetalGfxInterface.h; sourceTree = "<group>"; };
FBA9A76D2A5096DF00F960DA /* Renderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Renderer.h; path = cpp/Renderer.h; sourceTree = "<group>"; };
FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MetalGfxInterface.mm; sourceTree = "<group>"; };
FBA9A7712A509A4400F960DA /* Gfx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Gfx.h; path = cpp/Gfx.h; sourceTree = "<group>"; };
FBA9A7722A509C6500F960DA /* Renderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Renderer.cpp; path = cpp/Renderer.cpp; sourceTree = "<group>"; };
FBA9A77A2A50A65400F960DA /* OpenGLGFXInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenGLGFXInterface.cpp; path = cpp/OpenGLGFXInterface.cpp; sourceTree = "<group>"; };
FBA9A77B2A50A65400F960DA /* OpenGLGFXInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenGLGFXInterface.h; path = cpp/OpenGLGFXInterface.h; sourceTree = "<group>"; };
FBA9A77E2A50A82400F960DA /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; };
FBA9A77F2A50A82400F960DA /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/MetalKit.framework; sourceTree = DEVELOPER_DIR; };
FBA9A7822A50A82C00F960DA /* ModelIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ModelIO.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/ModelIO.framework; sourceTree = DEVELOPER_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -58,6 +73,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
FBA9A7832A50A82D00F960DA /* ModelIO.framework in Frameworks */,
FBA9A7802A50A82500F960DA /* Metal.framework in Frameworks */,
FBA9A7812A50A82500F960DA /* MetalKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -67,6 +85,11 @@
FBA9A7332A50789900F960DA /* cpp */ = {
isa = PBXGroup;
children = (
FBA9A77A2A50A65400F960DA /* OpenGLGFXInterface.cpp */,
FBA9A77B2A50A65400F960DA /* OpenGLGFXInterface.h */,
FBA9A7722A509C6500F960DA /* Renderer.cpp */,
FBA9A7712A509A4400F960DA /* Gfx.h */,
FBA9A76D2A5096DF00F960DA /* Renderer.h */,
FBA9A7412A5078D800F960DA /* stb_image.h */,
FBA9A7402A5078D800F960DA /* stb_truetype.h */,
FBA9A7432A5078D800F960DA /* StringRepository.cpp */,
@ -92,16 +115,18 @@
children = (
FBA9A74E2A50790A00F960DA /* AppDelegate.h */,
FBA9A74F2A50790A00F960DA /* AppDelegate.m */,
FBA9A7512A50790A00F960DA /* Renderer.h */,
FBA9A7522A50790A00F960DA /* Renderer.m */,
FBA9A7512A50790A00F960DA /* MetalViewDelegate.h */,
FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */,
FBA9A7542A50790A00F960DA /* GameViewController.h */,
FBA9A7552A50790A00F960DA /* GameViewController.m */,
FBA9A7552A50790A00F960DA /* GameViewController.mm */,
FBA9A7572A50790A00F960DA /* Shaders.metal */,
FBA9A7592A50790A00F960DA /* ShaderTypes.h */,
FBA9A75A2A50790A00F960DA /* Main.storyboard */,
FBA9A75D2A50790A00F960DA /* Assets.xcassets */,
FBA9A75F2A50790A00F960DA /* LaunchScreen.storyboard */,
FBA9A7622A50790A00F960DA /* main.m */,
FBA9A76C2A5096C500F960DA /* MetalGfxInterface.h */,
FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */,
);
path = m;
sourceTree = "<group>";
@ -114,12 +139,23 @@
name = Products;
sourceTree = "<group>";
};
FBA9A77D2A50A82400F960DA /* Frameworks */ = {
isa = PBXGroup;
children = (
FBA9A7822A50A82C00F960DA /* ModelIO.framework */,
FBA9A77E2A50A82400F960DA /* Metal.framework */,
FBA9A77F2A50A82400F960DA /* MetalKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
FBC6DF7A2A50782C00CA10E7 = {
isa = PBXGroup;
children = (
FBA9A7462A5078DC00F960DA /* m */,
FBA9A7332A50789900F960DA /* cpp */,
FBA9A74C2A50790A00F960DA /* Products */,
FBA9A77D2A50A82400F960DA /* Frameworks */,
);
sourceTree = "<group>";
};
@ -197,10 +233,12 @@
FBA9A7632A50790A00F960DA /* main.m in Sources */,
FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */,
FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */,
FBA9A7762A50A58000F960DA /* Renderer.cpp in Sources */,
FBA9A7682A50795000F960DA /* StringRepository.cpp in Sources */,
FBA9A7532A50790A00F960DA /* Renderer.m in Sources */,
FBA9A7702A5098E800F960DA /* MetalGfxInterface.mm in Sources */,
FBA9A7532A50790A00F960DA /* MetalViewDelegate.mm in Sources */,
FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */,
FBA9A7562A50790A00F960DA /* GameViewController.m in Sources */,
FBA9A7562A50790A00F960DA /* GameViewController.mm in Sources */,
FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "E5173B6F-DE97-46BD-BCEC-CF001AD0A836"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "0B1FCEA3-648A-47DA-9B17-82B7BCCE8D60"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "OpenGLGFXInterface.cpp"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "70"
endingLineNumber = "70"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -66,7 +66,7 @@ protected:
private:
// FIXME(Kevin): Temporary workaround
std::map<std::pair<StringHandle, float>, FontData> m_font_cache;
std::map<std::pair<KDEStringHandle, float>, FontData> m_font_cache;
};
#endif

15
app/src/main/cpp/Gfx.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef KRIMI_DINNER_ENGINE_GFX_H
#define KRIMI_DINNER_ENGINE_GFX_H
struct KDERect
{
float dst_p0_x, dst_p0_y;
float dst_p1_x, dst_p1_y;
float src_p0_x, src_p0_y;
float src_p1_x, src_p1_y;
float r, g, b, a;
int expand_r;
};
#endif

View File

@ -0,0 +1,285 @@
#include "OpenGLGfxInterface.h"
#include "Log.h"
#include "AssetManager.h"
#include "Texture.h"
#include "Profiling.h"
#ifdef _WIN32
#include "glad.h"
#elif defined(__ANDROID__)
#include <GLES3/gl3.h>
#else
#pragma error "Don't compile this!"
#endif
#include <unordered_map>
#include <vector>
#include <assert.h>
static const char* g_vert_src = "#version 300 es \n"
"precision mediump float; \n"
"uniform vec2 res; // resolution \n"
"layout (location = 0) in vec2 v_p0; // top left corner on screen \n"
"layout (location = 1) in vec2 v_p1; // top right corner on screen \n"
"layout (location = 2) in vec2 v_src_p0; \n"
"layout (location = 3) in vec2 v_src_p1; \n"
"layout (location = 4) in vec4 v_color; // color \n"
"layout (location = 5) in int v_expand_r; // \n"
"out vec4 f_color; \n"
"out vec2 f_uv; \n"
"flat out int f_expand_r; \n"
"const vec2 vertices[6] = vec2[6]( \n"
" vec2(-1,-1), \n"
" vec2(+1, -1), \n"
" vec2(-1, +1), \n"
" vec2(+1, -1), \n"
" vec2(+1, +1), \n"
" vec2(-1, +1) \n"
"); \n"
"void main() \n"
"{ \n"
" vec2 v = vertices[gl_VertexID]; \n"
" // destination on screen \n"
" //vec2 dst_half_size = (v_p1 - v_p0) / 2.0; \n"
" //vec2 dst_center = (v_p1 + v_p0) / 2.0; \n"
" vec2 dst_pos = v * ((v_p1 - v_p0) / 2.0) + ((v_p1 + v_p0) / 2.0); \n"
" dst_pos.y = res.y - dst_pos.y; \n"
" vec2 src = v * ((v_src_p1 - v_src_p0) / 2.0) + ((v_src_p1 + v_src_p0) / 2.0); \n"
" gl_Position = vec4(2.0 * dst_pos.x / res.x - 1.0, \n"
" 2.0 * dst_pos.y / res.y - 1.0, \n"
" 0.0, \n"
" 1.0); \n"
" f_color = v_color; \n"
" f_uv = src; \n"
" f_expand_r = v_expand_r; \n"
"} \n";
static const char* g_frag_src = "#version 300 es \n"
"precision mediump float; \n"
"in vec2 f_uv; \n"
"in vec4 f_color; \n"
"flat in int f_expand_r; \n"
"layout (location = 0) out vec4 frag_color; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" vec4 tex_color = texture(s_texture, f_uv); \n"
" if (f_expand_r == 1) \n"
" tex_color = tex_color.rrrr; \n"
" frag_color = tex_color * f_color; \n"
"} \n";
struct OpenGLGfx
{
GLuint m_shader;
GLuint m_vao;
GLuint m_vbo;
KDEStringHandle m_dummy_texture;
std::vector<KDERect> m_rects;
std::vector<KDEStringHandle> m_draw_textures;
std::unordered_map<KDEStringHandle, Texture> m_textures;
}
OpenGLGfx* createOpenGLGfx();
{
ZoneScoped;
OpenGLGFX* gfx = new OpenGLGFX;
GLuint vertex = 0, fragment = 0;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &g_vert_src, nullptr);
glCompileShader(vertex);
int status = 0;
glGetShaderiv(vertex, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetShaderInfoLog(vertex, 512, nullptr, info);
ALOGE("Failed to compile ui vertex shader: %s", info);
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &g_frag_src, nullptr);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetShaderInfoLog(fragment, 512, nullptr, info);
ALOGE("Failed to compile ui fragment shader: %s", info);
}
gfx->m_shader = glCreateProgram();
glAttachShader(gfx->m_shader, vertex);
glAttachShader(gfx->m_shader, fragment);
glLinkProgram(gfx->m_shader);
glGetProgramiv(gfx->m_shader, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetProgramInfoLog(gfx->m_shader, 512, nullptr, info);
ALOGE("Failed to link ui shader: %s", info);
}
glDeleteShader(vertex);
glDeleteShader(fragment);
glGenBuffers(1, &gfx->m_vbo);
glGenVertexArrays(1, &gfx->m_vao);
glBindVertexArray(gfx->m_vao);
glBindBuffer(GL_ARRAY_BUFFER, gfx->m_vbo);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, dst_p1_x));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, src_p0_x));
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, src_p1_x));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, r));
glVertexAttribIPointer(5, 1, GL_INT, sizeof(Rect), (GLvoid*)offsetof(Rect, expand_r));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribDivisor(0, 1);
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
glVertexAttribDivisor(5, 1);
glBindVertexArray(0);
// Dummy texture (1x1px white)
unsigned char tex[] = {255, 255, 255, 255};
Texture dummy_texture(1, 1, tex);
gfx->m_textures.insert(std::make_pair(0, dummy_texture));
m_dummy_texture = 0;
}
void destroyOpenGLGfx(OpenGLGFX* gfx)
{
ZoneScoped;
for (auto texture : gfx->m_textures)
texture.second.destroy();
glDeleteProgram(gfx->m_shader);
glDeleteVertexArrays(1, &gfx->m_vao);
glDeleteBuffers(1, &gfx->m_vbo);
delete gfx;
}
void openGLGfxPushRect(OpenGLGfx* gfx, KDERect rect, KDEStringHandle texture)
{
if (gfx->m_textures.find(texture) == gfx->m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) {
ALOGE("Failed to load texture");
return;
}
gfx->m_textures.insert(std::make_pair(texture, tex));
}
gfx->m_rects.push_back(rect);
gfx->m_draw_textures.push_back(texture);
}
void openGLGfxPushFontRect(OpenGLGfx* gfx, KDERect rect,
float char_height,
KDEStringHandle font,
KDEStringHandle id)
{
if (gfx->m_textures.find(id) == gfx->m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadFontBitmap(StringRepository::global->getString(font), char_height, &tex)) {
ALOGE("Failed to load font");
return;
}
gfx->m_textures.insert(std::make_pair(id, tex));
}
gfx->m_rects.push_back(rect);
gfx->m_draw_textures.push_back(texture);
}
void openGLGetTextureSize(OpenGLGfx* gfx, KDEStringHandle texture, unsigned int* w, unsigned int* h)
{
ZoneScoped;
if (gfx->m_textures.find(texture) == gfx->m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) {
ALOGE("Failed to load texture");
return;
}
gfx->m_textures.insert(std::make_pair(texture, tex));
}
Texture tex = gfx->m_textures[texture];
tex.getTextureSize(w, h);
}
void openGLRenderFrame(OpenGLGfx* gfx, float width, float height)
{
ZoneScoped;
assert(gfx->m_rects.size() == gfx->m_draw_textures.size());
glViewport(0, 0, static_cast<int>(width), static_cast<int>(height));
// glClearColor(0.8f, 0.3f, 0.3f, 1.f);
glClearColor(0.0f, 0.0f, 0.0f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const auto rect_count = static_cast<GLsizei>(gfx->m_rects.size());
if (rect_count == 0)
return;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindVertexArray(gfx->m_vao);
glUseProgram(gfx->m_shader);
glUniform2f(glGetUniformLocation(gfx->m_shader, "res"), width, height);
glUniform1i(glGetUniformLocation(gfx->m_shader, "s_texture"), 0);
glBindBuffer(GL_ARRAY_BUFFER, gfx->m_vbo);
size_t start = 0;
StringHandle current_texture = gfx->m_draw_textures[0];
while (start < rect_count) {
glActiveTexture(GL_TEXTURE0);
gfx->m_textures[current_texture].bind();
for (size_t i = start; i < rect_count; ++i) {
StringHandle texture = gfx->m_draw_textures[i];
if ((texture != current_texture)) {
// Draw everything in [start, i - 1]
const size_t count = i - start;
glBufferData(GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(sizeof(Rect) * count),
&gfx->m_rects[start],
GL_STREAM_DRAW);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast<GLsizei>(count));
start = i;
current_texture = texture;
break;
}
if (i == rect_count - 1) {
// just draw it
const size_t count = rect_count - start;
glBufferData(GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(sizeof(Rect) * count),
&gfx->m_rects[start],
GL_STREAM_DRAW);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast<GLsizei>(count));
start = rect_count;
current_texture = texture;
}
}
}
gfx->m_rects.clear();
gfx->m_draw_textures.clear();
}

View File

@ -0,0 +1,25 @@
#ifndef KRIMI_DINNER_GFX_INTERFACE_H
#define KRIMI_DINNER_GFX_INTERFACE_H
#include "Gfx.h"
#include "StringRepository.h"
struct OpenGLGfx;
OpenGLGfx* createOpenGLGfx();
void destroyOpenGLGfx(OpenGLGfx* gfx);
void openGLGfxPushRect(OpenGLGfx* gfx, KDERect rect, KDEStringHandle texture);
void openGLGfxPushFontRect(OpenGLGfx* gfx, KDERect rect,
float char_height,
KDEStringHandle font,
KDEStringHandle id);
void openGLRenderFrame(OpenGLGfx* gfx, float width, float height);
void openGLGetTextureSize(OpenGLGfx* gfx, KDEStringHandle texture, unsigned int* w, unsigned int* h);
#endif

View File

@ -1,70 +1,22 @@
#include "Renderer.h"
#include "Log.h"
#include "AssetManager.h"
#include "Texture.h"
#include "Profiling.h"
#ifdef __APPLE__
#include "../m/MetalGfxInterface.h"
#else
#include "OpenGLGFXInterface.h"
#endif
#include <assert.h>
Renderer* Renderer::ptr = nullptr;
static const char* g_vert_src = "#version 300 es \n"
"precision mediump float; \n"
"uniform vec2 res; // resolution \n"
"layout (location = 0) in vec2 v_p0; // top left corner on screen \n"
"layout (location = 1) in vec2 v_p1; // top right corner on screen \n"
"layout (location = 2) in vec2 v_src_p0; \n"
"layout (location = 3) in vec2 v_src_p1; \n"
"layout (location = 4) in vec4 v_color; // color \n"
"layout (location = 5) in int v_expand_r; // \n"
"out vec4 f_color; \n"
"out vec2 f_uv; \n"
"flat out int f_expand_r; \n"
"const vec2 vertices[6] = vec2[6]( \n"
" vec2(-1,-1), \n"
" vec2(+1, -1), \n"
" vec2(-1, +1), \n"
" vec2(+1, -1), \n"
" vec2(+1, +1), \n"
" vec2(-1, +1) \n"
"); \n"
"void main() \n"
"{ \n"
" vec2 v = vertices[gl_VertexID]; \n"
" // destination on screen \n"
" //vec2 dst_half_size = (v_p1 - v_p0) / 2.0; \n"
" //vec2 dst_center = (v_p1 + v_p0) / 2.0; \n"
" vec2 dst_pos = v * ((v_p1 - v_p0) / 2.0) + ((v_p1 + v_p0) / 2.0); \n"
" dst_pos.y = res.y - dst_pos.y; \n"
" vec2 src = v * ((v_src_p1 - v_src_p0) / 2.0) + ((v_src_p1 + v_src_p0) / 2.0); \n"
" gl_Position = vec4(2.0 * dst_pos.x / res.x - 1.0, \n"
" 2.0 * dst_pos.y / res.y - 1.0, \n"
" 0.0, \n"
" 1.0); \n"
" f_color = v_color; \n"
" f_uv = src; \n"
" f_expand_r = v_expand_r; \n"
"} \n";
#define DUMMY_TEXTURE 0
static const char* g_frag_src = "#version 300 es \n"
"precision mediump float; \n"
"in vec2 f_uv; \n"
"in vec4 f_color; \n"
"flat in int f_expand_r; \n"
"layout (location = 0) out vec4 frag_color; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" vec4 tex_color = texture(s_texture, f_uv); \n"
" if (f_expand_r == 1) \n"
" tex_color = tex_color.rrrr; \n"
" frag_color = tex_color * f_color; \n"
"} \n";
void Renderer::create()
void Renderer::create(void* gfx)
{
ZoneScoped;
Renderer::ptr = new Renderer;
Renderer::ptr = new Renderer(gfx);
}
void Renderer::destroy()
@ -74,94 +26,24 @@ void Renderer::destroy()
Renderer::ptr = nullptr;
}
Renderer::Renderer()
Renderer::Renderer(void* gfx)
: m_gfx(gfx)
{
ZoneScoped;
GLuint vertex = 0, fragment = 0;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &g_vert_src, nullptr);
glCompileShader(vertex);
int status = 0;
glGetShaderiv(vertex, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetShaderInfoLog(vertex, 512, nullptr, info);
ALOGE("Failed to compile ui vertex shader: %s", info);
}
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &g_frag_src, nullptr);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetShaderInfoLog(fragment, 512, nullptr, info);
ALOGE("Failed to compile ui fragment shader: %s", info);
}
m_shader = glCreateProgram();
glAttachShader(m_shader, vertex);
glAttachShader(m_shader, fragment);
glLinkProgram(m_shader);
glGetProgramiv(m_shader, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
char info[512];
glGetProgramInfoLog(m_shader, 512, nullptr, info);
ALOGE("Failed to link ui shader: %s", info);
}
glDeleteShader(vertex);
glDeleteShader(fragment);
glGenBuffers(1, &m_vbo);
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, dst_p1_x));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, src_p0_x));
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, src_p1_x));
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Rect), (GLvoid*)offsetof(Rect, r));
glVertexAttribIPointer(5, 1, GL_INT, sizeof(Rect), (GLvoid*)offsetof(Rect, expand_r));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glVertexAttribDivisor(0, 1);
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
glVertexAttribDivisor(5, 1);
glBindVertexArray(0);
// Dummy texture (1x1px white)
unsigned char tex[] = {255, 255, 255, 255};
Texture dummy_texture(1, 1, tex);
m_textures.insert(std::make_pair(0, dummy_texture));
m_dummy_texture = 0;
}
Renderer::~Renderer()
{
ZoneScoped;
for (auto texture : m_textures)
texture.second.destroy();
glDeleteProgram(m_shader);
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
}
void Renderer::addRect(float x, float y, float w, float h)
{
ZoneScoped;
addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, m_dummy_texture, 0.f, 0.f, 1.f, 1.f);
addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, DUMMY_TEXTURE, 0.f, 0.f, 1.f, 1.f);
}
void Renderer::addRect(float x, float y, float w, float h, StringHandle texture)
void Renderer::addRect(float x, float y, float w, float h, KDEStringHandle texture)
{
ZoneScoped;
addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, 0.f, 0.f, 1.f, 1.f);
@ -170,10 +52,10 @@ void Renderer::addRect(float x, float y, float w, float h, StringHandle texture)
void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a)
{
ZoneScoped;
addRect(x, y, w, h, r, g, b, a, m_dummy_texture, 0.f, 0.f, 1.f, 1.f);
addRect(x, y, w, h, r, g, b, a, DUMMY_TEXTURE, 0.f, 0.f, 1.f, 1.f);
}
void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture)
void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a, KDEStringHandle texture)
{
ZoneScoped;
addRect(x, y, w, h, r, g, b, a, texture, 0.f, 0.f, 1.f, 1.f);
@ -183,7 +65,7 @@ void Renderer::addRect(float x,
float y,
float w,
float h,
StringHandle texture,
KDEStringHandle texture,
float src_x,
float src_y,
float src_w,
@ -201,23 +83,15 @@ void Renderer::addRect(float x,
float g,
float b,
float a,
StringHandle texture,
KDEStringHandle texture,
float src_x,
float src_y,
float src_w,
float src_h)
{
ZoneScoped;
if (m_textures.find(texture) == m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) {
ALOGE("Failed to load texture");
return;
}
m_textures.insert(std::make_pair(texture, tex));
}
Rect rect = {};
KDERect rect = {};
rect.dst_p0_x = x;
rect.dst_p0_y = y;
rect.dst_p1_x = x + w;
@ -231,8 +105,12 @@ void Renderer::addRect(float x,
rect.b = b;
rect.a = a;
rect.expand_r = 0;
m_rects.push_back(rect);
m_draw_textures.push_back(texture);
#ifdef __APPLE__
metalGfxPushRect(m_gfx, rect, texture);
#else
openGLGfxPushRect((OpenGLGfx*)m_gfx, rect, texture);
#endif
}
void Renderer::addFontRect(float x,
@ -240,8 +118,8 @@ void Renderer::addFontRect(float x,
float w,
float h,
float char_height,
StringHandle font,
StringHandle id,
KDEStringHandle font,
KDEStringHandle id,
float src_x0,
float src_y0,
float src_x1,
@ -260,24 +138,15 @@ void Renderer::addFontRect(float x,
float b,
float a,
float char_height,
StringHandle font,
StringHandle id,
KDEStringHandle font,
KDEStringHandle id,
float src_x0,
float src_y0,
float src_x1,
float src_y1)
{
ZoneScoped;
if (m_textures.find(id) == m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadFontBitmap(StringRepository::global->getString(font), char_height, &tex)) {
ALOGE("Failed to load texture");
return;
}
m_textures.insert(std::make_pair(id, tex));
}
Rect rect = {};
KDERect rect = {};
rect.dst_p0_x = x;
rect.dst_p0_y = y;
rect.dst_p1_x = x + w;
@ -291,86 +160,27 @@ void Renderer::addFontRect(float x,
rect.b = b;
rect.a = a;
rect.expand_r = 1;
m_rects.push_back(rect);
m_draw_textures.push_back(id);
#ifdef __APPLE__
metalGfxPushFontRect(m_gfx, rect, char_height, font, id);
#else
openGLGfxPushFontRect((OpenGLGfx*)m_gfx, rect, char_height, font, id);
#endif
}
void Renderer::renderFrame(float width, float height)
{
ZoneScoped;
assert(m_rects.size() == m_draw_textures.size());
glViewport(0, 0, static_cast<int>(width), static_cast<int>(height));
// glClearColor(0.8f, 0.3f, 0.3f, 1.f);
glClearColor(0.0f, 0.0f, 0.0f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const auto rect_count = static_cast<GLsizei>(m_rects.size());
if (rect_count == 0)
return;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindVertexArray(m_vao);
glUseProgram(m_shader);
glUniform2f(glGetUniformLocation(m_shader, "res"), width, height);
glUniform1i(glGetUniformLocation(m_shader, "s_texture"), 0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
size_t start = 0;
StringHandle current_texture = m_draw_textures[0];
while (start < rect_count) {
glActiveTexture(GL_TEXTURE0);
m_textures[current_texture].bind();
for (size_t i = start; i < rect_count; ++i) {
StringHandle texture = m_draw_textures[i];
if ((texture != current_texture)) {
// Draw everything in [start, i - 1]
const size_t count = i - start;
glBufferData(GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(sizeof(Rect) * count),
&m_rects[start],
GL_STREAM_DRAW);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast<GLsizei>(count));
start = i;
current_texture = texture;
break;
}
if (i == rect_count - 1) {
// just draw it
const size_t count = rect_count - start;
glBufferData(GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(sizeof(Rect) * count),
&m_rects[start],
GL_STREAM_DRAW);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, static_cast<GLsizei>(count));
start = rect_count;
current_texture = texture;
}
}
}
m_rects.clear();
m_draw_textures.clear();
#if defined(_WIN32) || defined(__ANDROID__)
openGLGfxRenderFrame((OpenGLGfx*)m_gfx, width, height);
#endif
}
void Renderer::getTextureSize(StringHandle texture, unsigned int* w, unsigned int* h)
void Renderer::getTextureSize(KDEStringHandle texture, unsigned int* w, unsigned int* h)
{
ZoneScoped;
if (m_textures.find(texture) == m_textures.end()) {
Texture tex;
if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) {
ALOGE("Failed to load texture");
return;
}
m_textures.insert(std::make_pair(texture, tex));
}
Texture tex = m_textures[texture];
tex.getTextureSize(w, h);
}
#ifdef __APPLE__
#else
openGLGfxGetTextureSize((OpenGLGfx*)m_gfx, texture, w, h);
#endif
}

View File

@ -2,15 +2,8 @@
#define KRIMI_DINNER_ENGINE_RENDERER_H
/// @file Renderer.h
/// @brief GLES3 renderer
/// @brief Platform independent renderer interface
#ifdef _WIN32
#include "glad.h"
#else
#include <GLES3/gl3.h>
#endif
#include <unordered_map>
#include <vector>
#include "Texture.h"
#include "StringRepository.h"
@ -23,7 +16,7 @@ public:
static Renderer* ptr;
/// @brief Creates the singleton and sets @ref Renderer::ptr
static void create();
static void create(void* gfx);
/// @brief Destroys the singleton, only call this if you know what you are doing.
static void destroy();
@ -41,7 +34,7 @@ public:
/// \param w width in pixels
/// \param h height in pixels
/// \param texture String handle in the global string repository of the texture file name
void addRect(float x, float y, float w, float h, StringHandle texture);
void addRect(float x, float y, float w, float h, KDEStringHandle texture);
/// @brief Adds a colored rectangle to the screen
/// \param x X-coordinate of the top-left corner
@ -64,7 +57,7 @@ public:
/// \param b blue [0,1]
/// \param a alpha [0,1]
/// \param texture String handle in the global string repository of the texture file name
void addRect(float x, float y, float w, float h, float r, float g, float b, float a, StringHandle texture);
void addRect(float x, float y, float w, float h, float r, float g, float b, float a, KDEStringHandle texture);
/// @brief Adds a textured rectangle to the screen
/// \param x X-coordinate of the top-left corner
@ -80,7 +73,7 @@ public:
float y,
float w,
float h,
StringHandle texture,
KDEStringHandle texture,
float src_x,
float src_y,
float src_w,
@ -108,7 +101,7 @@ public:
float g,
float b,
float a,
StringHandle texture,
KDEStringHandle texture,
float src_x,
float src_y,
float src_w,
@ -130,8 +123,8 @@ public:
float w,
float h,
float char_height,
StringHandle font,
StringHandle id,
KDEStringHandle font,
KDEStringHandle id,
float src_x0,
float src_y0,
float src_x1,
@ -161,8 +154,8 @@ public:
float b,
float a,
float char_height,
StringHandle font,
StringHandle id,
KDEStringHandle font,
KDEStringHandle id,
float src_x0,
float src_y0,
float src_x1,
@ -179,37 +172,18 @@ public:
/// \param w output width in pixels
/// \param h output height in pixels
void getTextureSize(
StringHandle texture,
KDEStringHandle texture,
unsigned int* w,
unsigned int* h);
private:
Renderer();
Renderer(void* gfx);
~Renderer();
Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete;
struct Rect
{
float dst_p0_x, dst_p0_y;
float dst_p1_x, dst_p1_y;
float src_p0_x, src_p0_y;
float src_p1_x, src_p1_y;
float r, g, b, a;
int expand_r;
};
GLuint m_shader;
GLuint m_vao;
GLuint m_vbo;
StringHandle m_dummy_texture;
std::vector<Rect> m_rects;
std::vector<StringHandle> m_draw_textures;
std::unordered_map<StringHandle, Texture> m_textures;
void *m_gfx;
};
#endif
#endif

View File

@ -40,7 +40,7 @@ StringRepository::~StringRepository()
free(m_buffer);
}
StringHandle StringRepository::internStringLength(const char* string, unsigned int length)
KDEStringHandle StringRepository::internStringLength(const char* string, unsigned int length)
{
ZoneScoped;
uint64_t hash = hashString(string, length);
@ -62,16 +62,16 @@ StringHandle StringRepository::internStringLength(const char* string, unsigned i
if (!m_hash.insert(hash, offset))
return 0;
}
return static_cast<StringHandle>(offset + 1);
return static_cast<KDEStringHandle>(offset + 1);
}
StringHandle StringRepository::internString(const char* string)
KDEStringHandle StringRepository::internString(const char* string)
{
ZoneScoped;
return internStringLength(string, strlen(string));
}
const char* StringRepository::getString(StringHandle handle)
const char* StringRepository::getString(KDEStringHandle handle)
{
ZoneScoped;
if (handle == 0 || handle >= m_one_past_last_char)
@ -80,13 +80,13 @@ const char* StringRepository::getString(StringHandle handle)
return &m_buffer[offset];
}
void StringRepository::releaseString(StringHandle)
void StringRepository::releaseString(KDEStringHandle)
{
// do nothing
}
StringHandle StringRepository::concatenateString(StringHandle a, StringHandle b)
KDEStringHandle StringRepository::concatenateString(KDEStringHandle a, KDEStringHandle b)
{
ZoneScoped;
const char* texta = getString(a);

View File

@ -8,10 +8,10 @@
#include "Hash.h"
/// A string handle
using StringHandle = uint32_t;
using KDEStringHandle = uint32_t;
// Alias for compatibility
using nt_string_handle = StringHandle;
using nt_string_handle = KDEStringHandle;
/// @brief Stores strings
class StringRepository
@ -27,24 +27,24 @@ public:
/// @brief Adds a string to the string repository
/// @param string the string
/// @param length length in bytes
StringHandle internStringLength(const char* string, unsigned int length);
KDEStringHandle internStringLength(const char* string, unsigned int length);
/// @brief Adds a string to the string repository
/// @param string the string
StringHandle internString(const char* string);
KDEStringHandle internString(const char* string);
/// @brief Retrieves a string value
/// @param handle The string handle
/// @return The string
const char* getString(StringHandle handle);
const char* getString(KDEStringHandle handle);
/// @brief Frees a string
void releaseString(StringHandle handle);
void releaseString(KDEStringHandle handle);
/// @brief Adds a string to the string repository
/// @param a the first string
/// @param b the second string
StringHandle concatenateString(StringHandle a, StringHandle b);
KDEStringHandle concatenateString(KDEStringHandle a, KDEStringHandle b);
/// @brief Frees all strings inside the repository
void freeAll();
@ -56,4 +56,4 @@ private:
Hash m_hash;
};
#endif
#endif

View File

@ -6,36 +6,40 @@
//
#import "GameViewController.h"
#import "Renderer.h"
#import "MetalViewDelegate.h"
#include "../cpp/Renderer.h"
@implementation GameViewController
{
MTKView *_view;
Renderer *_renderer;
MetalViewDelegate *_renderer;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_view = (MTKView *)self.view;
_view.device = MTLCreateSystemDefaultDevice();
_view.backgroundColor = UIColor.blackColor;
if(!_view.device)
{
NSLog(@"Metal is not supported on this device");
self.view = [[UIView alloc] initWithFrame:self.view.frame];
return;
}
_renderer = [[Renderer alloc] initWithMetalKitView:_view];
_renderer = [[MetalViewDelegate alloc] initWithMetalKitView:_view];
[_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size];
_view.delegate = _renderer;
Renderer::create((__bridge void*)_renderer);
}
@end

View File

@ -0,0 +1,11 @@
#ifndef KRIMI_DINNER_ENGINE_METAL_GFX_INTERFACE_H
#define KRIMI_DINNER_ENGINE_METAL_GFX_INTERFACE_H
#include "../cpp/Gfx.h"
#include "../cpp/StringRepository.h"
void metalGfxPushRect(void* metalGfxObj, KDERect rect, KDEStringHandle texture);
void metalGfxPushFontRect(void* metalGfxObj, KDERect rect, float char_height, KDEStringHandle font, KDEStringHandle key);
#endif

View File

@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
#import "MetalViewDelegate.h"
void metalGfxPushRect(void* metalGfxObj, KDERect rect, KDEStringHandle texture)
{
[(__bridge id) metalGfxObj pushRect: rect withTexture: texture];
}
void metalGfxPushFontRect(void* metalGfxObj, KDERect rect, float char_height, KDEStringHandle font, KDEStringHandle key)
{
[(__bridge id)metalGfxObj pushRect:rect withFont:font withCharHeight:char_height withKey:key];
}

View File

@ -7,11 +7,18 @@
#import <MetalKit/MetalKit.h>
#include "../cpp/Gfx.h"
#include "../cpp/StringRepository.h"
// Our platform independent renderer class. Implements the MTKViewDelegate protocol which
// allows it to accept per-frame update and drawable resize callbacks.
@interface Renderer : NSObject <MTKViewDelegate>
@interface MetalViewDelegate : NSObject <MTKViewDelegate>
-(nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)view;
-(void)pushRect:(KDERect)rect withTexture:(KDEStringHandle)texture;
-(void)pushRect:(KDERect)rect withFont:(KDEStringHandle)font withCharHeight:(float)char_height withKey:(KDEStringHandle)key;
@end

View File

@ -8,14 +8,16 @@
#import <simd/simd.h>
#import <ModelIO/ModelIO.h>
#import "Renderer.h"
#import "MetalViewDelegate.h"
// Include header shared between C code here, which executes Metal API commands, and .metal files
#import "ShaderTypes.h"
#include "../cpp/Renderer.h"
static const NSUInteger MaxBuffersInFlight = 3;
@implementation Renderer
@implementation MetalViewDelegate
{
dispatch_semaphore_t _inFlightSemaphore;
id <MTLDevice> _device;
@ -169,8 +171,27 @@ static const NSUInteger MaxBuffersInFlight = 3;
- (void)_updateGameState
{
/// Update any game state before encoding renderint commands to our drawable
// Demo code
static float x = 1.f;
static float d = -0.01f;
x += d;
if (x <= 0.f)
d *= -1.f;
else if (x >= 1.f)
d *= -1.f;
#if 0
if (input_event_count > 0) {
m_smiley_pos = input_events[input_event_count - 1].end;
m_smiley_pos.x -= 250;
m_smiley_pos.y -= 250;
}
#endif
Renderer::ptr->addRect(100, 100, 500, 500, 0.3f, 0.3f, 0.3f, 1.f);
//Renderer::ptr->addRect(m_smiley_pos.x, m_smiley_pos.y, 500, 500, 0.f, x * x, 1.f - x * x, 1.f, m_smiley);
/// Update any game state before encoding renderint commands to our drawable
Uniforms * uniforms = (Uniforms*)_dynamicUniformBuffer[_uniformBufferIndex].contents;
uniforms->projectionMatrix = _projectionMatrix;
@ -271,6 +292,17 @@ static const NSUInteger MaxBuffersInFlight = 3;
_projectionMatrix = matrix_perspective_right_hand(65.0f * (M_PI / 180.0f), aspect, 0.1f, 100.0f);
}
- (void)pushRect:(KDERect)rect withTexture:(KDEStringHandle)texture
{
// TODO
}
- (void)pushRect:(KDERect)rect withFont:(KDEStringHandle)font withCharHeight:(float)char_height withKey:(KDEStringHandle)key
{
// TODO
}
#pragma mark Matrix Math Utilities
matrix_float4x4 matrix4x4_translation(float tx, float ty, float tz)