…aaand add PREFIX to the freebsd makefile too
[voxelands-alt.git] / src / graphics / render2d.c
blobf89b800cb7e9606af5b791997ac73d56a24985ab
1 /************************************************************************
2 * render2d.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #include "graphics.h"
22 #include "list.h"
23 #include "array.h"
25 #include <string.h>
26 #include <ctype.h>
28 typedef struct obj2d_s {
29 struct obj2d_s *prev;
30 struct obj2d_s *next;
31 int type;
32 rectf_t box;
33 material_t *mat;
34 } obj2d_t;
36 static struct {
37 GLuint vao;
38 GLuint vbo;
39 shader_t *shader;
40 obj2d_t *stack;
41 obj2d_t *current;
42 } render2d_data = {
45 NULL,
46 NULL,
47 NULL
50 static obj2d_t *render2d_section_create()
52 obj2d_t *r = malloc(sizeof(obj2d_t));
53 r->type = RD2_NONE;
54 r->mat = NULL;
56 return r;
59 static void render2d_get_section(material_t *m, int t)
61 if (!render2d_data.current) {
62 if (!render2d_data.stack) {
63 render2d_data.current = render2d_section_create();
64 render2d_data.stack = list_push(&render2d_data.stack,render2d_data.current);
65 }else{
66 render2d_data.current = render2d_data.stack;
70 if (render2d_data.current->mat) {
71 if (!render2d_data.current->next) {
72 render2d_data.current = render2d_section_create();
73 render2d_data.stack = list_push(&render2d_data.stack,render2d_data.current);
74 }else{
75 render2d_data.current = render2d_data.current->next;
78 if (m)
79 render2d_data.current->mat = m;
81 render2d_data.current->type = t;
84 /* render a 2d line */
85 void render2d_line(material_t *m, float x, float y, float ex, float ey)
88 render2d_get_section(m,RD2_LINE);
90 render2d_data.current->box.x = x;
91 render2d_data.current->box.y = y;
92 render2d_data.current->box.w = ex;
93 render2d_data.current->box.h = ey;
97 /* render a 2d quad of material */
98 void render2d_quad_mat(material_t *m, float x, float y, float w, float h)
100 render2d_get_section(m,RD2_QUAD);
102 y = wm_data.size.height-y;
104 w /= (float)wm_data.size.width;
105 h /= (float)wm_data.size.height;
106 x = (((x/(float)wm_data.size.width)*2.0)-1.0)+w;
107 y = (((y/(float)wm_data.size.height)*2.0)-1.0)-h;
109 render2d_data.current->box.x = x;
110 render2d_data.current->box.y = y;
111 render2d_data.current->box.w = w;
112 render2d_data.current->box.h = h;
115 /* render text */
116 void render2d_text(float x, float y, int font, int size, char* str)
119 render2d_get_section(NULL,RD2_TEXT);
121 strcpy(render2d_data.current->txt,str);
122 render2d_vertex_push(x,y);
123 render2d_vertex_push(font,size);
127 /* render 2d graphics to the frame */
128 void render2d()
130 int s = 0;
131 matrix_t m;
133 glDisable(GL_DEPTH_TEST);
135 render2d_data.current = render2d_data.stack;
137 if (render2d_data.vao == 0) {
138 GLfloat vertices[8] = {-1.0,1.0,-1.0,-1.0,1.0,1.0,1.0,-1.0};
139 glGenVertexArrays(1,&render2d_data.vao);
140 glBindVertexArray(render2d_data.vao);
141 glGenBuffers(1, &render2d_data.vbo);
142 glBindBuffer(GL_ARRAY_BUFFER, render2d_data.vbo);
143 glBufferData(GL_ARRAY_BUFFER, 32, vertices, GL_STATIC_DRAW);
144 glEnableVertexAttribArray(0);
145 glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
148 /* shader */
149 if (!render2d_data.shader) {
150 render2d_data.shader = shader_create("ui");
151 shader_attribute(render2d_data.shader,0,"position");
154 shader_enable(render2d_data.shader);
156 glBindVertexArray(render2d_data.vao);
157 glEnableVertexAttribArray(0);
159 while (render2d_data.current && render2d_data.current->mat) {
160 mat_use(render2d_data.current->mat,render2d_data.shader);
162 matrix_init(&m);
163 matrix_scale(&m,render2d_data.current->box.w,render2d_data.current->box.h,1.0);
164 matrix_translate(&m,render2d_data.current->box.x,render2d_data.current->box.y,1.0);
165 shader_uniform_matrix(render2d_data.shader,"transformationMatrix",&m);
167 glDrawArrays(GL_TRIANGLE_STRIP,0,4);
169 render2d_data.current->mat = NULL;
170 render2d_data.current = render2d_data.current->next;
171 s++;
174 glDisableVertexAttribArray(0);
175 glBindVertexArray(0);
177 /* shader */
178 shader_disable(render2d_data.shader);
180 render2d_data.current = NULL;