Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Shader for bitmap not working

This thread is locked; no one can reply to it. rss feed Print
Shader for bitmap not working
jmasterx
Member #11,410
October 2009

I'm using the shader addon and loaded a default shader pair. That works fine. Now I want to apply a shader pair to a bitmap.

After the default pair is loaded and d3d effect is set, I load this shader:

px

   texture tex;
   sampler2D s = sampler_state {
      texture = <tex>;
   };

   float4 ps_main(VS_OUTPUT Input) : COLOR0
   {
     return float4(1.0,1.0,1.0,1.0);
   }

vtx

#SelectExpand
1 struct VS_INPUT 2 { 3 float4 Position : POSITION0; 4 float2 TexCoord : TEXCOORD0; 5 float4 Color : TEXCOORD1; 6 }; 7 struct VS_OUTPUT 8 { 9 float4 Position : POSITION0; 10 float4 Color : COLOR0; 11 float2 TexCoord : TEXCOORD0; 12 }; 13 14 float4x4 projview_matrix; 15 16 VS_OUTPUT vs_main(VS_INPUT Input) 17 { 18 VS_OUTPUT Output; 19 Output.Position = mul(Input.Position, projview_matrix); 20 Output.Color = Input.Color; 21 Output.TexCoord = Input.TexCoord; 22 return Output; 23 }

Then when I come to render:

      m_shader.setSampler(m_table,"tex");
      m_shader.use();
      g->drawScaledSprite(m_table,0,0,
        m_table->getWidth(),m_table->getHeight(),
        x,
        y,
        desiredW,desiredW,0);
      m_shader.stop();

However it still renders it with the default shader pair. The table should be white.

The shader compiles fine. What could be wrong?

Thanks

Trent Gamblin
Member #261
April 2000
avatar

Can you post a test case? I still find these things tricky to deal with so I'd have to play around with it a bit to see why it's not working.

jmasterx
Member #11,410
October 2009

This demonstrates it:

#SelectExpand
1#include "allegro5/allegro5.h" 2#include "allegro5/allegro_shader.h" 3#include "allegro5/allegro_image.h" 4#include "allegro5/allegro_primitives.h" 5#include <cstdio> 6 7// FIXME: supported drivers should go in alplatf.h 8// Uncomment one of these three blocks depending what driver you want 9 10#define HLSL 11#include "allegro5/allegro_direct3d.h" 12#include "allegro5/allegro_shader_hlsl.h" 13 14//#define GLSL 15//#include "allegro5/allegro_opengl.h" 16//#include "allegro5/allegro_shader_glsl.h" 17 18/* 19#define CG 20#include <Cg/cg.h> 21*/ 22 23#ifdef HLSL 24#define TOP 0 25#define BOT 1 26#define vsource_name hlsl_vertex_source 27#define psource_name hlsl_pixel_source 28#define PLATFORM ALLEGRO_SHADER_HLSL 29#elif defined GLSL 30#define TOP 1 31#define BOT 0 32#define vsource_name glsl_vertex_source 33#define psource_name glsl_pixel_source 34#define PLATFORM ALLEGRO_SHADER_GLSL 35#else 36#define TOP 1 37#define BOT 0 38#define vsource_name cg_vertex_source 39#define psource_name cg_pixel_source 40#define PLATFORM ALLEGRO_SHADER_CG 41#endif 42 43#ifdef GLSL 44#define EX_SHADER_FLAGS ALLEGRO_OPENGL 45#else 46#define EX_SHADER_FLAGS 0 47#endif 48 49#ifdef CG 50static const char *cg_vertex_source = 51"uniform float4x4 projview_matrix;\n" 52"void vs_main(\n" 53" in float3 pos : POSITION,\n" 54" in float4 color : COLOR0,\n" 55" in float2 texcoord : TEXCOORD0,\n" 56" out float4 posO : POSITION,\n" 57" out float4 colorO : COLOR0,\n" 58" out float2 texcoordO : TEXCOORD0)\n" 59"{\n" 60" posO = mul(float4(pos, 1.0), projview_matrix);\n" 61" colorO = color;\n" 62" texcoordO = texcoord;\n" 63"}\n"; 64 65static const char *cg_pixel_source = 66"uniform sampler2D tex;\n" 67"uniform float3 tint;\n" 68"void ps_main(\n" 69" in float4 color : COLOR0,\n" 70" in float2 texcoord : TEXCOORD0,\n" 71" out float4 colorO : COLOR0)\n" 72"{\n" 73" colorO = color * tex2D(tex, texcoord);\n" 74" colorO.r *= tint.r;\n" 75" colorO.g *= tint.g;\n" 76" colorO.b *= tint.b;\n" 77"}\n"; 78#endif 79 80#ifdef HLSL 81static const char *hlsl_vertex_source = 82"struct VS_INPUT\n" 83"{\n" 84" float4 Position : POSITION0;\n" 85" float2 TexCoord : TEXCOORD0;\n" 86" float4 Color : TEXCOORD1;\n" 87"};\n" 88"struct VS_OUTPUT\n" 89"{\n" 90" float4 Position : POSITION0;\n" 91" float4 Color : COLOR0;\n" 92" float2 TexCoord : TEXCOORD0;\n" 93"};\n" 94"\n" 95"float4x4 projview_matrix;\n" 96"\n" 97"VS_OUTPUT vs_main(VS_INPUT Input)\n" 98"{\n" 99" VS_OUTPUT Output;\n" 100" Output.Position = mul(Input.Position, projview_matrix);\n" 101" Output.Color = Input.Color;\n" 102" Output.TexCoord = Input.TexCoord;\n" 103" return Output;\n" 104"}\n"; 105 106static const char *hlsl_pixel_source = 107"texture tex;\n" 108"sampler2D s = sampler_state {\n" 109" texture = <tex>;\n" 110"};\n" 111"float3 tint;\n" 112"float4 ps_main(VS_OUTPUT Input) : COLOR0\n" 113"{\n" 114" float4 pixel = tex2D(s, Input.TexCoord.xy);\n" 115" pixel.r *= tint.r;\n" 116" pixel.g *= tint.g;\n" 117" pixel.b *= tint.b;\n" 118" return pixel;\n" 119"}\n"; 120#endif 121 122#ifdef GLSL 123static const char *glsl_vertex_source = 124"attribute vec4 pos;\n" 125"attribute vec4 color;\n" 126"attribute vec2 texcoord;\n" 127"uniform mat4 projview_matrix;\n" 128"varying vec4 varying_color;\n" 129"varying vec2 varying_texcoord;\n" 130"void main()\n" 131"{\n" 132" varying_color = color;\n" 133" varying_texcoord = texcoord;\n" 134" gl_Position = projview_matrix * pos;\n" 135"}\n"; 136 137static const char *glsl_pixel_source = 138"uniform sampler2D tex;\n" 139"uniform vec3 tint;\n" 140"varying vec4 varying_color;\n" 141"varying vec2 varying_texcoord;\n" 142"void main()\n" 143"{\n" 144" vec4 tmp = varying_color * texture2D(tex, varying_texcoord);\n" 145" tmp.r *= tint.r;\n" 146" tmp.g *= tint.g;\n" 147" tmp.b *= tint.b;\n" 148" gl_FragColor = tmp;\n" 149"}\n"; 150#endif 151 152#if defined HLSL && !defined CG 153#include <allegro5/allegro_direct3d.h> 154#include <d3d9.h> 155#include <d3dx9.h> 156 157#define A5V_FVF (D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE4(1)) 158 159void drawD3D(ALLEGRO_VERTEX *v, int start, int count) 160{ 161 ALLEGRO_DISPLAY *display = al_get_current_display(); 162 LPDIRECT3DDEVICE9 device = al_get_d3d_device(display); 163 164 device->SetFVF(A5V_FVF); 165 166 device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, 167 &v[start].x, sizeof(ALLEGRO_VERTEX)); 168} 169#endif 170 171int main(int argc, char **argv) 172{ 173 ALLEGRO_DISPLAY *display; 174 ALLEGRO_BITMAP *bmp; 175 ALLEGRO_SHADER *shader; 176 ALLEGRO_SHADER *shader2; 177 178 (void)argc; 179 (void)argv; 180 181 al_init(); 182 al_install_keyboard(); 183 al_init_image_addon(); 184 185 al_set_new_display_flags(ALLEGRO_USE_PROGRAMMABLE_PIPELINE | EX_SHADER_FLAGS); 186 187 display = al_create_display(640, 480); 188 189 bmp = al_load_bitmap("data/mysha.pcx"); 190 191 shader = al_create_shader(PLATFORM); 192 if (!shader) { 193 fprintf(stderr, "Could not create shader\n"); 194 return 1; 195 } 196 197 if (!al_attach_shader_source(shader, ALLEGRO_VERTEX_SHADER, vsource_name)) { 198 fprintf(stderr, "%s\n", al_get_shader_log(shader)); 199 return 1; 200 } 201 if (!al_attach_shader_source(shader, ALLEGRO_PIXEL_SHADER, psource_name)) { 202 fprintf(stderr, "%s\n", al_get_shader_log(shader)); 203 return 1; 204 } 205 206 if (!al_link_shader(shader)) { 207 fprintf(stderr, "%s\n", al_get_shader_log(shader)); 208 return 1; 209 } 210 211 shader2 = al_create_shader(PLATFORM); 212 if (!shader2) { 213 fprintf(stderr, "Could not create shader\n"); 214 return 1; 215 } 216 217 if (!al_attach_shader_source_file(shader2, ALLEGRO_VERTEX_SHADER, "data/test.hlslv")) { 218 fprintf(stderr, "%s\n", al_get_shader_log(shader)); 219 return 1; 220 } 221 if (!al_attach_shader_source_file(shader2, ALLEGRO_PIXEL_SHADER, "data/test.hlslp")) { 222 fprintf(stderr, "%s\n", al_get_shader_log(shader2)); 223 return 1; 224 } 225 226 if (!al_link_shader(shader2)) { 227 fprintf(stderr, "%s\n", al_get_shader_log(shader2)); 228 return 1; 229 } 230 231#if defined GLSL 232 al_set_opengl_program_object(display, al_get_opengl_program_object(shader)); 233#elif defined HLSL 234 al_set_direct3d_effect(display, al_get_direct3d_effect(shader)); 235#endif 236 237 float tints[12] = { 238 4.0, 0.0, 1.0, 239 0.0, 4.0, 1.0, 240 1.0, 0.0, 4.0, 241 4.0, 4.0, 1.0 242 }; 243 244 while (1) { 245 ALLEGRO_KEYBOARD_STATE s; 246 al_get_keyboard_state(&s); 247 if (al_key_down(&s, ALLEGRO_KEY_ESCAPE)) 248 break; 249 250 al_clear_to_color(al_map_rgb(140, 40, 40)); 251 252 al_set_shader_sampler(shader2, "tex", bmp, 0); 253 254 al_use_shader(shader2, true); 255 al_draw_bitmap(bmp, 0, 0, 0); 256 al_use_shader(shader2, false); 257 258 al_set_shader_sampler(shader, "tex", bmp, 0); 259 al_set_shader_float_vector(shader, "tint", 3, &tints[3], 1); 260 al_use_shader(shader, true); 261 al_draw_bitmap(bmp, 320, 0, 0); 262 al_use_shader(shader, false); 263 264 al_set_shader_sampler(shader2, "tex", bmp, 0); 265 al_use_shader(shader2, true); 266 al_draw_bitmap(bmp, 0, 240, 0); 267 al_use_shader(shader2, false); 268 269 270 al_flip_display(); 271 272 al_rest(0.01); 273 } 274 275 al_destroy_shader(shader); 276 277 return 0; 278}

The drawn bitmaps should be white, but clearly they are being drawn by the first shader and are green.

Trent Gamblin
Member #261
April 2000
avatar

I don't know what's going on on my system. The window gets created but then it exits with return code 1, but nothing is printed, and I'm running it as a console program. Single stepping from main doesn't show anything either. I'm using a VM but I'll reboot a bit later tonight and try to figure it out from a real Windows install.

EDIT: Oops. I didn't read the code and notice the external shader source. It is not displaying them in green.

EDIT2: 1 character fix: "shader" in the al_set_direct3d_effect should be shader2. :)

jmasterx
Member #11,410
October 2009

I did it on purpose for the D3D effect not to be shader2. Do you mean I have to call set d3d effect every time I want to switch shaders? I thought I only called that to set the default shader pair.

Trent Gamblin
Member #261
April 2000
avatar

There's no such thing as a default shader pair. You set the shader and keep track of which one you want set. So yes, you call it every time.

jmasterx
Member #11,410
October 2009

Ooooooh... okay. That makes much more sense.

So in my Shader class I should keep a static pointer to the 'default' (by default I mean the ones I set to take the place of the fixed pipeline) shader pair.

I imagined it as setting a default shader pair that basically takes place of fixed pipeline, then when you use() a shader it overrides that until you use(false) where it would go back to the default pair. Maybe that could be an option, it seems redundant to have to keep track of the shader that takes place of the fixed pipeline.

Go to: