|
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. Switching the bitmaps in the glBindTexture calls produces the same situation, but with op_map instead of mysha. So the first texture is binding well I guess... 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. I wonder why every tutorial I was reading was actually doing it wrong? I will blame gamedev.net for this one. TranslatorHack 2010, a human translation chain in a.cc. |
|