aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gl.c15
-rw-r--r--src/graphics/vertex_buffer.c111
-rw-r--r--src/window/window.c3
3 files changed, 128 insertions, 1 deletions
diff --git a/src/gl.c b/src/gl.c
index 45280f1..615fb55 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -1,6 +1,6 @@
#include "../include/mgl/gl.h"
#include <dlfcn.h>
-#include <GL/gl.h>
+/*#include <GL/gl.h>*/
#include <stdio.h>
typedef struct {
@@ -53,7 +53,20 @@ int mgl_gl_load(mgl_gl *self) {
{ &self->glTexCoord2f, "glTexCoord2f" },
{ &self->glOrtho, "glOrtho" },
{ &self->glMatrixMode, "glMatrixMode" },
+ { &self->glPushMatrix, "glPushMatrix" },
+ { &self->glPopMatrix, "glPopMatrix" },
{ &self->glLoadIdentity, "glLoadIdentity" },
+ { &self->glTranslatef, "glTranslatef" },
+ { &self->glGenBuffers, "glGenBuffers" },
+ { &self->glBindBuffer, "glBindBuffer" },
+ { &self->glDeleteBuffers, "glDeleteBuffers" },
+ { &self->glBufferData, "glBufferData" },
+ { &self->glBufferSubData, "glBufferSubData" },
+ { &self->glDrawArrays, "glDrawArrays" },
+ { &self->glEnableClientState, "glEnableClientState" },
+ { &self->glVertexPointer, "glVertexPointer" },
+ { &self->glColorPointer, "glColorPointer" },
+ { &self->glTexCoordPointer, "glTexCoordPointer" },
{ NULL, NULL }
};
diff --git a/src/graphics/vertex_buffer.c b/src/graphics/vertex_buffer.c
new file mode 100644
index 0000000..415f574
--- /dev/null
+++ b/src/graphics/vertex_buffer.c
@@ -0,0 +1,111 @@
+#include "../../include/mgl/graphics/vertex_buffer.h"
+#include "../../include/mgl/graphics/texture.h"
+#include "../../include/mgl/mgl.h"
+
+/* TODO: Cache vertex buffer */
+/*
+ TODO: Add option to only use vertices and color or vertices and texture coordinates.
+ In such cases we should call glEnableClientState/glDisableClientState(GL_COLOR_ARRAY/GL_TEXTURE_COORD_ARRAY) and others.
+*/
+
+static unsigned int mgl_vertex_buffer_usage_to_gl_usage(mgl_vertex_buffer_usage usage) {
+ switch(usage) {
+ case MGL_USAGE_STREAM: return GL_STREAM_DRAW;
+ case MGL_USAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
+ case MGL_USAGE_STATIC: return GL_STATIC_DRAW;
+ }
+ return GL_STREAM_DRAW;
+}
+
+static unsigned int mgl_primitive_type_to_gl_mode(mgl_primitive_type primitive_type) {
+ switch(primitive_type) {
+ case MGL_PRIMITIVE_POINTS: return GL_POINTS;
+ case MGL_PRIMITIVE_LINES: return GL_LINES;
+ case MGL_PRIMITIVE_LINE_STRIP: return GL_LINE_STRIP;
+ case MGL_PRIMITIVE_TRIANGLES: return GL_TRIANGLES;
+ case MGL_PRIMITIVE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
+ case MGL_PRIMITIVE_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
+ case MGL_PRIMITIVE_QUADS: return GL_QUADS;
+ case MGL_PRIMITIVE_QUAD_STRIP: return GL_QUAD_STRIP;
+ case MGL_PRIMITIVE_POLYGON: return GL_POLYGON;
+ }
+ return MGL_PRIMITIVE_QUADS;
+}
+
+int mgl_vertex_buffer_init(mgl_vertex_buffer *self, mgl_primitive_type primitive_type, mgl_vertex_buffer_usage usage) {
+ self->id = 0;
+ self->vertex_count = 0;
+ self->primitive_type = primitive_type;
+ self->usage = usage;
+ self->position = (mgl_vec2f){ 0.0f, 0.0f };
+
+ mgl_context *context = mgl_get_context();
+ context->gl.glGenBuffers(1, &self->id);
+ if(self->id == 0)
+ return -1;
+
+ return 0;
+}
+
+void mgl_vertex_buffer_deinit(mgl_vertex_buffer *self) {
+ mgl_context *context = mgl_get_context();
+ if(self->id) {
+ context->gl.glDeleteBuffers(1, &self->id);
+ self->id = 0;
+ }
+ self->vertex_count = 0;
+ self->primitive_type = 0;
+ self->usage = 0;
+}
+
+static void mgl_vertex_buffer_set_gl_buffer_pointers(mgl_context *context) {
+ context->gl.glVertexPointer(2, GL_FLOAT, sizeof(mgl_vertex), (void*)offsetof(mgl_vertex, position));
+ context->gl.glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(mgl_vertex), (void*)offsetof(mgl_vertex, color));
+ context->gl.glTexCoordPointer(2, GL_FLOAT, sizeof(mgl_vertex), (void*)offsetof(mgl_vertex, texcoords));
+}
+
+/* TODO: Check for glBufferData error */
+static int mgl_vertex_buffer_resize(mgl_vertex_buffer *self, mgl_vertex *vertices, size_t vertex_count) {
+ mgl_context *context = mgl_get_context();
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, self->id);
+ context->gl.glBufferData(GL_ARRAY_BUFFER, sizeof(mgl_vertex) * vertex_count, vertices, mgl_vertex_buffer_usage_to_gl_usage(self->usage));
+ mgl_vertex_buffer_set_gl_buffer_pointers(context);
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
+ self->vertex_count = vertex_count;
+ return 0;
+}
+
+void mgl_vertex_buffer_set_position(mgl_vertex_buffer *self, mgl_vec2f position) {
+ self->position = position;
+}
+
+/* TODO: Check for glBufferSubData error */
+int mgl_vertex_buffer_update(mgl_vertex_buffer *self, mgl_vertex *vertices, size_t vertex_count) {
+ if(vertex_count != self->vertex_count)
+ return mgl_vertex_buffer_resize(self, vertices, vertex_count);
+
+ mgl_context *context = mgl_get_context();
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, self->id);
+ context->gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(mgl_vertex) * vertex_count, vertices);
+ mgl_vertex_buffer_set_gl_buffer_pointers(context);
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
+ return 0;
+}
+
+/* TODO: Optimize bind texture */
+void mgl_vertex_buffer_draw(mgl_context *context, mgl_vertex_buffer *self, mgl_texture *texture) {
+ if(self->vertex_count == 0 || self->id == 0)
+ return;
+
+ /* TODO: Optimize this */
+ context->gl.glPushMatrix();
+ context->gl.glTranslatef(self->position.x, self->position.y, 0.0f);
+
+ context->gl.glBindTexture(GL_TEXTURE_2D, texture ? texture->id : 0);
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, self->id);
+ context->gl.glDrawArrays(mgl_primitive_type_to_gl_mode(self->primitive_type), 0, self->vertex_count);
+ context->gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
+ context->gl.glBindTexture(GL_TEXTURE_2D, 0);
+
+ context->gl.glPopMatrix();
+}
diff --git a/src/window/window.c b/src/window/window.c
index 80c3ccf..691a647 100644
--- a/src/window/window.c
+++ b/src/window/window.c
@@ -84,6 +84,9 @@ 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);
+ context->gl.glEnableClientState(GL_VERTEX_ARRAY);
+ context->gl.glEnableClientState(GL_COLOR_ARRAY);
+ context->gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
XWindowAttributes gwa;
gwa.width = 0;