diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-11-03 16:53:03 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-11-03 20:34:22 +0100 |
commit | f26a606bf50f7dbe35c79bfa52f2026bd7af3eb8 (patch) | |
tree | 1c0a35e3cea48ffe989a366b685da65d274ff0af | |
parent | def772cc0efd7c22c6154c6d9f73df1a08fa2671 (diff) |
Add viewport
-rw-r--r-- | include/mgl/graphics/vertex.h | 4 | ||||
-rw-r--r-- | include/mgl/window/window.h | 14 | ||||
-rw-r--r-- | src/window/window.c | 20 | ||||
-rw-r--r-- | tests/main.c | 27 |
4 files changed, 53 insertions, 12 deletions
diff --git a/include/mgl/graphics/vertex.h b/include/mgl/graphics/vertex.h index e4fef34..8cc2f25 100644 --- a/include/mgl/graphics/vertex.h +++ b/include/mgl/graphics/vertex.h @@ -14,6 +14,10 @@ typedef struct { mgl_color color; } mgl_vertex; +/* + Note: this sends the vertices to the gpu everytime this is called. This should only be used for small lists of vertices + or if every vertex needs to change every frame. Use mgl_vertex_buffer instead if possible. +*/ void mgl_vertices_draw(mgl_context *context, const mgl_vertex *vertices, size_t vertex_count, mgl_primitive_type primitive_type); #endif /* MGL_VERTEX_H */ diff --git a/include/mgl/window/window.h b/include/mgl/window/window.h index 297ccb9..8e3f626 100644 --- a/include/mgl/window/window.h +++ b/include/mgl/window/window.h @@ -14,12 +14,18 @@ typedef unsigned long mgl_window_handle; typedef struct mgl_window mgl_window; +typedef struct { + mgl_vec2i position; + mgl_vec2i size; +} mgl_view; + struct mgl_window { mgl_window_handle window; GLXContext glx_context; mgl_vec2i size; /* relative to the top left of the window. only updates when the cursor is inside the window */ mgl_vec2i cursor_position; + mgl_view view; }; int mgl_window_create(mgl_window *self, const char *title, int width, int height); @@ -32,4 +38,12 @@ void mgl_window_clear(mgl_window *self, mgl_color color); bool mgl_window_poll_event(mgl_window *self, mgl_event *event); void mgl_window_display(mgl_window *self); +/* + The previous view is returned in |prev_view|. |prev_view| may be NULL. + This should be called every frame to retain the view. + Make sure to set the view back to |prev_view| after rendering items + inside the view. +*/ +void mgl_window_set_view(mgl_window *self, mgl_view *new_view, mgl_view *prev_view); + #endif /* MGL_WINDOW_H */ diff --git a/src/window/window.c b/src/window/window.c index 9a650ae..44e0a23 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -32,10 +32,11 @@ static void mgl_window_on_resize(mgl_window *self, int width, int height) { mgl_context *context = mgl_get_context(); self->size.x = width; self->size.y = height; - context->gl.glViewport(0, 0, self->size.x, self->size.y); - context->gl.glMatrixMode(GL_PROJECTION); - context->gl.glLoadIdentity(); - context->gl.glOrtho(0.0, width, height, 0.0, -1.0, 1.0); + + mgl_view view; + view.position = (mgl_vec2i){ 0, 0 }; + view.size = self->size; + mgl_window_set_view(self, &view, NULL); } int mgl_window_create(mgl_window *self, const char *title, int width, int height) { @@ -288,3 +289,14 @@ void mgl_window_display(mgl_window *self) { context->gl.glXSwapBuffers(context->connection, self->window); } +void mgl_window_set_view(mgl_window *self, mgl_view *new_view, mgl_view *prev_view) { + if(prev_view) + *prev_view = self->view; + + mgl_context *context = mgl_get_context(); + self->view = *new_view; + context->gl.glViewport(new_view->position.x, self->size.y - new_view->size.y - new_view->position.y, new_view->size.x, new_view->size.y); + context->gl.glMatrixMode(GL_PROJECTION); + context->gl.glLoadIdentity(); + context->gl.glOrtho(0.0, new_view->size.x, new_view->size.y, 0.0, 0.0, 1.0); +} diff --git a/tests/main.c b/tests/main.c index 6a69866..99a8398 100644 --- a/tests/main.c +++ b/tests/main.c @@ -55,30 +55,41 @@ static void draw(mgl_window *window, void *userdata) { mgl_vertex_buffer_set_position(u->vertex_buffer2, (mgl_vec2f){ window->cursor_position.x, window->cursor_position.y + 500 }); mgl_vertex_buffer_draw(context, u->vertex_buffer2, &u->font->texture); + mgl_vec2i view_size = { + .x = 200, + .y = 200 + }; + + mgl_view prev_view; + mgl_view new_view = { + .position = { window->size.x/2 - view_size.x/2, window->size.y/2 - view_size.y/2 }, + .size = view_size + }; + mgl_window_set_view(window, &new_view, &prev_view); mgl_vertex vertices[4] = { (mgl_vertex){ - .position = {window->cursor_position.x, 0.0f}, + .position = {-new_view.position.x + window->cursor_position.x, -new_view.position.y + window->cursor_position.y}, .texcoords = {0.0f, 0.0f}, - .color = {0, 255, 0, 255} + .color = {255, 0, 0, 255} }, (mgl_vertex){ - .position = {window->cursor_position.x + 100.0f, 0.0f}, + .position = {-new_view.position.x + window->cursor_position.x + 400.0f, -new_view.position.y + window->cursor_position.y}, .texcoords = {0.0f, 0.0f}, .color = {0, 255, 0, 255}, }, (mgl_vertex){ - .position = {window->cursor_position.x + 100.0f, 100.0f}, + .position = {-new_view.position.x + window->cursor_position.x + 400.0f, -new_view.position.y + window->cursor_position.y + 400.0f}, .texcoords = {0.0f, 0.0f}, - .color = {0, 255, 0, 255}, + .color = {0, 0, 255, 255}, }, (mgl_vertex){ - .position = {window->cursor_position.x, 100.0f}, + .position = {-new_view.position.x + window->cursor_position.x, -new_view.position.y + window->cursor_position.y + 400.0f}, .texcoords = {0.0f, 0.0f}, - .color = {0, 255, 0, 255} + .color = {255, 255, 0, 255} } }; - mgl_vertices_draw(context, vertices, 4, MGL_PRIMITIVE_QUADS); + mgl_window_set_view(window, &prev_view, NULL); } int main(int argc, char **argv) { |