27 |
27 |
28 #include "ascension/2d/sprite.h" |
28 #include "ascension/2d/sprite.h" |
29 |
29 |
30 #include "ascension/context.h" |
30 #include "ascension/context.h" |
31 #include "ascension/glcontext.h" |
31 #include "ascension/glcontext.h" |
|
32 #include "ascension/error.h" |
|
33 #include "ascension/mesh.h" |
|
34 #include "ascension/constants.h" |
32 |
35 |
33 #include <GL/glew.h> |
36 #include <GL/glew.h> |
34 |
37 |
35 #include "ascension/error.h" |
38 |
36 #include "ascension/mesh.h" |
39 struct asc_sprite_shader_s { |
|
40 AscShaderProgram program; |
|
41 int tex; |
|
42 }; |
|
43 |
|
44 static void *asc_sprite_shader_create(bool rect) { |
|
45 AscShaderCodes codes; |
|
46 if (asc_shader_load_code_files((AscShaderCodeInfo){ |
|
47 .files.vtx = "sprite_vtx.glsl", |
|
48 .files.frag = "sprite_frag.glsl", |
|
49 .defines.frag = rect ? "#define USE_RECT" : NULL, |
|
50 }, &codes)) { |
|
51 asc_error("Loading sprite shader failed."); |
|
52 return NULL; |
|
53 } |
|
54 struct asc_sprite_shader_s *shader = asc_shader_create(codes, sizeof(*shader)); |
|
55 if (asc_has_error()) { |
|
56 asc_shader_free_codes(codes); |
|
57 return NULL; |
|
58 } |
|
59 shader->tex = glGetUniformLocation(shader->program.gl_id, "tex"); |
|
60 asc_shader_free_codes(codes); |
|
61 |
|
62 asc_error_catch_all_gl(); |
|
63 |
|
64 return shader; |
|
65 } |
|
66 |
|
67 static AscShaderProgram *asc_sprite_shader_rect_create() { |
|
68 return asc_sprite_shader_create(true); |
|
69 } |
|
70 |
|
71 static AscShaderProgram *asc_sprite_shader_uv_create() { |
|
72 return asc_sprite_shader_create(false); |
|
73 } |
37 |
74 |
38 static void asc_sprite_destroy(AscSceneNode *node) { |
75 static void asc_sprite_destroy(AscSceneNode *node) { |
39 AscSprite *sprite = (AscSprite *) node; |
76 AscSprite *sprite = (AscSprite *) node; |
40 asc_mesh_destroy(&sprite->mesh); |
77 asc_mesh_destroy(&sprite->mesh); |
41 sprite->texture->refcount--; |
78 sprite->texture->refcount--; |
86 |
123 |
87 asc_node_update(node); |
124 asc_node_update(node); |
88 return node; |
125 return node; |
89 } |
126 } |
90 |
127 |
91 void asc_sprite_draw(const AscShaderSprite *shader, const AscSprite *node) { |
128 const AscShaderProgram *asc_sprite_shader_rect(void) { |
|
129 return asc_shader_lookup_or_create(ASC_SHADER_SPRITE_RECT, asc_sprite_shader_rect_create); |
|
130 } |
|
131 |
|
132 const AscShaderProgram *asc_sprite_shader_uv(void) { |
|
133 return asc_shader_lookup_or_create(ASC_SHADER_SPRITE_UV, asc_sprite_shader_uv_create); |
|
134 } |
|
135 |
|
136 void asc_sprite_draw(const AscShaderProgram *program, const AscSprite *node) { |
|
137 asc_ptr_cast(const struct asc_sprite_shader_s, shader, program); |
|
138 |
92 // Upload model matrix |
139 // Upload model matrix |
93 glUniformMatrix4fv(shader->program.model, 1, |
140 glUniformMatrix4fv(shader->program.model, 1, |
94 GL_FALSE, node->data.world_transform); |
141 GL_FALSE, node->data.world_transform); |
95 |
142 |
96 // Bind texture |
143 // Bind texture |
105 sprite->width = width; |
152 sprite->width = width; |
106 sprite->height = height; |
153 sprite->height = height; |
107 asc_node_update(node); |
154 asc_node_update(node); |
108 } |
155 } |
109 |
156 |
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 } |
|