1 module main; 2 3 import std.stdio; 4 import std.path; 5 import std.file; 6 import core.memory; 7 8 import rpui.application; 9 import rpui.events; 10 import rpui.view; 11 import rpui.view_component; 12 import rpui.widget; 13 import rpui.widgets.button.widget; 14 import rpui.widgets.panel.widget; 15 import rpui.widgets.dialog.widget; 16 import rpui.widgets.canvas.widget; 17 18 import gapi.vec; 19 import gapi.camera; 20 import gapi.geometry; 21 import gapi.geometry_quad; 22 import gapi.shader; 23 import gapi.texture; 24 import gapi.transform; 25 import gapi.shader_uniform; 26 import gapi.opengl; 27 28 void main() { 29 auto app = new TestApplication(); 30 app.run(); 31 } 32 33 final class TestApplication : Application { 34 private View rootView; 35 36 override void onProgress(in ProgressEvent event) { 37 rootView.onProgress(event); 38 } 39 40 override void onRender() { 41 rootView.onRender(); 42 } 43 44 override void onCreate() { 45 auto viewResources = createViewResources("light"); 46 viewResources.strings.setLocale("en"); 47 viewResources.strings.addStrings("test_view.rdl"); 48 49 rootView = new View(windowData.window, "light", cursorManager, viewResources); 50 events.join(rootView.events); 51 events.subscribe(rootView); 52 53 ViewComponent.createFromFileWithShortcuts!(MyViewComponent)(rootView, "test.rdl"); 54 } 55 } 56 57 final class MyViewComponent : ViewComponent { 58 @bindWidget Button okButton; 59 @bindWidget Panel testPanel; 60 @bindWidget("cancelButton") Button myButton; 61 @bindWidget Dialog testDialog; 62 @bindGroupWidgets Button[3] buttons; 63 @bindWidget Canvas openglCanvas; 64 65 int a = 0; 66 67 this(View view, in string laytoutFileName, in string shortcutsFileName) { 68 super(view, laytoutFileName, shortcutsFileName); 69 } 70 71 override void onCreate() { 72 okButton.events.subscribe!KeyPressedEvent(delegate(in event) { 73 writeln("Handle OkButton Key Pressed Event", event.key); 74 }); 75 76 openglCanvas.canvasRenderer = new OpenGLRenderer(); 77 } 78 79 @onClickListener("okButton") 80 void onOkButtonClick() { 81 writeln("Hello world! a = ", a); 82 a += 1; 83 } 84 85 @onClickListener("okButton") 86 void onOkButtonClick2() { 87 okButton.caption = "YAY!"; 88 myButton.caption = "WORKS!"; 89 buttons[2].caption = "YES!"; 90 } 91 92 @shortcut("TestGroup.cancel") 93 void someShortcutAction() { 94 writeln("Wow! shortcut was executed!"); 95 } 96 97 @onClickListener("closeButton") 98 @onClickListener("cancelButton") 99 void onCancelButtonClick() { 100 writeln("Close!"); 101 } 102 103 @onClickListener("testMenuItem") 104 @onClickListener("testMenuItem2") 105 @onClickListener("openDialogButton") 106 void onOpenDialogButtonClick() { 107 testDialog.open(); 108 } 109 110 @onClickListener("closeDialogButton") 111 void onCloseDialogButtonClick() { 112 testDialog.close(); 113 } 114 } 115 116 final class OpenGLRenderer : CanvasRenderer { 117 struct Geometry { 118 Buffer indicesBuffer; 119 Buffer verticesBuffer; 120 Buffer texCoordsBuffer; 121 122 VAO vao; 123 } 124 125 private Geometry sprite; 126 private Texture2D spriteTexture; 127 private ShaderProgram transformShader; 128 private Transform2D spriteTransform; 129 private mat4 spriteModelMatrix; 130 private mat4 spriteMVPMatrix; 131 private Widget widget; 132 133 override void onCreate(Widget widget) { 134 createSprite(); 135 createTexture(); 136 createShaders(); 137 138 this.widget = widget; 139 } 140 141 override void onDestroy() { 142 deleteBuffer(sprite.indicesBuffer); 143 deleteBuffer(sprite.verticesBuffer); 144 deleteBuffer(sprite.texCoordsBuffer); 145 deleteTexture2D(spriteTexture); 146 deleteShaderProgram(transformShader); 147 } 148 149 private void createSprite() { 150 sprite.indicesBuffer = createIndicesBuffer(quadIndices); 151 sprite.verticesBuffer = createVector2fBuffer(centeredQuadVertices); 152 sprite.texCoordsBuffer = createVector2fBuffer(quadTexCoords); 153 154 sprite.vao = createVAO(); 155 bindVAO(sprite.vao); 156 createVector2fVAO(sprite.verticesBuffer, inAttrPosition); 157 createVector2fVAO(sprite.texCoordsBuffer, inAttrTextCoords); 158 } 159 160 private void createTexture() { 161 const Texture2DParameters params = { 162 minFilter: true, 163 magFilter: true 164 }; 165 spriteTexture = createTexture2DFromFile(buildPath("res", "test.jpg"), params); 166 } 167 168 private void createShaders() { 169 const vertexSource = readText(buildPath("res", "shaders", "transform_vertex.glsl")); 170 const vertexShader = createShader("transform vertex shader", ShaderType.vertex, vertexSource); 171 172 const fragmentSource = readText(buildPath("res", "shaders", "texture_fragment.glsl")); 173 const fragmentShader = createShader("transform fragment shader", ShaderType.fragment, fragmentSource); 174 175 transformShader = createShaderProgram("transform program", [vertexShader, fragmentShader]); 176 } 177 178 override void onRender() { 179 bindShaderProgram(transformShader); 180 setShaderProgramUniformMatrix(transformShader, "MVP", spriteMVPMatrix); 181 setShaderProgramUniformTexture(transformShader, "texture", spriteTexture, 0); 182 183 bindVAO(sprite.vao); 184 bindIndices(sprite.indicesBuffer); 185 renderIndexedGeometry(cast(uint) quadIndices.length, GL_TRIANGLE_STRIP); 186 } 187 188 override void onProgress(in ProgressEvent event) { 189 assert(widget !is null); 190 assert(widget.view !is null); 191 192 const screenCameraView = widget.view.cameraView; 193 spriteTransform.position = vec2( 194 screenCameraView.viewportWidth / 2, 195 screenCameraView.viewportHeight / 2 196 ); 197 spriteTransform.scaling = vec2(430.0f, 600.0f); 198 spriteTransform.rotation += 0.025f * event.deltaTime; 199 200 spriteModelMatrix = create2DModelMatrix(spriteTransform); 201 spriteMVPMatrix = screenCameraView.mvpMatrix * spriteModelMatrix; 202 } 203 }