104 .size = asc_vec2f_new(sprite->width, sprite->height), |
104 .size = asc_vec2f_new(sprite->width, sprite->height), |
105 .uv_scale = uv_scale |
105 .uv_scale = uv_scale |
106 ); |
106 ); |
107 } |
107 } |
108 |
108 |
|
109 void asc_sprite_draw(const AscCamera *camera, const AscSceneNode *node) { |
|
110 asc_ptr_cast(const AscSprite, sprite, node); |
|
111 |
|
112 // Activate shader |
|
113 // TODO: scene should know which shader we are going to activate s.t. it can pre-sort nodes |
|
114 const AscSpriteShader *shader = |
|
115 sprite->texture->target == GL_TEXTURE_RECTANGLE |
|
116 ? asc_sprite_shader_rect() |
|
117 : asc_sprite_shader_uv(); |
|
118 asc_shader_use(&shader->program, camera); |
|
119 |
|
120 // Upload model matrix |
|
121 glUniformMatrix4fv(shader->program.model, 1, |
|
122 GL_FALSE, node->world_transform); |
|
123 |
|
124 // Bind texture |
|
125 asc_texture_bind(sprite->texture, shader->tex, 0); |
|
126 |
|
127 // Draw mesh |
|
128 asc_mesh_draw_triangle_strip(&sprite->mesh); |
|
129 } |
|
130 |
109 AscSceneNode *asc_sprite_create(struct asc_sprite_create_args args) { |
131 AscSceneNode *asc_sprite_create(struct asc_sprite_create_args args) { |
110 AscSprite *sprite = cxZallocDefault(sizeof(AscSprite)); |
132 AscSprite *sprite = cxZallocDefault(sizeof(AscSprite)); |
111 |
133 |
112 // sprite parameters |
134 // sprite parameters |
113 args.texture->refcount++; |
135 args.texture->refcount++; |
120 |
142 |
121 // basic node parameters |
143 // basic node parameters |
122 AscSceneNode *node = (AscSceneNode *) sprite; |
144 AscSceneNode *node = (AscSceneNode *) sprite; |
123 asc_scene_node_name(node, args.name); |
145 asc_scene_node_name(node, args.name); |
124 node->render_group = args.opaque |
146 node->render_group = args.opaque |
125 ? ASC_RENDER_GROUP_SPRITE_OPAQUE |
147 ? ASC_RENDER_GROUP_2D_OPAQUE |
126 : ASC_RENDER_GROUP_SPRITE_BLEND; |
148 : ASC_RENDER_GROUP_2D_BLEND; |
127 node->update_func = asc_sprite_update; |
149 node->update_func = asc_sprite_update; |
128 node->destroy_func = asc_sprite_destroy; |
150 node->destroy_func = asc_sprite_destroy; |
|
151 node->draw_func = asc_sprite_draw; |
129 |
152 |
130 node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); |
153 node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); |
131 node->scale = asc_vec3f_one; |
154 node->scale = asc_vec3f_one; |
132 |
155 |
133 asc_node_update(node); |
156 asc_node_update(node); |
134 return node; |
157 return node; |
135 } |
|
136 |
|
137 void asc_sprite_draw(const AscCamera *camera, const AscSprite *node) { |
|
138 // Activate shader |
|
139 const AscSpriteShader *shader = |
|
140 node->texture->target == GL_TEXTURE_RECTANGLE |
|
141 ? asc_sprite_shader_rect() |
|
142 : asc_sprite_shader_uv(); |
|
143 asc_shader_use(&shader->program, camera); |
|
144 |
|
145 // Upload model matrix |
|
146 glUniformMatrix4fv(shader->program.model, 1, |
|
147 GL_FALSE, node->data.world_transform); |
|
148 |
|
149 // Bind texture |
|
150 asc_texture_bind(node->texture, shader->tex, 0); |
|
151 |
|
152 // Draw mesh |
|
153 asc_mesh_draw_triangle_strip(&node->mesh); |
|
154 } |
158 } |
155 |
159 |
156 void asc_sprite_set_size(AscSceneNode *node, unsigned width, unsigned height) { |
160 void asc_sprite_set_size(AscSceneNode *node, unsigned width, unsigned height) { |
157 AscSprite *sprite = (AscSprite*) node; |
161 AscSprite *sprite = (AscSprite*) node; |
158 sprite->width = width; |
162 sprite->width = width; |