stuffs
This commit is contained in:
		
							parent
							
								
									a636ae5932
								
							
						
					
					
						commit
						57efb162d6
					
				
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3
									
								
								dub.json
								
								
								
								
							
							
						
						
									
										3
									
								
								dub.json
								
								
								
								
							| 
						 | 
				
			
			@ -4,7 +4,8 @@
 | 
			
		|||
		"profan"
 | 
			
		||||
	],
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
		"derelict-sdl2": "~>3.1.0-alpha.4"
 | 
			
		||||
		"derelict-sdl2": "~>3.1.0-alpha.4",
 | 
			
		||||
		"derelict-imgui": "~>0.10.0"
 | 
			
		||||
	},
 | 
			
		||||
	"description": "A minimal D application.",
 | 
			
		||||
	"copyright": "Copyright © 2018, profan",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
	"fileVersion": 1,
 | 
			
		||||
	"versions": {
 | 
			
		||||
		"derelict-gl3": "2.0.0-beta.6",
 | 
			
		||||
		"derelict-imgui": "0.10.0",
 | 
			
		||||
		"derelict-sdl2": "3.1.0-alpha.4",
 | 
			
		||||
		"derelict-util": "3.0.0-beta.2"
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										72
									
								
								source/app.d
								
								
								
								
							
							
						
						
									
										72
									
								
								source/app.d
								
								
								
								
							| 
						 | 
				
			
			@ -1,7 +1,11 @@
 | 
			
		|||
import std.stdio;
 | 
			
		||||
import derelict.sdl2.sdl;
 | 
			
		||||
import derelict.imgui.imgui;
 | 
			
		||||
import glad.gl.all;
 | 
			
		||||
 | 
			
		||||
import window;
 | 
			
		||||
import imgui;
 | 
			
		||||
 | 
			
		||||
string doCapture(string sym, uint start, uint end)(){
 | 
			
		||||
 | 
			
		||||
	import std.string : format;
 | 
			
		||||
| 
						 | 
				
			
			@ -426,6 +430,10 @@ struct Chip8 {
 | 
			
		|||
 | 
			
		||||
	} // step
 | 
			
		||||
 | 
			
		||||
	void handle_event(ref SDL_Event ev) {
 | 
			
		||||
 | 
			
		||||
	} // handle_event
 | 
			
		||||
 | 
			
		||||
	void tick() {
 | 
			
		||||
 | 
			
		||||
		if (run_flag) {
 | 
			
		||||
| 
						 | 
				
			
			@ -448,49 +456,12 @@ struct Chip8 {
 | 
			
		|||
 | 
			
		||||
} // Emulator
 | 
			
		||||
 | 
			
		||||
struct Window {
 | 
			
		||||
 | 
			
		||||
	import core.stdc.stdio;
 | 
			
		||||
	import core.stdc.stdlib;
 | 
			
		||||
 | 
			
		||||
	SDL_Window* window;
 | 
			
		||||
	SDL_GLContext context;
 | 
			
		||||
 | 
			
		||||
	void create_window(int w, int h, const char* title = "Chipd8 Emu") {
 | 
			
		||||
		assert(w > 0, "window width must be > 0");
 | 
			
		||||
		assert(h > 0, "window height must be > 0");
 | 
			
		||||
 | 
			
		||||
		// minimum OpenGL 3.3
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
 | 
			
		||||
 | 
			
		||||
		SDL_Window* new_win = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL);
 | 
			
		||||
		if (new_win == null) {
 | 
			
		||||
			printf("SDL2 - Window could not be created: %s\n", SDL_GetError());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		SDL_GLContext new_con = SDL_GL_CreateContext(new_win);
 | 
			
		||||
		if (new_con == null) {
 | 
			
		||||
			printf("SDL2 - failed creating OpenGL 3.3 context: %s\n", SDL_GetError());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// assign em yes
 | 
			
		||||
		window = new_win;
 | 
			
		||||
		context = new_con;
 | 
			
		||||
 | 
			
		||||
		atexit(SDL_Quit);
 | 
			
		||||
 | 
			
		||||
	} // create_window
 | 
			
		||||
 | 
			
		||||
} // Window
 | 
			
		||||
 | 
			
		||||
void load_libs() {
 | 
			
		||||
 | 
			
		||||
	import glad.gl.loader;
 | 
			
		||||
 | 
			
		||||
	DerelictSDL2.load();
 | 
			
		||||
	DerelictImgui.load();
 | 
			
		||||
	auto status = gladLoadGL();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -534,28 +505,10 @@ struct Emulator {
 | 
			
		|||
 | 
			
		||||
		SDL_Event event;
 | 
			
		||||
		while (SDL_PollEvent(&event)) {
 | 
			
		||||
 | 
			
		||||
			chip8.handle_event(event);
 | 
			
		||||
 | 
			
		||||
			switch (event.type) with (SDL_EventType) {
 | 
			
		||||
				case SDL_TEXTINPUT: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_TEXTEDITING: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_MOUSEBUTTONDOWN: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_MOUSEBUTTONUP: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_MOUSEWHEEL: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_KEYDOWN: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_KEYUP: {
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case SDL_QUIT: {
 | 
			
		||||
					running = false;
 | 
			
		||||
					break;
 | 
			
		||||
| 
						 | 
				
			
			@ -564,6 +517,7 @@ struct Emulator {
 | 
			
		|||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} // handle_events
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,278 @@
 | 
			
		|||
module imgui;
 | 
			
		||||
 | 
			
		||||
import glad.gl.all;
 | 
			
		||||
import derelict.sdl2.sdl;
 | 
			
		||||
import derelict.imgui.imgui;
 | 
			
		||||
 | 
			
		||||
import window;
 | 
			
		||||
 | 
			
		||||
import std.traits : isDelegate, ReturnType, ParameterTypeTuple;
 | 
			
		||||
auto bindDelegate(T, string file = __FILE__, size_t line = __LINE__)(T t) if(isDelegate!T) {
 | 
			
		||||
 | 
			
		||||
    static T dg;
 | 
			
		||||
    dg = t;
 | 
			
		||||
    
 | 
			
		||||
    extern(C) static ReturnType!T func(ParameterTypeTuple!T args) {
 | 
			
		||||
        return dg(args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return &func;
 | 
			
		||||
 | 
			
		||||
} // bindDelegate (thanks Destructionator)
 | 
			
		||||
 | 
			
		||||
struct Imgui {
 | 
			
		||||
 | 
			
		||||
    // OpenGL data, cleanup soon
 | 
			
		||||
    GLuint       g_FontTexture = 0;
 | 
			
		||||
    int          g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
 | 
			
		||||
    int          g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
 | 
			
		||||
    int          g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
 | 
			
		||||
    uint         g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0;
 | 
			
		||||
 | 
			
		||||
    void initialize() {
 | 
			
		||||
 | 
			
		||||
        auto io = igGetIO();
 | 
			
		||||
        io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
 | 
			
		||||
        io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
 | 
			
		||||
        io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
 | 
			
		||||
        io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
 | 
			
		||||
        io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
 | 
			
		||||
        io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
 | 
			
		||||
        io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
 | 
			
		||||
        io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
 | 
			
		||||
        io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
 | 
			
		||||
        io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
 | 
			
		||||
        io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
 | 
			
		||||
        io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
 | 
			
		||||
        io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
 | 
			
		||||
 | 
			
		||||
        io.RenderDrawListsFn = bindDelegate(&render_draw_lists);
 | 
			
		||||
        io.SetClipboardTextFn = bindDelegate(&set_clipboard_text);
 | 
			
		||||
        io.GetClipboardTextFn = bindDelegate(&get_clipboard_text);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void create_font_texture() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void create_device_objects() {
 | 
			
		||||
 | 
			
		||||
        // backup GL state
 | 
			
		||||
        GLint last_texture, last_array_buffer, last_vertex_array;
 | 
			
		||||
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
 | 
			
		||||
        glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
 | 
			
		||||
        glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
 | 
			
		||||
 | 
			
		||||
        const GLchar *vertex_shader = q{
 | 
			
		||||
            #version 330
 | 
			
		||||
            uniform mat4 ProjMtx;
 | 
			
		||||
            in vec2 Position;
 | 
			
		||||
            in vec2 UV;
 | 
			
		||||
            in vec4 Color;
 | 
			
		||||
            out vec2 Frag_UV;
 | 
			
		||||
            out vec4 Frag_Color;
 | 
			
		||||
            void main() {
 | 
			
		||||
               Frag_UV = UV;
 | 
			
		||||
               Frag_Color = Color;
 | 
			
		||||
               gl_Position = ProjMtx * vec4(Position.xy,0,1);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const GLchar* fragment_shader = q{
 | 
			
		||||
            #version 330
 | 
			
		||||
            uniform sampler2D Texture;
 | 
			
		||||
            in vec2 Frag_UV;
 | 
			
		||||
            in vec4 Frag_Color;
 | 
			
		||||
            out vec4 Out_Color;
 | 
			
		||||
            void main() {
 | 
			
		||||
               Out_Color = Frag_Color * texture( Texture, Frag_UV.st);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        g_ShaderHandle = glCreateProgram();
 | 
			
		||||
        g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
 | 
			
		||||
        g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
 | 
			
		||||
        glShaderSource(g_VertHandle, 1, &vertex_shader, null);
 | 
			
		||||
        glShaderSource(g_FragHandle, 1, &fragment_shader, null);
 | 
			
		||||
        glCompileShader(g_VertHandle);
 | 
			
		||||
        glCompileShader(g_FragHandle);
 | 
			
		||||
        glAttachShader(g_ShaderHandle, g_VertHandle);
 | 
			
		||||
        glAttachShader(g_ShaderHandle, g_FragHandle);
 | 
			
		||||
        glLinkProgram(g_ShaderHandle);
 | 
			
		||||
 | 
			
		||||
        g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
 | 
			
		||||
        g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
 | 
			
		||||
        g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
 | 
			
		||||
        g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
 | 
			
		||||
        g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
 | 
			
		||||
 | 
			
		||||
        glGenBuffers(1, &g_VboHandle);
 | 
			
		||||
        glGenBuffers(1, &g_ElementsHandle);
 | 
			
		||||
 | 
			
		||||
        glGenVertexArrays(1, &g_VaoHandle);
 | 
			
		||||
        glBindVertexArray(g_VaoHandle);
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
 | 
			
		||||
        glEnableVertexAttribArray(g_AttribLocationPosition);
 | 
			
		||||
        glEnableVertexAttribArray(g_AttribLocationUV);
 | 
			
		||||
        glEnableVertexAttribArray(g_AttribLocationColor);
 | 
			
		||||
 | 
			
		||||
        glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.pos.offsetof);
 | 
			
		||||
        glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(void*)ImDrawVert.uv.offsetof);
 | 
			
		||||
        glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(void*)ImDrawVert.col.offsetof);
 | 
			
		||||
 | 
			
		||||
        create_font_texture();
 | 
			
		||||
 | 
			
		||||
        // restore modified GL state
 | 
			
		||||
        glBindTexture(GL_TEXTURE_2D, last_texture);
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
 | 
			
		||||
        glBindVertexArray(last_vertex_array);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern(C) nothrow
 | 
			
		||||
    void render_draw_lists(ImDrawData* draw_data) {
 | 
			
		||||
        
 | 
			
		||||
        // avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
 | 
			
		||||
        auto io = igGetIO();
 | 
			
		||||
        int fb_width = cast(int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
 | 
			
		||||
        int fb_height = cast(int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
 | 
			
		||||
        if (fb_width == 0 || fb_height == 0) { return; }
 | 
			
		||||
        draw_data.ScaleClipRects(io.DisplayFramebufferScale);
 | 
			
		||||
 | 
			
		||||
        // backup GL state
 | 
			
		||||
        GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, cast(GLint*)&last_active_texture);
 | 
			
		||||
        glActiveTexture(GL_TEXTURE0);
 | 
			
		||||
        GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
 | 
			
		||||
        GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
 | 
			
		||||
        GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
 | 
			
		||||
        GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer);
 | 
			
		||||
        GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
 | 
			
		||||
        GLint[4] last_viewport; glGetIntegerv(GL_VIEWPORT, last_viewport.ptr);
 | 
			
		||||
        GLint[4] last_scissor_box; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr);
 | 
			
		||||
        GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, cast(GLint*)&last_blend_src_rgb);
 | 
			
		||||
        GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, cast(GLint*)&last_blend_dst_rgb);
 | 
			
		||||
        GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, cast(GLint*)&last_blend_src_alpha);
 | 
			
		||||
        GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, cast(GLint*)&last_blend_dst_alpha);
 | 
			
		||||
        GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, cast(GLint*)&last_blend_equation_rgb);
 | 
			
		||||
        GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, cast(GLint*)&last_blend_equation_alpha);
 | 
			
		||||
        GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
 | 
			
		||||
        GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
 | 
			
		||||
        GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
 | 
			
		||||
        GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
 | 
			
		||||
 | 
			
		||||
        // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
 | 
			
		||||
        glEnable(GL_BLEND);
 | 
			
		||||
        glBlendEquation(GL_FUNC_ADD);
 | 
			
		||||
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
        glDisable(GL_CULL_FACE);
 | 
			
		||||
        glDisable(GL_DEPTH_TEST);
 | 
			
		||||
        glEnable(GL_SCISSOR_TEST);
 | 
			
		||||
 | 
			
		||||
        // Setup viewport, orthographic projection matrix
 | 
			
		||||
        glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height);
 | 
			
		||||
        const float[4][4] ortho_projection = [
 | 
			
		||||
            [ 2.0f/io.DisplaySize.x, 0.0f,                   0.0f, 0.0f ],
 | 
			
		||||
            [ 0.0f,                  2.0f/-io.DisplaySize.y, 0.0f, 0.0f ],
 | 
			
		||||
            [ 0.0f,                  0.0f,                  -1.0f, 0.0f ],
 | 
			
		||||
            [-1.0f,                  1.0f,                   0.0f, 1.0f ],
 | 
			
		||||
        ];
 | 
			
		||||
        glUseProgram(g_ShaderHandle);
 | 
			
		||||
        glUniform1i(g_AttribLocationTex, 0);
 | 
			
		||||
        glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
 | 
			
		||||
        glBindVertexArray(g_VaoHandle);
 | 
			
		||||
 | 
			
		||||
        foreach (int n; 0 .. draw_data.CmdListsCount) {
 | 
			
		||||
            ImDrawList* cmd_list = draw_data.CmdLists[n];
 | 
			
		||||
            ImDrawIdx* idx_buffer_offset;
 | 
			
		||||
 | 
			
		||||
            auto countVertices = ImDrawList_GetVertexBufferSize(cmd_list);
 | 
			
		||||
            auto countIndices = ImDrawList_GetIndexBufferSize(cmd_list);
 | 
			
		||||
 | 
			
		||||
            glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
 | 
			
		||||
            glBufferData(GL_ARRAY_BUFFER, countVertices * ImDrawVert.sizeof, cast(GLvoid*)ImDrawList_GetVertexPtr(cmd_list,0), GL_STREAM_DRAW);
 | 
			
		||||
 | 
			
		||||
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
 | 
			
		||||
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, countIndices * ImDrawIdx.sizeof, cast(GLvoid*)ImDrawList_GetIndexPtr(cmd_list,0), GL_STREAM_DRAW);
 | 
			
		||||
 | 
			
		||||
            auto cmdCnt = ImDrawList_GetCmdSize(cmd_list);
 | 
			
		||||
 | 
			
		||||
            foreach(int cmd_i; 0 .. cmdCnt) {
 | 
			
		||||
                auto pcmd = ImDrawList_GetCmdPtr(cmd_list, cmd_i);
 | 
			
		||||
 | 
			
		||||
                if (pcmd.UserCallback)             {
 | 
			
		||||
                    pcmd.UserCallback(cmd_list, pcmd);
 | 
			
		||||
                } else {
 | 
			
		||||
                    glBindTexture(GL_TEXTURE_2D, cast(GLuint)pcmd.TextureId);
 | 
			
		||||
                    glScissor(cast(int)pcmd.ClipRect.x, cast(int)(fb_height - pcmd.ClipRect.w), cast(int)(pcmd.ClipRect.z - pcmd.ClipRect.x), cast(int)(pcmd.ClipRect.w - pcmd.ClipRect.y));
 | 
			
		||||
                    glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
 | 
			
		||||
                }
 | 
			
		||||
                idx_buffer_offset += pcmd.ElemCount;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Restore modified GL state
 | 
			
		||||
        glUseProgram(last_program);
 | 
			
		||||
        glBindTexture(GL_TEXTURE_2D, last_texture);
 | 
			
		||||
        glActiveTexture(last_active_texture);
 | 
			
		||||
        glBindVertexArray(last_vertex_array);
 | 
			
		||||
        glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
 | 
			
		||||
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer);
 | 
			
		||||
        glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
 | 
			
		||||
        glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
 | 
			
		||||
        if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
 | 
			
		||||
        if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
 | 
			
		||||
        if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
 | 
			
		||||
        if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
 | 
			
		||||
        glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]);
 | 
			
		||||
        glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern(C) nothrow 
 | 
			
		||||
    const(char)* get_clipboard_text(void* user_data) {
 | 
			
		||||
        return SDL_GetClipboardText();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    extern(C) nothrow
 | 
			
		||||
    void set_clipboard_text(void* user_data, const (char)* text) {
 | 
			
		||||
        SDL_SetClipboardText(text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void new_frame(ref Window win) {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void handle_event(ref SDL_Event ev) {
 | 
			
		||||
        
 | 
			
		||||
        switch (ev.type) with (SDL_EventType) {
 | 
			
		||||
 | 
			
		||||
            case SDL_TEXTINPUT:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_MOUSEBUTTONUP:
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_MOUSEWHEEL:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case SDL_KEYDOWN:
 | 
			
		||||
                break;
 | 
			
		||||
            case SDL_KEYUP:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
module window;
 | 
			
		||||
 | 
			
		||||
import derelict.sdl2.sdl;
 | 
			
		||||
import glad.gl.all;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Converts an integer representing a colour, for example 0x428bca into a 4 element
 | 
			
		||||
 * int array for passing to OpenGL.
 | 
			
		||||
*/
 | 
			
		||||
GLfloat[4] to(T : GLfloat[4])(int color, ubyte alpha = 255) nothrow @nogc pure {
 | 
			
		||||
 | 
			
		||||
	GLfloat[4] gl_color = [ //mask out r, g, b components from int
 | 
			
		||||
		cast(float)cast(ubyte)(color>>16)/255,
 | 
			
		||||
		cast(float)cast(ubyte)(color>>8)/255,
 | 
			
		||||
		cast(float)cast(ubyte)(color)/255,
 | 
			
		||||
		cast(float)cast(ubyte)(alpha)/255
 | 
			
		||||
	];
 | 
			
		||||
 | 
			
		||||
	return gl_color;
 | 
			
		||||
 | 
			
		||||
} // to!GLfloat[4]
 | 
			
		||||
 | 
			
		||||
struct Window {
 | 
			
		||||
 | 
			
		||||
	import core.stdc.stdio;
 | 
			
		||||
	import core.stdc.stdlib;
 | 
			
		||||
 | 
			
		||||
	SDL_Window* window;
 | 
			
		||||
	SDL_GLContext context;
 | 
			
		||||
 | 
			
		||||
	void create_window(int w, int h, const char* title = "Chipd8 Emu") {
 | 
			
		||||
		assert(w > 0, "window width must be > 0");
 | 
			
		||||
		assert(h > 0, "window height must be > 0");
 | 
			
		||||
 | 
			
		||||
		// minimum OpenGL 3.3
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 | 
			
		||||
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
 | 
			
		||||
 | 
			
		||||
		SDL_Window* new_win = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_OPENGL);
 | 
			
		||||
		if (new_win == null) {
 | 
			
		||||
			printf("SDL2 - Window could not be created: %s\n", SDL_GetError());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		SDL_GLContext new_con = SDL_GL_CreateContext(new_win);
 | 
			
		||||
		if (new_con == null) {
 | 
			
		||||
			printf("SDL2 - failed creating OpenGL 3.3 context: %s\n", SDL_GetError());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// assign em yes
 | 
			
		||||
		window = new_win;
 | 
			
		||||
		context = new_con;
 | 
			
		||||
 | 
			
		||||
		atexit(SDL_Quit);
 | 
			
		||||
 | 
			
		||||
	} // create_window
 | 
			
		||||
 | 
			
		||||
    void handle_event(ref SDL_Event ev) {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void render_clear(int colour) {
 | 
			
		||||
 | 
			
		||||
        auto col = to!GLColor(color, 255);
 | 
			
		||||
		glClearColor(col[0], col[1], col[2], col[3]);
 | 
			
		||||
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void render_present() {
 | 
			
		||||
 | 
			
		||||
        SDL_GL_SwapWindow(window);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	@property nothrow @nogc {
 | 
			
		||||
 | 
			
		||||
		int[2] window_size() {
 | 
			
		||||
			int w, h;
 | 
			
		||||
			SDL_GetWindowSize(window, &w, &h);
 | 
			
		||||
			return [w, h];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int[2] framebuffer_size() {
 | 
			
		||||
			int w, h;
 | 
			
		||||
			SDL_GL_GetDrawableSize(window, &w, &h);
 | 
			
		||||
			return [w, h];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
} // Window
 | 
			
		||||
		Loading…
	
		Reference in New Issue