1 /************************************************************************
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 ************************************************************************/
28 typedef struct obj2d_s
{
52 static obj2d_t
*render2d_section_create()
54 obj2d_t
*r
= malloc(sizeof(obj2d_t
));
59 textbuffer_init(&r
->txt
,NULL
,0,0,0,0,0,0,0);
64 static void render2d_get_section(material_t
*m
, int t
)
66 if (!render2d_data
.current
) {
67 if (!render2d_data
.stack
) {
68 render2d_data
.current
= render2d_section_create();
69 render2d_data
.stack
= list_push(&render2d_data
.stack
,render2d_data
.current
);
71 render2d_data
.current
= render2d_data
.stack
;
75 if (render2d_data
.current
->type
!= RD2_NONE
) {
78 || render2d_data
.current
->type
!= t
81 && m
!= render2d_data
.current
->mat
84 if (!render2d_data
.current
->next
) {
85 render2d_data
.current
= render2d_section_create();
86 render2d_data
.stack
= list_push(&render2d_data
.stack
,render2d_data
.current
);
88 render2d_data
.current
= render2d_data
.current
->next
;
93 render2d_data
.current
->mat
= m
;
95 render2d_data
.current
->type
= t
;
98 /* render a 2d line */
99 void render2d_line(material_t
*m
, float x
, float y
, float ex
, float ey
)
102 render2d_get_section(m,RD2_LINE);
104 render2d_data.current->box.x = x;
105 render2d_data.current->box.y = y;
106 render2d_data.current->box.w = ex;
107 render2d_data.current->box.h = ey;
111 /* render a 2d quad of material */
112 void render2d_quad_mat(material_t
*m
, float x
, float y
, float w
, float h
)
114 render2d_get_section(m
,RD2_QUAD
);
116 y
= wm_data
.size
.height
-y
;
118 w
/= (float)wm_data
.size
.width
;
119 h
/= (float)wm_data
.size
.height
;
120 x
= (((x
/(float)wm_data
.size
.width
)*2.0)-1.0)+w
;
121 y
= (((y
/(float)wm_data
.size
.height
)*2.0)-1.0)-h
;
123 render2d_data
.current
->box
.x
= x
;
124 render2d_data
.current
->box
.y
= y
;
125 render2d_data
.current
->box
.w
= w
;
126 render2d_data
.current
->box
.h
= h
;
130 void render2d_text(float x
, float y
, int w
, int h
, int font
, int size
, char* str
)
133 render2d_get_section(NULL
,RD2_TEXT
);
137 textbuffer_adjust(&render2d_data
.current
->txt
,f
,size
,x
,y
,w
,h
,0,0);
138 textbuffer_addstr(&render2d_data
.current
->txt
,str
);
141 /* render a pregenerated textbuffer */
142 void render2d_textbuffer(textbuffer_t
*t
)
147 render2d_get_section(NULL
,RD2_TEXT
);
149 render2d_data
.current
->itxt
= t
;
151 s
= (((float)t
->font_size
)*0.15);
152 s
/= (float)wm_data
.size
.height
;
155 y
= wm_data
.size
.height
-t
->y
;
157 x
= (((x
/(float)wm_data
.size
.width
)*2.0)-1.0);
158 y
= (((y
/(float)wm_data
.size
.height
)*2.0)-1.0);
160 render2d_data
.current
->box
.x
= x
;
161 render2d_data
.current
->box
.y
= y
;
162 render2d_data
.current
->box
.w
= s
;
163 render2d_data
.current
->box
.h
= s
;
166 /* render a textbuffer */
168 /* render 2d graphics to the frame */
178 glDisable(GL_DEPTH_TEST
);
180 render2d_data
.current
= render2d_data
.stack
;
182 if (render2d_data
.vao
== 0) {
183 GLfloat vertices
[8] = {-1.0,1.0, -1.0,-1.0, 1.0,1.0, 1.0,-1.0};
184 GLfloat texcoords
[8] = {0.0,0.0, 0.0,1.0, 1.0,0.0, 1.0,1.0};
185 glGenVertexArrays(1,&render2d_data
.vao
);
186 glBindVertexArray(render2d_data
.vao
);
187 glGenBuffers(2, render2d_data
.vbo
);
188 glBindBuffer(GL_ARRAY_BUFFER
, render2d_data
.vbo
[0]);
189 glBufferData(GL_ARRAY_BUFFER
, 32, vertices
, GL_STATIC_DRAW
);
190 glEnableVertexAttribArray(0);
191 glVertexAttribPointer(0,2,GL_FLOAT
,GL_FALSE
,0,0);
192 glBindBuffer(GL_ARRAY_BUFFER
, render2d_data
.vbo
[1]);
193 glBufferData(GL_ARRAY_BUFFER
, 32, texcoords
, GL_STATIC_DRAW
);
194 glEnableVertexAttribArray(1);
195 glVertexAttribPointer(1,2,GL_FLOAT
,GL_FALSE
,0,0);
196 glBindBuffer(GL_ARRAY_BUFFER
, 0);
200 if (!render2d_data
.shader
) {
201 render2d_data
.shader
= shader_create("ui");
202 shader_attribute(render2d_data
.shader
,0,"position");
203 shader_attribute(render2d_data
.shader
,1,"uvs");
206 shader_enable(render2d_data
.shader
);
208 glBindVertexArray(render2d_data
.vao
);
209 glEnableVertexAttribArray(0);
210 glEnableVertexAttribArray(1);
213 while (render2d_data
.current
&& render2d_data
.current
->type
!= RD2_NONE
) {
214 if (render2d_data
.current
->type
== RD2_TEXT
) {
215 txt
= render2d_data
.current
->itxt
;
217 txt
= &render2d_data
.current
->txt
;
218 for (i
=0; i
<txt
->data
.length
; i
++) {
219 t
= array_get_ptr(&txt
->data
,i
);
222 glGenVertexArrays(1,&t
->vao
);
223 glBindVertexArray(t
->vao
);
224 glGenBuffers(2, t
->vbo
);
225 glBindBuffer(GL_ARRAY_BUFFER
, t
->vbo
[0]);
226 glBufferData(GL_ARRAY_BUFFER
, t
->v
.length
*4, t
->v
.data
, GL_STATIC_DRAW
);
227 glEnableVertexAttribArray(0);
228 glVertexAttribPointer(0,2,GL_FLOAT
,GL_FALSE
,0,0);
229 glBindBuffer(GL_ARRAY_BUFFER
, t
->vbo
[1]);
230 glBufferData(GL_ARRAY_BUFFER
, t
->t
.length
*4, t
->t
.data
, GL_STATIC_DRAW
);
231 glEnableVertexAttribArray(1);
232 glVertexAttribPointer(1,2,GL_FLOAT
,GL_FALSE
,0,0);
236 glBindVertexArray(t
->vao
);
237 glEnableVertexAttribArray(0);
238 glEnableVertexAttribArray(1);
241 glDeleteBuffers(2, t
->vbo
);
242 glGenBuffers(2, t
->vbo
);
243 glBindBuffer(GL_ARRAY_BUFFER
, t
->vbo
[0]);
244 glBufferData(GL_ARRAY_BUFFER
, t
->v
.length
*4, t
->v
.data
, GL_STATIC_DRAW
);
245 glEnableVertexAttribArray(0);
246 glVertexAttribPointer(0,2,GL_FLOAT
,GL_FALSE
,0,0);
247 glBindBuffer(GL_ARRAY_BUFFER
, t
->vbo
[1]);
248 glBufferData(GL_ARRAY_BUFFER
, t
->t
.length
*4, t
->t
.data
, GL_STATIC_DRAW
);
249 glEnableVertexAttribArray(1);
250 glVertexAttribPointer(1,2,GL_FLOAT
,GL_FALSE
,0,0);
255 glBindTexture(GL_TEXTURE_2D
,t
->glid
);
257 matrix_scale(&m
,render2d_data
.current
->box
.w
,render2d_data
.current
->box
.h
,1.0);
258 matrix_translate(&m
,render2d_data
.current
->box
.x
,render2d_data
.current
->box
.y
,1.0);
259 shader_uniform_matrix(render2d_data
.shader
,"transformationMatrix",&m
);
260 glDrawArrays(GL_TRIANGLES
,0,t
->v
.length
/2);
263 render2d_data
.current
->itxt
= NULL
;
264 textbuffer_clear(&render2d_data
.current
->txt
);
265 }else if (render2d_data
.current
->type
== RD2_QUAD
) {
267 glBindVertexArray(render2d_data
.vao
);
268 glEnableVertexAttribArray(0);
269 glEnableVertexAttribArray(1);
272 mat_use(render2d_data
.current
->mat
,render2d_data
.shader
);
275 matrix_scale(&m
,render2d_data
.current
->box
.w
,render2d_data
.current
->box
.h
,1.0);
276 matrix_translate(&m
,render2d_data
.current
->box
.x
,render2d_data
.current
->box
.y
,1.0);
277 shader_uniform_matrix(render2d_data
.shader
,"transformationMatrix",&m
);
279 glDrawArrays(GL_TRIANGLE_STRIP
,0,4);
280 render2d_data
.current
->mat
= NULL
;
283 render2d_data
.current
->type
= RD2_NONE
;
284 render2d_data
.current
= render2d_data
.current
->next
;
288 glDisableVertexAttribArray(0);
289 glDisableVertexAttribArray(1);
290 glBindVertexArray(0);
293 shader_disable(render2d_data
.shader
);
295 render2d_data
.current
= NULL
;