src/sprite.c

changeset 137
f8e6e0ae61a8
parent 122
1b118cd3e369
equal deleted inserted replaced
136:768e6eac1ab0 137:f8e6e0ae61a8
30 #include "ascension/context.h" 30 #include "ascension/context.h"
31 #include "ascension/glcontext.h" 31 #include "ascension/glcontext.h"
32 32
33 #include <GL/glew.h> 33 #include <GL/glew.h>
34 34
35 #include "ascension/error.h"
35 #include "ascension/mesh.h" 36 #include "ascension/mesh.h"
36 37
37 static void asc_sprite_destroy(AscSceneNode *node) { 38 static void asc_sprite_destroy(AscSceneNode *node) {
38 AscSprite *sprite = (AscSprite *) node; 39 AscSprite *sprite = (AscSprite *) node;
39 asc_mesh_destroy(&sprite->mesh); 40 asc_mesh_destroy(&sprite->mesh);
73 74
74 // basic node parameters 75 // basic node parameters
75 AscSceneNode *node = (AscSceneNode *) sprite; 76 AscSceneNode *node = (AscSceneNode *) sprite;
76 asc_scene_node_name(node, args.name); 77 asc_scene_node_name(node, args.name);
77 node->render_group = args.opaque 78 node->render_group = args.opaque
78 ? ASC_RENDER_GROUP_SPRITE_OPAQUE 79 ? ASC_RENDER_GROUP_SPRITE_OPAQUE_UV
79 : ASC_RENDER_GROUP_SPRITE_BLEND; 80 : ASC_RENDER_GROUP_SPRITE_BLEND_UV;
80 node->update_func = asc_sprite_update; 81 node->update_func = asc_sprite_update;
81 node->destroy_func = asc_sprite_destroy; 82 node->destroy_func = asc_sprite_destroy;
82 83
83 node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET); 84 node->position = asc_vec3f_new(args.x, args.y, ASC_SCENE_2D_DEPTH_OFFSET);
84 node->scale = asc_vec3f_one; 85 node->scale = asc_vec3f_one;
85 86
86 asc_node_update(node); 87 asc_node_update(node);
87 return node; 88 return node;
88 } 89 }
89 90
90 void asc_sprite_draw(AscSprite const *node) { 91 void asc_sprite_draw(const AscShaderSprite *shader, const AscSprite *node) {
91 // Obtain shader
92 AscShaderSprite *shader = ASC_SHADER_SPRITE;
93
94 // Upload model matrix 92 // Upload model matrix
95 glUniformMatrix4fv(shader->program.model, 1, 93 glUniformMatrix4fv(shader->program.model, 1,
96 GL_FALSE, node->data.world_transform); 94 GL_FALSE, node->data.world_transform);
97 95
98 // Bind texture 96 // Bind texture
99 if (node->texture->target == GL_TEXTURE_RECTANGLE) { 97 asc_texture_bind(node->texture, shader->tex, 0);
100 asc_texture_bind(node->texture, shader->rect_tex, 0);
101 asc_texture_bind(ASC_TEXTURE_2D_EMPTY_1X1, shader->uv_tex, 1);
102 } else {
103 asc_texture_bind(ASC_TEXTURE_RECT_EMPTY_1X1, shader->rect_tex, 0);
104 asc_texture_bind(node->texture, shader->uv_tex, 1);
105 }
106 98
107 // Draw mesh 99 // Draw mesh
108 asc_mesh_draw_triangle_strip(&node->mesh); 100 asc_mesh_draw_triangle_strip(&node->mesh);
109 } 101 }
110 102
112 AscSprite *sprite = (AscSprite*) node; 104 AscSprite *sprite = (AscSprite*) node;
113 sprite->width = width; 105 sprite->width = width;
114 sprite->height = height; 106 sprite->height = height;
115 asc_node_update(node); 107 asc_node_update(node);
116 } 108 }
109
110 int asc_shader_sprite_init(AscShaderSprite *sprite, bool rect) {
111 AscShaderCodes codes;
112 if (asc_shader_load_code_files((AscShaderCodeInfo){
113 .files.vtx = "sprite_vtx.glsl",
114 .files.frag = "sprite_frag.glsl",
115 .defines.frag = rect ? "#define USE_RECT" : NULL,
116 }, &codes)) {
117 asc_error("Loading sprite shader failed.");
118 return 1;
119 }
120 sprite->program = asc_shader_program_create(codes);
121 if (asc_has_error()) {
122 asc_shader_free_codes(codes);
123 return 1;
124 }
125 sprite->tex = glGetUniformLocation(sprite->program.id, "tex");
126 asc_shader_free_codes(codes);
127
128 return asc_error_catch_all_gl();
129 }

mercurial