![]() |
|
Simple Multitexturing GLSL? [A5] |
Dario ff
Member #10,065
August 2008
![]() |
So I've decided on trying back GLSL, but I'm finding quite a lot of trouble in getting a basic multitexture shader up. I've googled for hours, always ending up on the same result. I can't spot anything else that would be needed on the code, so I would appreciate if someone with more experience could help me. The expected output is the picture of mysha drawn, with its R color channel replaced by the one in op_map.png. Instead, it's using the R component from the original image, so you can't spot anything different. It's as if the two samples pointed to the same texture. The code is pretty much copy-pasted from various tutorials around, which pretty much say the same on all occasions. I was a bit confused as well since the standard example in the allegro folder was setting the backBuffer sampler to the texture's ID instead of of a texture unit like GL_TEXTURE0. Which everyone said is a pretty common mistake as well. So here's the code, and I've attached the 2 used images(as well as the source). 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_opengl.h>
3#include <allegro5/allegro_image.h>
4#include <stdio.h>
5
6
7GLhandleARB tinter;
8GLhandleARB tinter_shader;
9
10
11
12void abort_example(char const *format, ...)
13{
14 char str[1024];
15 va_list args;
16 ALLEGRO_DISPLAY *display;
17
18 va_start(args, format);
19 vsnprintf(str, sizeof str, format, args);
20 va_end(args);
21
22 display = al_is_system_installed() ? al_get_current_display() : NULL;
23 al_show_native_message_box(display, "Error", "Cannot run example", str, NULL, 0);
24 exit(1);
25}
26
27
28int main(void)
29{
30 ALLEGRO_DISPLAY *display;
31 ALLEGRO_BITMAP *mysha;
32 ALLEGRO_BITMAP *op_map;
33
34 const char *tinter_shader_src[] = {
35 "uniform sampler2D base;",
36 "uniform sampler2D op_map;",
37 "void main() {",
38 " vec4 color;",
39 " vec4 color_map;",
40 " color = texture2D(base, gl_TexCoord[0].st);",
41 " color_map = texture2D(op_map, gl_TexCoord[0].st);",
42 " color.r = color_map.r;",
43 " gl_FragColor = color;",
44 "}"
45 };
46 const int TINTER_LEN = 10;
47 GLint loc;
48
49 if (!al_init()) {
50 abort_example("Could not init Allegro\n");
51 }
52
53 al_install_keyboard();
54 al_init_image_addon();
55
56 al_set_new_display_flags(ALLEGRO_OPENGL);
57 display = al_create_display(320, 200);
58 if (!display) {
59 abort_example("Error creating display\n");
60 }
61
62 mysha = al_load_bitmap("mysha.pcx");
63 if (!mysha) {
64 abort_example("Could not load image.\n");
65 }
66
67 op_map = al_load_bitmap("op_map.png");
68 if (!op_map) {
69 abort_example("Could not load image.\n");
70 }
71
72
73 if (!al_have_opengl_extension("GL_EXT_framebuffer_object")) {
74 abort_example("GL_EXT_framebuffer_object not supported.\n");
75 }
76
77 // Check for shader support
78 if (!al_have_opengl_extension("GL_ARB_fragment_shader")) {
79 abort_example("Fragment shaders not supported.\n");
80 }
81
82 tinter_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
83
84 glShaderSourceARB(tinter_shader, TINTER_LEN, tinter_shader_src, NULL);
85 glCompileShaderARB(tinter_shader);
86 tinter = glCreateProgramObjectARB();
87 glAttachObjectARB(tinter, tinter_shader);
88 glLinkProgramARB(tinter);
89
90 glUseProgramObjectARB(tinter);
91 // Assign base sample to first texture unit
92 loc = glGetUniformLocationARB(tinter, "base");
93 glUniform1iARB(loc, GL_TEXTURE0);
94 printf("%d\n", loc);
95
96 // Assign opacity map sample to second texture unit
97 loc = glGetUniformLocationARB(tinter, "op_map");
98 glUniform1iARB(loc, GL_TEXTURE1);
99 printf("%d\n", loc);
100 glUseProgramObjectARB(0);
101
102 while (1) {
103 ALLEGRO_KEYBOARD_STATE state;
104 al_get_keyboard_state(&state);
105 if (al_key_down(&state, ALLEGRO_KEY_ESCAPE)) {
106 break;
107 }
108
109 glUseProgramObjectARB(tinter);
110
111 glActiveTexture(GL_TEXTURE0);
112 glBindTexture(GL_TEXTURE_2D, al_get_opengl_texture(mysha));
113
114 glActiveTexture(GL_TEXTURE1);
115 glBindTexture(GL_TEXTURE_2D, al_get_opengl_texture(op_map));
116
117 glBegin(GL_QUADS);
118
119 float sx, sy, fx, fy;
120 sx = 0; sy = 0;
121 fx = 320; fy = 200;
122 glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
123 glMultiTexCoord2f(GL_TEXTURE1, 0.0, 1.0);
124 glVertex3f(0.0, 0.0, 0.0);
125
126 glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
127 glMultiTexCoord2f(GL_TEXTURE1, 0.0, 0.0);
128 glVertex3f(0.0, fy, 0.0);
129
130 glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
131 glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);
132 glVertex3f(fx, fy, 0.0);
133
134 glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
135 glMultiTexCoord2f(GL_TEXTURE1, 1.0, 1.0);
136 glVertex3f(fx, 0.0, 0.0);
137 glEnd();
138
139 glActiveTexture(GL_TEXTURE0);
140
141 glUseProgramObjectARB(0);
142 al_flip_display();
143 al_rest(0.001);
144 }
145
146 glDetachObjectARB(tinter, tinter_shader);
147 glDeleteObjectARB(tinter_shader);
148
149 al_uninstall_system();
150
151 return 0;
152}
153
154/* vim: set sts=3 sw=3 et: */
And a clicky for the attachment. TranslatorHack 2010, a human translation chain in a.cc. |
gnolam
Member #2,030
March 2002
![]() |
Dario ff said: glUniform1iARB(loc, GL_TEXTURE0); The sampler uniform doesn't take the GL_TEXTUREx define as a value - it takes the actual number of the texture unit the texture is bound to (in this case, 0). -- |
Dario ff
Member #10,065
August 2008
![]() |
Thanks, it works with that. TranslatorHack 2010, a human translation chain in a.cc. |
|