1 module rpui.render.renderer; 2 3 import std.math; 4 5 import gapi.vec; 6 import gapi.transform; 7 import gapi.shader; 8 import gapi.shader_uniform; 9 import gapi.texture; 10 import gapi.geometry; 11 import gapi.geometry_quad; 12 import gapi.opengl; 13 import gapi.font; 14 import gapi.text; 15 16 import rpui.events; 17 import rpui.theme; 18 import rpui.widget; 19 import rpui.render.components; 20 import rpui.primitives; 21 22 interface Renderer { 23 void onCreate(Widget widget, in string style); 24 25 void onRender(); 26 27 void onProgress(in ProgressEvent event); 28 } 29 30 class DummyRenderer : Renderer { 31 override void onCreate(Widget widget, in string style) { 32 } 33 34 override void onRender() { 35 } 36 37 override void onProgress(in ProgressEvent event) { 38 } 39 } 40 41 interface RenderSystem { 42 void onRender(); 43 } 44 45 void renderTexAtlasQuad( 46 in Theme theme, 47 in StatefulTexAtlasTextureQuad quad, 48 in QuadTransforms transforms, 49 in float alpha = 1.0f, 50 ) { 51 renderTexAtlasQuad( 52 theme, 53 quad.geometry, 54 quad.texture, 55 quad.texCoords[quad.state].normilizedTexCoords, 56 transforms, 57 alpha 58 ); 59 } 60 61 void renderTexAtlasQuad( 62 in Theme theme, 63 in TexAtlasTextureQuad quad, 64 in QuadTransforms transforms, 65 in float alpha = 1.0f, 66 ) { 67 renderTexAtlasQuad( 68 theme, 69 quad.geometry, 70 quad.texture, 71 quad.texCoords.normilizedTexCoords, 72 transforms, 73 alpha 74 ); 75 } 76 77 void renderTexAtlasQuad( 78 in Theme theme, 79 in Geometry geometry, 80 in Texture2D texture, 81 in Texture2DCoords texCoord, 82 in QuadTransforms transforms, 83 in float alpha = 1.0f, 84 ) { 85 const shader = theme.shaders.textureAtlasShader; 86 bindShaderProgram(shader); 87 88 setShaderProgramUniformMatrix(shader, "MVP", transforms.mvpMatrix); 89 setShaderProgramUniformTexture(shader, "texture", texture, 0); 90 setShaderProgramUniformVec2f(shader,"texOffset", texCoord.offset); 91 setShaderProgramUniformVec2f(shader,"texSize", texCoord.size); 92 setShaderProgramUniformFloat(shader, "alpha", alpha); 93 94 bindVAO(geometry.vao); 95 bindIndices(geometry.indicesBuffer); 96 renderIndexedGeometry(cast(uint) quadIndices.length, GL_TRIANGLE_STRIP); 97 } 98 99 void renderColorQuad( 100 in Theme theme, 101 in Geometry geometry, 102 in vec4 color, 103 in QuadTransforms transforms 104 ) { 105 const shader = theme.shaders.colorShader; 106 bindShaderProgram(shader); 107 108 setShaderProgramUniformMatrix(shader, "MVP", transforms.mvpMatrix); 109 setShaderProgramUniformVec4f(shader, "color", color); 110 111 bindVAO(geometry.vao); 112 bindIndices(geometry.indicesBuffer); 113 renderIndexedGeometry(cast(uint) quadIndices.length, GL_TRIANGLE_STRIP); 114 } 115 116 void renderColorLines( 117 in Theme theme, 118 in LinesGeometry geometry, 119 in vec4 color, 120 in LinesTransforms transforms 121 ) { 122 const shader = theme.shaders.colorShader; 123 bindShaderProgram(shader); 124 125 setShaderProgramUniformMatrix(shader, "MVP", transforms.mvpMatrix); 126 setShaderProgramUniformVec4f(shader, "color", color); 127 128 bindVAO(geometry.vao); 129 bindIndices(geometry.indicesBuffer); 130 131 renderIndexedGeometry(geometry.pointsCount, GL_LINES); 132 } 133 134 void renderBlock(in Theme theme, in Block block, in BlockTransforms transforms, in float alpha = 1.0f) { 135 renderHorizontalChain(theme, block.topChain, transforms.topChain, Widget.PartDraws.all, alpha); 136 renderHorizontalChain(theme, block.bottomChain, transforms.bottomChain, Widget.PartDraws.all, alpha); 137 renderHorizontalChain(theme, block.middleChain, transforms.middleChain, Widget.PartDraws.all, alpha); 138 } 139 140 void renderHorizontalChain( 141 in Theme theme, 142 in StatefulChain chain, 143 in HorizontalChainTransforms transforms, 144 in Widget.PartDraws partDraws = Widget.PartDraws.all, 145 in float alpha = 1.0f 146 ) { 147 renderHorizontalChain( 148 theme, 149 chain.parts, 150 chain.texCoords[chain.state], 151 transforms, 152 partDraws, 153 alpha 154 ); 155 } 156 157 void renderHorizontalChain( 158 in Theme theme, 159 in Chain chain, 160 in HorizontalChainTransforms transforms, 161 in Widget.PartDraws partDraws = Widget.PartDraws.all, 162 in float alpha = 1.0f 163 ) { 164 renderHorizontalChain( 165 theme, 166 chain.parts, 167 chain.texCoords, 168 transforms, 169 partDraws, 170 alpha 171 ); 172 } 173 174 void renderHorizontalChain( 175 in Theme theme, 176 in TextureQuad[ChainPart] parts, 177 in Texture2DCoords[ChainPart] texCoords, 178 in HorizontalChainTransforms transforms, 179 in Widget.PartDraws partDraws = Widget.PartDraws.all, 180 in float alpha = 1.0f 181 ) { 182 if (partDraws == Widget.PartDraws.left || partDraws == Widget.PartDraws.all) { 183 renderTexAtlasQuad( 184 theme, 185 parts[ChainPart.left].geometry, 186 parts[ChainPart.left].texture, 187 texCoords[ChainPart.left], 188 transforms.quadTransforms[ChainPart.left], 189 alpha 190 ); 191 } 192 193 if (partDraws == Widget.PartDraws.right || partDraws == Widget.PartDraws.all) { 194 renderTexAtlasQuad( 195 theme, 196 parts[ChainPart.right].geometry, 197 parts[ChainPart.right].texture, 198 texCoords[ChainPart.right], 199 transforms.quadTransforms[ChainPart.right], 200 alpha 201 ); 202 } 203 204 renderTexAtlasQuad( 205 theme, 206 parts[ChainPart.center].geometry, 207 parts[ChainPart.center].texture, 208 texCoords[ChainPart.center], 209 transforms.quadTransforms[ChainPart.center], 210 alpha 211 ); 212 } 213 214 void renderVerticalChain( 215 in Theme theme, 216 in TextureQuad[ChainPart] parts, 217 in Texture2DCoords[ChainPart] texCoords, 218 in HorizontalChainTransforms transforms 219 ) { 220 renderTexAtlasQuad( 221 theme, 222 parts[ChainPart.top].geometry, 223 parts[ChainPart.top].texture, 224 texCoords[ChainPart.top], 225 transforms.quadTransforms[ChainPart.top] 226 ); 227 228 renderTexAtlasQuad( 229 theme, 230 parts[ChainPart.bottom].geometry, 231 parts[ChainPart.bottom].texture, 232 texCoords[ChainPart.bottom], 233 transforms.quadTransforms[ChainPart.bottom] 234 ); 235 236 renderTexAtlasQuad( 237 theme, 238 parts[ChainPart.middle].geometry, 239 parts[ChainPart.middle].texture, 240 texCoords[ChainPart.middle], 241 transforms.quadTransforms[ChainPart.middle] 242 ); 243 } 244 245 void renderUiText( 246 in Theme theme, 247 in StatefulUiText text, 248 in UiTextTransforms transforms 249 ) { 250 renderUiText( 251 theme, 252 text.render, 253 text.attrs[text.state], 254 transforms 255 ); 256 } 257 258 void renderUiText( 259 in Theme theme, 260 in UiTextRender text, 261 in UiTextAttributes attrs, 262 in UiTextTransforms transforms 263 ) { 264 bindShaderProgram(theme.shaders.textShader); 265 266 setShaderProgramUniformVec4f(theme.shaders.textShader, "color", attrs.color); 267 setShaderProgramUniformTexture(theme.shaders.textShader, "texture", text.texture, 0); 268 setShaderProgramUniformMatrix(theme.shaders.textShader, "MVP", transforms.mvpMatrix); 269 270 bindVAO(text.geometry.vao); 271 bindIndices(text.geometry.indicesBuffer); 272 273 renderIndexedGeometry(cast(uint) quadIndices.length, GL_TRIANGLE_STRIP); 274 }