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 */ /* Begin PBXBuildFile section */
FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A74F2A50790A00F960DA /* AppDelegate.m */; }; FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A74F2A50790A00F960DA /* AppDelegate.m */; };
FBA9A7532A50790A00F960DA /* Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7522A50790A00F960DA /* Renderer.m */; }; FBA9A7532A50790A00F960DA /* MetalViewDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */; };
FBA9A7562A50790A00F960DA /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7552A50790A00F960DA /* GameViewController.m */; }; FBA9A7562A50790A00F960DA /* GameViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7552A50790A00F960DA /* GameViewController.mm */; };
FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7572A50790A00F960DA /* Shaders.metal */; }; FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A7572A50790A00F960DA /* Shaders.metal */; };
FBA9A75C2A50790A00F960DA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FBA9A75A2A50790A00F960DA /* Main.storyboard */; }; FBA9A75C2A50790A00F960DA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FBA9A75A2A50790A00F960DA /* Main.storyboard */; };
FBA9A75E2A50790A00F960DA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FBA9A75D2A50790A00F960DA /* Assets.xcassets */; }; 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 */; }; FBA9A7692A50795400F960DA /* AssetManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73D2A5078B800F960DA /* AssetManager.cpp */; };
FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73A2A5078B800F960DA /* Hash.cpp */; }; FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73A2A5078B800F960DA /* Hash.cpp */; };
FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FBA9A73F2A5078D800F960DA /* Texture.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 */ /* End PBXBuildFile section */
/* Begin PBXFileReference 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; }; 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>"; }; 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>"; }; 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>"; }; FBA9A7512A50790A00F960DA /* MetalViewDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MetalViewDelegate.h; sourceTree = "<group>"; };
FBA9A7522A50790A00F960DA /* Renderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Renderer.m; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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 */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -58,6 +73,9 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
FBA9A7832A50A82D00F960DA /* ModelIO.framework in Frameworks */,
FBA9A7802A50A82500F960DA /* Metal.framework in Frameworks */,
FBA9A7812A50A82500F960DA /* MetalKit.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -67,6 +85,11 @@
FBA9A7332A50789900F960DA /* cpp */ = { FBA9A7332A50789900F960DA /* cpp */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FBA9A77A2A50A65400F960DA /* OpenGLGFXInterface.cpp */,
FBA9A77B2A50A65400F960DA /* OpenGLGFXInterface.h */,
FBA9A7722A509C6500F960DA /* Renderer.cpp */,
FBA9A7712A509A4400F960DA /* Gfx.h */,
FBA9A76D2A5096DF00F960DA /* Renderer.h */,
FBA9A7412A5078D800F960DA /* stb_image.h */, FBA9A7412A5078D800F960DA /* stb_image.h */,
FBA9A7402A5078D800F960DA /* stb_truetype.h */, FBA9A7402A5078D800F960DA /* stb_truetype.h */,
FBA9A7432A5078D800F960DA /* StringRepository.cpp */, FBA9A7432A5078D800F960DA /* StringRepository.cpp */,
@ -92,16 +115,18 @@
children = ( children = (
FBA9A74E2A50790A00F960DA /* AppDelegate.h */, FBA9A74E2A50790A00F960DA /* AppDelegate.h */,
FBA9A74F2A50790A00F960DA /* AppDelegate.m */, FBA9A74F2A50790A00F960DA /* AppDelegate.m */,
FBA9A7512A50790A00F960DA /* Renderer.h */, FBA9A7512A50790A00F960DA /* MetalViewDelegate.h */,
FBA9A7522A50790A00F960DA /* Renderer.m */, FBA9A7522A50790A00F960DA /* MetalViewDelegate.mm */,
FBA9A7542A50790A00F960DA /* GameViewController.h */, FBA9A7542A50790A00F960DA /* GameViewController.h */,
FBA9A7552A50790A00F960DA /* GameViewController.m */, FBA9A7552A50790A00F960DA /* GameViewController.mm */,
FBA9A7572A50790A00F960DA /* Shaders.metal */, FBA9A7572A50790A00F960DA /* Shaders.metal */,
FBA9A7592A50790A00F960DA /* ShaderTypes.h */, FBA9A7592A50790A00F960DA /* ShaderTypes.h */,
FBA9A75A2A50790A00F960DA /* Main.storyboard */, FBA9A75A2A50790A00F960DA /* Main.storyboard */,
FBA9A75D2A50790A00F960DA /* Assets.xcassets */, FBA9A75D2A50790A00F960DA /* Assets.xcassets */,
FBA9A75F2A50790A00F960DA /* LaunchScreen.storyboard */, FBA9A75F2A50790A00F960DA /* LaunchScreen.storyboard */,
FBA9A7622A50790A00F960DA /* main.m */, FBA9A7622A50790A00F960DA /* main.m */,
FBA9A76C2A5096C500F960DA /* MetalGfxInterface.h */,
FBA9A76F2A5098E800F960DA /* MetalGfxInterface.mm */,
); );
path = m; path = m;
sourceTree = "<group>"; sourceTree = "<group>";
@ -114,12 +139,23 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FBA9A77D2A50A82400F960DA /* Frameworks */ = {
isa = PBXGroup;
children = (
FBA9A7822A50A82C00F960DA /* ModelIO.framework */,
FBA9A77E2A50A82400F960DA /* Metal.framework */,
FBA9A77F2A50A82400F960DA /* MetalKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
FBC6DF7A2A50782C00CA10E7 = { FBC6DF7A2A50782C00CA10E7 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FBA9A7462A5078DC00F960DA /* m */, FBA9A7462A5078DC00F960DA /* m */,
FBA9A7332A50789900F960DA /* cpp */, FBA9A7332A50789900F960DA /* cpp */,
FBA9A74C2A50790A00F960DA /* Products */, FBA9A74C2A50790A00F960DA /* Products */,
FBA9A77D2A50A82400F960DA /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -197,10 +233,12 @@
FBA9A7632A50790A00F960DA /* main.m in Sources */, FBA9A7632A50790A00F960DA /* main.m in Sources */,
FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */, FBA9A7582A50790A00F960DA /* Shaders.metal in Sources */,
FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */, FBA9A76B2A5079BC00F960DA /* Texture.cpp in Sources */,
FBA9A7762A50A58000F960DA /* Renderer.cpp in Sources */,
FBA9A7682A50795000F960DA /* StringRepository.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 */, FBA9A76A2A50795700F960DA /* Hash.cpp in Sources */,
FBA9A7562A50790A00F960DA /* GameViewController.m in Sources */, FBA9A7562A50790A00F960DA /* GameViewController.mm in Sources */,
FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */, FBA9A7502A50790A00F960DA /* AppDelegate.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; 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: private:
// FIXME(Kevin): Temporary workaround // 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 #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 "Renderer.h"
#include "Log.h"
#include "AssetManager.h"
#include "Texture.h"
#include "Profiling.h" #include "Profiling.h"
#ifdef __APPLE__
#include "../m/MetalGfxInterface.h"
#else
#include "OpenGLGFXInterface.h"
#endif
#include <assert.h> #include <assert.h>
Renderer* Renderer::ptr = nullptr; Renderer* Renderer::ptr = nullptr;
static const char* g_vert_src = "#version 300 es \n" #define DUMMY_TEXTURE 0
"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" void Renderer::create(void* gfx)
"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()
{ {
ZoneScoped; ZoneScoped;
Renderer::ptr = new Renderer; Renderer::ptr = new Renderer(gfx);
} }
void Renderer::destroy() void Renderer::destroy()
@ -74,94 +26,24 @@ void Renderer::destroy()
Renderer::ptr = nullptr; Renderer::ptr = nullptr;
} }
Renderer::Renderer() Renderer::Renderer(void* gfx)
: m_gfx(gfx)
{ {
ZoneScoped; 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() Renderer::~Renderer()
{ {
ZoneScoped; 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) void Renderer::addRect(float x, float y, float w, float h)
{ {
ZoneScoped; 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; ZoneScoped;
addRect(x, y, w, h, 1.f, 1.f, 1.f, 1.f, texture, 0.f, 0.f, 1.f, 1.f); 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) void Renderer::addRect(float x, float y, float w, float h, float r, float g, float b, float a)
{ {
ZoneScoped; 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; ZoneScoped;
addRect(x, y, w, h, r, g, b, a, texture, 0.f, 0.f, 1.f, 1.f); 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 y,
float w, float w,
float h, float h,
StringHandle texture, KDEStringHandle texture,
float src_x, float src_x,
float src_y, float src_y,
float src_w, float src_w,
@ -201,23 +83,15 @@ void Renderer::addRect(float x,
float g, float g,
float b, float b,
float a, float a,
StringHandle texture, KDEStringHandle texture,
float src_x, float src_x,
float src_y, float src_y,
float src_w, float src_w,
float src_h) float src_h)
{ {
ZoneScoped; 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_x = x;
rect.dst_p0_y = y; rect.dst_p0_y = y;
rect.dst_p1_x = x + w; rect.dst_p1_x = x + w;
@ -231,8 +105,12 @@ void Renderer::addRect(float x,
rect.b = b; rect.b = b;
rect.a = a; rect.a = a;
rect.expand_r = 0; 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, void Renderer::addFontRect(float x,
@ -240,8 +118,8 @@ void Renderer::addFontRect(float x,
float w, float w,
float h, float h,
float char_height, float char_height,
StringHandle font, KDEStringHandle font,
StringHandle id, KDEStringHandle id,
float src_x0, float src_x0,
float src_y0, float src_y0,
float src_x1, float src_x1,
@ -260,24 +138,15 @@ void Renderer::addFontRect(float x,
float b, float b,
float a, float a,
float char_height, float char_height,
StringHandle font, KDEStringHandle font,
StringHandle id, KDEStringHandle id,
float src_x0, float src_x0,
float src_y0, float src_y0,
float src_x1, float src_x1,
float src_y1) float src_y1)
{ {
ZoneScoped; ZoneScoped;
if (m_textures.find(id) == m_textures.end()) { KDERect rect = {};
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 = {};
rect.dst_p0_x = x; rect.dst_p0_x = x;
rect.dst_p0_y = y; rect.dst_p0_y = y;
rect.dst_p1_x = x + w; rect.dst_p1_x = x + w;
@ -291,86 +160,27 @@ void Renderer::addFontRect(float x,
rect.b = b; rect.b = b;
rect.a = a; rect.a = a;
rect.expand_r = 1; 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) void Renderer::renderFrame(float width, float height)
{ {
ZoneScoped; #if defined(_WIN32) || defined(__ANDROID__)
assert(m_rects.size() == m_draw_textures.size()); openGLGfxRenderFrame((OpenGLGfx*)m_gfx, width, height);
#endif
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();
} }
void Renderer::getTextureSize(StringHandle texture, unsigned int* w, unsigned int* h) void Renderer::getTextureSize(KDEStringHandle texture, unsigned int* w, unsigned int* h)
{ {
ZoneScoped; #ifdef __APPLE__
if (m_textures.find(texture) == m_textures.end()) {
Texture tex; #else
if (!AssetManager::ptr->loadTexture(StringRepository::global->getString(texture), &tex)) { openGLGfxGetTextureSize((OpenGLGfx*)m_gfx, texture, w, h);
ALOGE("Failed to load texture"); #endif
return; }
}
m_textures.insert(std::make_pair(texture, tex));
}
Texture tex = m_textures[texture];
tex.getTextureSize(w, h);
}

View File

@ -2,15 +2,8 @@
#define KRIMI_DINNER_ENGINE_RENDERER_H #define KRIMI_DINNER_ENGINE_RENDERER_H
/// @file 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 "Texture.h"
#include "StringRepository.h" #include "StringRepository.h"
@ -23,7 +16,7 @@ public:
static Renderer* ptr; static Renderer* ptr;
/// @brief Creates the singleton and sets @ref 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. /// @brief Destroys the singleton, only call this if you know what you are doing.
static void destroy(); static void destroy();
@ -41,7 +34,7 @@ public:
/// \param w width in pixels /// \param w width in pixels
/// \param h height in pixels /// \param h height in pixels
/// \param texture String handle in the global string repository of the texture file name /// \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 /// @brief Adds a colored rectangle to the screen
/// \param x X-coordinate of the top-left corner /// \param x X-coordinate of the top-left corner
@ -64,7 +57,7 @@ public:
/// \param b blue [0,1] /// \param b blue [0,1]
/// \param a alpha [0,1] /// \param a alpha [0,1]
/// \param texture String handle in the global string repository of the texture file name /// \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 /// @brief Adds a textured rectangle to the screen
/// \param x X-coordinate of the top-left corner /// \param x X-coordinate of the top-left corner
@ -80,7 +73,7 @@ public:
float y, float y,
float w, float w,
float h, float h,
StringHandle texture, KDEStringHandle texture,
float src_x, float src_x,
float src_y, float src_y,
float src_w, float src_w,
@ -108,7 +101,7 @@ public:
float g, float g,
float b, float b,
float a, float a,
StringHandle texture, KDEStringHandle texture,
float src_x, float src_x,
float src_y, float src_y,
float src_w, float src_w,
@ -130,8 +123,8 @@ public:
float w, float w,
float h, float h,
float char_height, float char_height,
StringHandle font, KDEStringHandle font,
StringHandle id, KDEStringHandle id,
float src_x0, float src_x0,
float src_y0, float src_y0,
float src_x1, float src_x1,
@ -161,8 +154,8 @@ public:
float b, float b,
float a, float a,
float char_height, float char_height,
StringHandle font, KDEStringHandle font,
StringHandle id, KDEStringHandle id,
float src_x0, float src_x0,
float src_y0, float src_y0,
float src_x1, float src_x1,
@ -179,37 +172,18 @@ public:
/// \param w output width in pixels /// \param w output width in pixels
/// \param h output height in pixels /// \param h output height in pixels
void getTextureSize( void getTextureSize(
StringHandle texture, KDEStringHandle texture,
unsigned int* w, unsigned int* w,
unsigned int* h); unsigned int* h);
private: private:
Renderer(); Renderer(void* gfx);
~Renderer(); ~Renderer();
Renderer(const Renderer&) = delete; Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete; Renderer& operator=(const Renderer&) = delete;
struct Rect void *m_gfx;
{
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;
}; };
#endif #endif

View File

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

View File

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

View File

@ -6,36 +6,40 @@
// //
#import "GameViewController.h" #import "GameViewController.h"
#import "Renderer.h" #import "MetalViewDelegate.h"
#include "../cpp/Renderer.h"
@implementation GameViewController @implementation GameViewController
{ {
MTKView *_view; MTKView *_view;
Renderer *_renderer; MetalViewDelegate *_renderer;
} }
- (void)viewDidLoad - (void)viewDidLoad
{ {
[super viewDidLoad]; [super viewDidLoad];
_view = (MTKView *)self.view; _view = (MTKView *)self.view;
_view.device = MTLCreateSystemDefaultDevice(); _view.device = MTLCreateSystemDefaultDevice();
_view.backgroundColor = UIColor.blackColor; _view.backgroundColor = UIColor.blackColor;
if(!_view.device) if(!_view.device)
{ {
NSLog(@"Metal is not supported on this device"); NSLog(@"Metal is not supported on this device");
self.view = [[UIView alloc] initWithFrame:self.view.frame]; self.view = [[UIView alloc] initWithFrame:self.view.frame];
return; return;
} }
_renderer = [[Renderer alloc] initWithMetalKitView:_view]; _renderer = [[MetalViewDelegate alloc] initWithMetalKitView:_view];
[_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size]; [_renderer mtkView:_view drawableSizeWillChange:_view.bounds.size];
_view.delegate = _renderer; _view.delegate = _renderer;
Renderer::create((__bridge void*)_renderer);
} }
@end @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> #import <MetalKit/MetalKit.h>
#include "../cpp/Gfx.h"
#include "../cpp/StringRepository.h"
// Our platform independent renderer class. Implements the MTKViewDelegate protocol which // Our platform independent renderer class. Implements the MTKViewDelegate protocol which
// allows it to accept per-frame update and drawable resize callbacks. // 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; -(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 @end

View File

@ -8,14 +8,16 @@
#import <simd/simd.h> #import <simd/simd.h>
#import <ModelIO/ModelIO.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 // Include header shared between C code here, which executes Metal API commands, and .metal files
#import "ShaderTypes.h" #import "ShaderTypes.h"
#include "../cpp/Renderer.h"
static const NSUInteger MaxBuffersInFlight = 3; static const NSUInteger MaxBuffersInFlight = 3;
@implementation Renderer @implementation MetalViewDelegate
{ {
dispatch_semaphore_t _inFlightSemaphore; dispatch_semaphore_t _inFlightSemaphore;
id <MTLDevice> _device; id <MTLDevice> _device;
@ -169,8 +171,27 @@ static const NSUInteger MaxBuffersInFlight = 3;
- (void)_updateGameState - (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 * uniforms = (Uniforms*)_dynamicUniformBuffer[_uniformBufferIndex].contents;
uniforms->projectionMatrix = _projectionMatrix; 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); _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 #pragma mark Matrix Math Utilities
matrix_float4x4 matrix4x4_translation(float tx, float ty, float tz) matrix_float4x4 matrix4x4_translation(float tx, float ty, float tz)