30 #include "ascension/constants.h" |
30 #include "ascension/constants.h" |
31 #include "ascension/context.h" |
31 #include "ascension/context.h" |
32 #include "ascension/error.h" |
32 #include "ascension/error.h" |
33 #include "ascension/shader.h" |
33 #include "ascension/shader.h" |
34 |
34 |
|
35 // TODO: implement abstraction in shader.h to remove glew.h include here |
35 #include <GL/glew.h> |
36 #include <GL/glew.h> |
36 #include <assert.h> |
37 #include <assert.h> |
37 |
38 |
38 typedef struct asc_rectangle_shader_s { |
39 typedef struct asc_rectangle_shader_s { |
39 AscShaderProgram program; |
40 AscShaderProgram program; |
100 asc_mesh_destroy(&rectangle->mesh); |
101 asc_mesh_destroy(&rectangle->mesh); |
101 } |
102 } |
102 |
103 |
103 static void asc_rectangle_update(AscSceneNode *node) { |
104 static void asc_rectangle_update(AscSceneNode *node) { |
104 asc_ptr_cast(AscRectangle, rectangle, node); |
105 asc_ptr_cast(AscRectangle, rectangle, node); |
105 asc_vec2f size = asc_vec2f_new(rectangle->width, rectangle->height); |
106 asc_mesh_plane_2d(&rectangle->mesh, .size = rectangle->size, .uv_scale = rectangle->size); |
106 asc_mesh_plane_2d(&rectangle->mesh, .size = size, .uv_scale = size); |
|
107 } |
107 } |
108 |
108 |
109 static void asc_rectangle_draw(const AscCamera *camera, const AscSceneNode *node) { |
109 static void asc_rectangle_draw(const AscCamera *camera, const AscSceneNode *node) { |
110 asc_ptr_cast(AscRectangle, rectangle, node); |
110 asc_ptr_cast(AscRectangle, rectangle, node); |
111 const bool filled = rectangle->filled; |
111 const bool filled = rectangle->filled; |
136 // TODO: how to remove the following cast? |
136 // TODO: how to remove the following cast? |
137 if (asc_shader_invalid((AscShaderProgram*)shader)) return; |
137 if (asc_shader_invalid((AscShaderProgram*)shader)) return; |
138 asc_shader_use(&shader->program, camera); |
138 asc_shader_use(&shader->program, camera); |
139 |
139 |
140 // Upload uniforms |
140 // Upload uniforms |
141 // TODO: uploading model matrix could be a helper function |
141 asc_shader_upload_model_matrix(&shader->program, node); |
142 glUniformMatrix4fv(shader->program.model, 1, |
|
143 GL_FALSE, node->world_transform); |
|
144 |
142 |
145 if (filled) { |
143 if (filled) { |
146 glUniform4f(shader->color, |
144 asc_shader_upload_col4f(shader->color, rectangle->color); |
147 rectangle->color.red, |
145 } |
148 rectangle->color.green, |
146 asc_shader_upload_vec2f(shader->size, rectangle->size); |
149 rectangle->color.blue, |
|
150 rectangle->color.alpha |
|
151 ); |
|
152 } |
|
153 glUniform2f(shader->size, rectangle->width, rectangle->height); |
|
154 |
147 |
155 if (border) { |
148 if (border) { |
156 glUniform1f(shader->thickness, rectangle->thickness); |
149 asc_shader_upload_float(shader->thickness, rectangle->thickness); |
157 glUniform4f(shader->border_color, |
150 asc_shader_upload_col4f(shader->border_color, rectangle->border_color); |
158 rectangle->border_color.red, |
|
159 rectangle->border_color.green, |
|
160 rectangle->border_color.blue, |
|
161 rectangle->border_color.alpha |
|
162 ); |
|
163 } |
151 } |
164 if (round) { |
152 if (round) { |
165 glUniform1f(shader->radius, rectangle->radius); |
153 asc_shader_upload_float(shader->radius, rectangle->radius); |
166 } |
154 } |
167 |
155 |
168 // Draw mesh |
156 // Draw mesh |
169 asc_mesh_draw_triangle_strip(&rectangle->mesh); |
157 asc_mesh_draw_triangle_strip(&rectangle->mesh); |
170 } |
158 } |
173 AscRectangle *rectangle = cxZallocDefault(sizeof(AscRectangle)); |
161 AscRectangle *rectangle = cxZallocDefault(sizeof(AscRectangle)); |
174 |
162 |
175 if (args.bounds.size.width + args.bounds.size.height > 0) { |
163 if (args.bounds.size.width + args.bounds.size.height > 0) { |
176 rectangle->node.position.x = (float) args.bounds.pos.x; |
164 rectangle->node.position.x = (float) args.bounds.pos.x; |
177 rectangle->node.position.y = (float) args.bounds.pos.y; |
165 rectangle->node.position.y = (float) args.bounds.pos.y; |
178 rectangle->width = (float) args.bounds.size.width; |
166 rectangle->size.width = (float) args.bounds.size.width; |
179 rectangle->height = (float) args.bounds.size.height; |
167 rectangle->size.height = (float) args.bounds.size.height; |
180 } else { |
168 } else { |
181 rectangle->node.position.x = (float) args.x; |
169 rectangle->node.position.x = (float) args.x; |
182 rectangle->node.position.y = (float) args.y; |
170 rectangle->node.position.y = (float) args.y; |
183 rectangle->width = (float) args.width; |
171 rectangle->size.width = (float) args.width; |
184 rectangle->height = (float) args.height; |
172 rectangle->size.height = (float) args.height; |
185 } |
173 } |
186 |
174 |
187 rectangle->radius = (float)args.radius; |
175 rectangle->radius = (float)args.radius; |
188 rectangle->color = asc_col_itof(asc_context.ink); |
176 rectangle->color = asc_col_itof(asc_context.ink); |
189 rectangle->border_color = asc_col_itof(args.border_color); |
177 rectangle->border_color = asc_col_itof(args.border_color); |