From 97f1b1c735775d1e22412bbcf98ef403f9ee2275 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 16 Oct 2021 07:04:34 +0200 Subject: Add rectangle and sprite, use pixel coordinates, remote opengl dependency from test --- README.md | 3 ++- include/mgl/gl.h | 13 +++++++++++++ include/mgl/graphics/color.h | 8 ++++++++ include/mgl/graphics/rectangle.h | 17 +++++++++++++++++ include/mgl/graphics/sprite.h | 21 +++++++++++++++++++++ include/mgl/graphics/texture.h | 6 ++++-- include/mgl/graphics/vec.h | 8 ++++++++ include/mgl/mgl.h | 5 +++-- include/mgl/window.h | 2 ++ src/gl.c | 9 +++++++++ src/graphics/rectangle.c | 12 ++++++++++++ src/graphics/sprite.c | 37 +++++++++++++++++++++++++++++++++++++ src/window.c | 32 ++++++++++++++++++++++++-------- tests/main.c | 37 +++++++++++++------------------------ tests/project.conf | 3 --- 15 files changed, 173 insertions(+), 40 deletions(-) create mode 100644 include/mgl/graphics/color.h create mode 100644 include/mgl/graphics/rectangle.h create mode 100644 include/mgl/graphics/sprite.h create mode 100644 include/mgl/graphics/vec.h create mode 100644 src/graphics/rectangle.c create mode 100644 src/graphics/sprite.c delete mode 100644 tests/project.conf diff --git a/README.md b/README.md index 4fed650..612aa5b 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,5 @@ Written in C. `libglvnd (libGL.so)` ## TODO Handle window close (window destroyed event, disconnected from server and socket becomes invalid (check select return?)).\ -Bind texture and cache the bound texture to reduce calls to opengl. \ No newline at end of file +Bind texture and cache the bound texture to reduce calls to opengl. +Use gl triangle instead of quad. \ No newline at end of file diff --git a/include/mgl/gl.h b/include/mgl/gl.h index 7d9900c..823e6af 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -47,6 +47,10 @@ #define GL_CLAMP_TO_EDGE 0x812F #define GL_LINEAR 0x2601 +#define GL_QUADS 0x0007 + +#define GL_PROJECTION 0x1701 + typedef struct _XVisualInfo _XVisualInfo; typedef struct _XDisplay Display; typedef struct __GLXcontextRec *GLXContext; @@ -73,6 +77,15 @@ typedef struct { void (*glBindTexture)(unsigned int target, unsigned int texture); void (*glTexParameteri)(unsigned int target, unsigned int pname, int param); void (*glHint)(unsigned int target, unsigned int mode); + void (*glBegin)(unsigned int mode); + void (*glEnd)(void); + void (*glColor3f)(float red, float green, float blue); + void (*glVertex3f)(float x, float y, float z); + void (*glColor4f)(float red, float green, float blue, float alpha); + void (*glTexCoord2f)(float s, float t); + void (*glOrtho)(double left, double right, double bottom, double top, double near_val, double far_val); + void (*glMatrixMode)(unsigned int mode); + void (*glLoadIdentity)(void); /* Optional*/ void (*glXSwapIntervalEXT)(Display * dpy, GLXDrawable drawable, int interval); diff --git a/include/mgl/graphics/color.h b/include/mgl/graphics/color.h new file mode 100644 index 0000000..62ded72 --- /dev/null +++ b/include/mgl/graphics/color.h @@ -0,0 +1,8 @@ +#ifndef MGL_COLOR_H +#define MGL_COLOR_H + +typedef struct { + float r, g, b, a; +} mgl_color; + +#endif /* MGL_COLOR_H */ diff --git a/include/mgl/graphics/rectangle.h b/include/mgl/graphics/rectangle.h new file mode 100644 index 0000000..7c2403b --- /dev/null +++ b/include/mgl/graphics/rectangle.h @@ -0,0 +1,17 @@ +#ifndef MGL_RECTANGLE_H +#define MGL_RECTANGLE_H + +#include "color.h" +#include "vec.h" + +typedef struct mgl_context mgl_context; + +typedef struct { + mgl_color color; + mgl_vec2f position; + mgl_vec2f size; +} mgl_rectangle; + +void mgl_rectangle_draw(mgl_context *context, mgl_rectangle *rect); + +#endif /* MGL_RECTANGLE_H */ diff --git a/include/mgl/graphics/sprite.h b/include/mgl/graphics/sprite.h new file mode 100644 index 0000000..045da19 --- /dev/null +++ b/include/mgl/graphics/sprite.h @@ -0,0 +1,21 @@ +#ifndef MGL_SPRITE_H +#define MGL_SPRITE_H + +#include "color.h" +#include "vec.h" + +typedef struct mgl_context mgl_context; +typedef struct mgl_texture mgl_texture; + +typedef struct { + mgl_texture *texture; + mgl_color color; + mgl_vec2f position; + mgl_vec2f scale; +} mgl_sprite; + +void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture, float x, float y); +void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite); +void mgl_sprite_set_color(mgl_sprite *self, float r, float g, float b, float a); + +#endif /* MGL_SPRITE_H */ diff --git a/include/mgl/graphics/texture.h b/include/mgl/graphics/texture.h index 669be1e..7048c20 100644 --- a/include/mgl/graphics/texture.h +++ b/include/mgl/graphics/texture.h @@ -1,6 +1,8 @@ #ifndef MGL_TEXTURE_H #define MGL_TEXTURE_H +typedef struct mgl_texture mgl_texture; + typedef enum { MGL_TEXTURE_GRAY = 1, MGL_TEXTURE_GRAY_ALPHA = 2, @@ -8,12 +10,12 @@ typedef enum { MGL_TEXTURE_RGB_ALPHA = 4 } mgl_texture_format; -typedef struct { +struct mgl_texture { unsigned int id; int width; int height; mgl_texture_format format; -} mgl_texture; +}; int mgl_texture_load_from_file(mgl_texture *self, const char *filepath); void mgl_texture_unload(mgl_texture *self); diff --git a/include/mgl/graphics/vec.h b/include/mgl/graphics/vec.h new file mode 100644 index 0000000..562f560 --- /dev/null +++ b/include/mgl/graphics/vec.h @@ -0,0 +1,8 @@ +#ifndef MGL_VEC_H +#define MGL_VEC_H + +typedef struct { + float x, y; +} mgl_vec2f; + +#endif /* MGL_VEC_H */ diff --git a/include/mgl/mgl.h b/include/mgl/mgl.h index e906bc1..15020e9 100644 --- a/include/mgl/mgl.h +++ b/include/mgl/mgl.h @@ -5,13 +5,14 @@ /* Display* on x11 */ typedef void* mgl_connection; +typedef struct mgl_context mgl_context; -typedef struct { +struct mgl_context { mgl_connection connection; GLXContext glx_context; _XVisualInfo *visual_info; mgl_gl gl; -} mgl_context; +}; /* Safe to call multiple times, but will only be initialized the first time called. diff --git a/include/mgl/window.h b/include/mgl/window.h index 1cee698..34920a8 100644 --- a/include/mgl/window.h +++ b/include/mgl/window.h @@ -11,6 +11,8 @@ typedef struct { struct mgl_window { unsigned long window; mgl_window_callback callback; + int width; + int height; }; int mgl_window_create(mgl_window *self, const char *title, int width, int height, mgl_window_callback *callback); diff --git a/src/gl.c b/src/gl.c index fd63c81..a06f75a 100644 --- a/src/gl.c +++ b/src/gl.c @@ -46,6 +46,15 @@ int mgl_gl_load(mgl_gl *self) { { &self->glBindTexture, "glBindTexture" }, { &self->glTexParameteri, "glTexParameteri" }, { &self->glHint, "glHint" }, + { &self->glBegin, "glBegin" }, + { &self->glEnd, "glEnd" }, + { &self->glColor3f, "glColor3f" }, + { &self->glVertex3f, "glVertex3f" }, + { &self->glColor4f, "glColor4f" }, + { &self->glTexCoord2f, "glTexCoord2f" }, + { &self->glOrtho, "glOrtho" }, + { &self->glMatrixMode, "glMatrixMode" }, + { &self->glLoadIdentity, "glLoadIdentity" }, { NULL, NULL } }; diff --git a/src/graphics/rectangle.c b/src/graphics/rectangle.c new file mode 100644 index 0000000..4f2e40b --- /dev/null +++ b/src/graphics/rectangle.c @@ -0,0 +1,12 @@ +#include "../../include/mgl/graphics/rectangle.h" +#include "../../include/mgl/mgl.h" + +void mgl_rectangle_draw(mgl_context *context, mgl_rectangle *rect) { + context->gl.glColor4f(rect->color.r, rect->color.g, rect->color.b, rect->color.a); + context->gl.glBegin(GL_QUADS); + context->gl.glVertex3f(rect->position.x, rect->position.y, 0.0f); + context->gl.glVertex3f(rect->position.x + rect->size.x, rect->position.y, 0.0f); + context->gl.glVertex3f(rect->position.x + rect->size.x, rect->position.y + rect->size.y, 0.0f); + context->gl.glVertex3f(rect->position.x, rect->position.y + rect->size.y, 0.0f); + context->gl.glEnd(); +} diff --git a/src/graphics/sprite.c b/src/graphics/sprite.c new file mode 100644 index 0000000..1ec942a --- /dev/null +++ b/src/graphics/sprite.c @@ -0,0 +1,37 @@ +#include "../../include/mgl/graphics/sprite.h" +#include "../../include/mgl/graphics/texture.h" +#include "../../include/mgl/mgl.h" + +void mgl_sprite_init(mgl_sprite *self, mgl_texture *texture, float x, float y) { + self->texture = texture; + self->color = (mgl_color){ 1.0f, 1.0f, 1.0f, 1.0f }; + self->position = (mgl_vec2f){ x, y }; + self->scale = (mgl_vec2f){ 1.0f, 1.0f }; +} + +/* TODO: Cache texture bind to not bind texture if its already bound and do not bind texture 0 */ +void mgl_sprite_draw(mgl_context *context, mgl_sprite *sprite) { + context->gl.glColor4f(sprite->color.r, sprite->color.g, sprite->color.b, sprite->color.a); + context->gl.glBindTexture(GL_TEXTURE_2D, sprite->texture->id); + context->gl.glBegin(GL_QUADS); + context->gl.glTexCoord2f(0.0f, 0.0f); + context->gl.glVertex3f(sprite->position.x, sprite->position.y, 0.0f); + + context->gl.glTexCoord2f(1.0f, 0.0f); + context->gl.glVertex3f(sprite->position.x + sprite->texture->width * sprite->scale.x, sprite->position.y, 0.0f); + + context->gl.glTexCoord2f(1.0f, 1.0f); + context->gl.glVertex3f(sprite->position.x + sprite->texture->width * sprite->scale.x, sprite->position.y + sprite->texture->height * sprite->scale.y, 0.0f); + + context->gl.glTexCoord2f(0.0f, 1.0f); + context->gl.glVertex3f(sprite->position.x, sprite->position.y + sprite->texture->height * sprite->scale.y, 0.0f); + context->gl.glEnd(); + context->gl.glBindTexture(GL_TEXTURE_2D, 0); +} + +void mgl_sprite_set_color(mgl_sprite *self, float r, float g, float b, float a) { + self->color.r = r; + self->color.g = g; + self->color.b = b; + self->color.a = a; +} diff --git a/src/window.c b/src/window.c index ccfab93..818805d 100644 --- a/src/window.c +++ b/src/window.c @@ -27,6 +27,16 @@ static void set_vertical_sync_enabled(Window window, int enabled) { fprintf(stderr, "Warning: setting vertical sync failed\n"); } +static void mgl_window_on_resize(mgl_window *self, int width, int height) { + mgl_context *context = mgl_get_context(); + self->width = width; + self->height = height; + context->gl.glViewport(0, 0, self->width, self->height); + context->gl.glMatrixMode(GL_PROJECTION); + context->gl.glLoadIdentity(); + context->gl.glOrtho(0.0, width, height, 0.0, -1.0, 1.0); +} + int mgl_window_create(mgl_window *self, const char *title, int width, int height, mgl_window_callback *callback) { return mgl_window_create_with_params(self, title, width, height, DefaultRootWindow(mgl_get_context()->connection), callback); } @@ -45,7 +55,7 @@ int mgl_window_create_with_params(mgl_window *self, const char *title, int width XSetWindowAttributes window_attr; window_attr.colormap = color_map; - window_attr.event_mask = KeyPressMask; + window_attr.event_mask = KeyPressMask | StructureNotifyMask; self->window = XCreateWindow(context->connection, parent_window, 0, 0, width, height, 0, ((XVisualInfo*)context->visual_info)->depth, InputOutput, ((XVisualInfo*)context->visual_info)->visual, CWColormap | CWEventMask, &window_attr); XFreeColormap(context->connection, color_map); @@ -66,6 +76,13 @@ int mgl_window_create_with_params(mgl_window *self, const char *title, int width context->gl.glEnable(GL_TEXTURE_2D); context->gl.glEnable(GL_BLEND); context->gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + XWindowAttributes gwa; + gwa.width = 0; + gwa.height = 0; + XGetWindowAttributes(context->connection, self->window, &gwa); + + mgl_window_on_resize(self, gwa.width, gwa.height); mgl_window_draw(self); return 0; } @@ -79,7 +96,12 @@ void mgl_window_deinit(mgl_window *self) { } static void on_receive_x11_event(mgl_window *window, XEvent *xev) { - + if(xev->type == ConfigureNotify) { + if(xev->xconfigure.width != window->width || xev->xconfigure.height != window->height) { + mgl_window_on_resize(window, xev->xconfigure.width, xev->xconfigure.height); + /*fprintf(stderr, "resize!\n");*/ + } + } } void mgl_window_events_poll(mgl_window *self) { @@ -112,12 +134,6 @@ void mgl_window_events_poll(mgl_window *self) { void mgl_window_draw(mgl_window *self) { mgl_context *context = mgl_get_context(); - - /* TODO: Get window size from window resize event instead */ - XWindowAttributes gwa; - XGetWindowAttributes(context->connection, self->window, &gwa); - - context->gl.glViewport(0, 0, gwa.width, gwa.height); context->gl.glClear(GL_COLOR_BUFFER_BIT); context->gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); if(self->callback.draw) diff --git a/tests/main.c b/tests/main.c index 7a40d80..0b4c559 100644 --- a/tests/main.c +++ b/tests/main.c @@ -2,40 +2,29 @@ #include #include #include - -#include -#include +#include +#include typedef struct { mgl_texture *texture; } Userdata; static void draw(mgl_window *window, void *userdata) { + mgl_context *context = mgl_get_context(); Userdata *u = userdata; - glBegin(GL_QUADS); - glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.); - glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.); - glColor3f(0., 0., 1.); glVertex3f( .75, .75, 0.); - glColor3f(1., 1., 0.); glVertex3f(-.75, .75, 0.); - glEnd(); + mgl_rectangle rect = { + .color = { 1.0f, 0.0f, 0.0f, 1.0f }, + .position = { 0.0f, 0.0f }, + .size = { 100.0f, 500.0f } + }; - glBegin(GL_QUADS); - glColor4f(1., 0., 0., 0.5); glVertex3f(0.1 + -.75, 0.1 + -.75, 0.); - glColor4f(1., 0., 0., 0.5); glVertex3f(0.1 + .75, 0.1 + -.75, 0.); - glColor4f(1., 0., 0., 0.5); glVertex3f(0.1 + .75, 0.1 + .75, 0.); - glColor4f(1., 0., 0., 0.5); glVertex3f(0.1 + -.75, 0.1 + .75, 0.); - glEnd(); + mgl_rectangle_draw(context, &rect); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glBindTexture(GL_TEXTURE_2D, u->texture->id); - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f + 0.1f, -1.0f, 0.0f); - glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f + 0.1f, -1.0f + 0.1f, 0.0f); - glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f + 0.1f, 0.0f); - glEnd(); - glBindTexture(GL_TEXTURE_2D, 0); + mgl_sprite sprite; + mgl_sprite_init(&sprite, u->texture, 10.0f, 0.0f); + mgl_sprite_set_color(&sprite, 1.0f, 1.0f, 1.0f, 0.5f); + mgl_sprite_draw(context, &sprite); } int main(int argc, char **argv) { diff --git a/tests/project.conf b/tests/project.conf deleted file mode 100644 index 3c15235..0000000 --- a/tests/project.conf +++ /dev/null @@ -1,3 +0,0 @@ -[dependencies] -gl = ">=1" -glu = ">=9" -- cgit v1.2.3