1 /** 2 * Copyright: Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved 3 * Authors: $(Gabriel Gheorghe) 4 * License: $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007) 5 * Source: $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/graphics/renderer.d, _renderer.d) 6 * Documentation: 7 * Coverage: 8 */ 9 module liberty.graphics.renderer; 10 import liberty.math.vector : Vector2F, Vector3F; 11 import liberty.graphics.util : RenderUtil; 12 import liberty.graphics.video.vertex : VertexSpec; 13 import liberty.graphics.video.vao : VertexArray; 14 import liberty.graphics.video.buffer : VideoBuffer, BufferTarget; 15 import liberty.graphics.video.shader : ShaderProgram; 16 import derelict.opengl; 17 import liberty.core.imaging; 18 import liberty.core.engine; 19 import liberty.math; 20 import liberty.core.time; 21 import liberty.math.vector; 22 import derelict.sdl2.sdl : SDL_GL_SetSwapInterval; 23 import liberty.graphics.video.backend : VideoBackend; 24 import liberty.core.engine; 25 import liberty.core.model; 26 import liberty.graphics.material; 27 import liberty.core.utils : Singleton, IService; 28 //import sunshine.graphics.video.vao : VertexArrayObject; 29 version (__OpenGL__) { 30 import liberty.graphics.opengl.backend : GLBackend; 31 import liberty.graphics.opengl.buffer : GLBuffer; 32 //import sunshine.graphics.opengl.vao : GLVertexArrayObject; 33 import derelict.opengl : glPolygonMode, GL_FRONT_AND_BACK, GL_LINE, GL_FILL; 34 } else version (__Vulkan__) { 35 import liberty.graphics.vulkan.backend : VKBackend; 36 import liberty.graphics.vulkan.buffer : VKBuffer; 37 } else version (__WASM__) { 38 import liberty.graphics.wasm.backend : WASMBackend; 39 } 40 /// 41 class GraphicsEngine : Singleton!GraphicsEngine, IService { 42 private { 43 private bool _serviceRunning; 44 VideoBackend _backend; 45 bool _vsyncEnabled = false; 46 bool _wireframe = false; 47 Vector4F _color = Vector4F(1.0, 1.0, 1.0, 1.0); 48 } 49 /// Start GraphicsEngine service. 50 void startService() @trusted { 51 version (__OpenGL__) { 52 _backend = new GLBackend(); 53 } else version (__Vulkan__) { 54 _backend = new VKBackend(); 55 } else version (__WASM__) { 56 _backend = new WASMBackend(); 57 } 58 _serviceRunning = true; 59 } 60 /// Stop GraphicsEngine service. 61 void stopService() @trusted { 62 if (_backend !is null) { 63 _backend.destroy(); 64 _backend = null; 65 } 66 _serviceRunning = false; 67 } 68 /// Restart GraphicsEngine service. 69 void restartService() @trusted { 70 stopService(); 71 startService(); 72 } 73 /// Returns true if GraphicsEngine service is running. 74 bool isServiceRunning() pure nothrow const @safe @nogc { 75 return _serviceRunning; 76 } 77 /// 78 VideoBackend backend() { 79 return _backend; 80 } 81 /// 82 void render() { 83 import derelict.opengl; 84 glEnable(GL_DEPTH_TEST); 85 glEnable(GL_CULL_FACE); 86 glFrontFace(GL_CW); 87 _backend.resizeViewport(); 88 _backend.clear(); 89 //_backend.enableDepthTest(); // TODO. + culling. 90 _backend.clearColor(_color.r, _color.g, _color.b, _color.a); 91 CoreEngine.get.activeScene.render(); 92 _backend.swapBuffers(); 93 } 94 /// 95 void vSyncEnabled(bool enabled = true) { 96 SDL_GL_SetSwapInterval(enabled); // TODO: VULKAN? 97 _vsyncEnabled = enabled; 98 } 99 /// 100 bool isVSyncEnabled() nothrow { 101 return _vsyncEnabled; 102 } 103 /// 104 void windowBackgroundColor(float r, float g, float b, float a = 1.0f) { 105 _color = Vector4F(r, g, b, a); 106 } 107 /// 108 void windowBackgroundColor(Vector3F color, float a = 1.0f) { 109 _color = Vector4F(color, a); 110 } 111 /// 112 void windowBackgroundColor(Vector4F color) { 113 _color = color; 114 } 115 /// 116 void toggleWireframe() { // TODO: Vulkan. 117 version (__OpenGL__) { 118 if (!_wireframe) { 119 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 120 } else { 121 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 122 } 123 } 124 _wireframe = !_wireframe; 125 } 126 } 127 /// 128 static struct Vertex { 129 Vector3F position; 130 Vector2F texCoords; 131 } 132 /// 133 enum Vendor : byte { 134 /// 135 Amd = 0x00, 136 /// 137 Intel = 0x01, 138 /// 139 Nvidia = 0x02, 140 /// 141 Mesa = 0x03, 142 /// For Software rendering, no driver 143 Apple = 0x04, 144 /// For GDI Generic, no driver 145 Microsoft = 0x05, 146 /// 147 Other = -0x01 148 } 149 /// 150 enum Blending : byte { 151 /// 152 Opaque = 0x00, 153 /// 154 AlphaBlend = 0x01, 155 /// 156 NonPremultiplied = 0x02, 157 /// 158 Additive = 0x03 159 } 160 /// 161 enum Sampling : byte { 162 /// 163 AnisotropicClamp = 0x00, 164 /// 165 AnisotropicWrap = 0x01, 166 /// 167 LinearClamp = 0x02, 168 /// 169 LinearWrap = 0x03, 170 /// 171 PointClamp = 0x04, 172 /// 173 PointWrap = 0x05 174 } 175 /// 176 enum VSyncState : byte { 177 /// 178 Immediate = 0x00, 179 /// 180 Default = 0x01, 181 /// 182 LateTearing = -0x01 183 // TODO: GSync / FreeSync ? 184 } 185 /// 186 enum DataUsage : byte { 187 /// 188 StreamDraw = 0x00, 189 /// 190 StreamRead = 0x01, 191 /// 192 StreamCopy = 0x02, 193 /// 194 StaticDraw = 0x03, 195 /// 196 StaticRead = 0x04, 197 /// 198 StaticCopy = 0x05, 199 /// 200 DynamicDraw = 0x06, 201 /// 202 DynamicRead = 0x07, 203 /// 204 DynamicCopy = 0x08 205 } 206 /// 207 enum DrawMode : byte { 208 /// 209 Triangles = 0x00 210 } 211 /// 212 enum VectorType : byte { 213 /// 214 UnsignedInt = 0x00 215 } 216 /// 217 interface Renderable { 218 /// 219 void render(); 220 }