Simple Multitexturing GLSL? [A5]
Dario ff

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. :P

So here's the code, and I've attached the 2 used images(as well as the source).

#SelectExpand
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.

gnolam
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

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. :P

Thread #606245. Printed from Allegro.cc