Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Mipmap causing texture bleeding

This thread is locked; no one can reply to it. rss feed Print
Mipmap causing texture bleeding
Space cpp
Member #16,322
May 2016

I enabled mipmaps in some bitmaps and they are now bleeding to the opposite side when drawn scaled down. I tried adding a transparent border but it doesn't solve the problem 100% of the time.
Is there a way to disable the texture wrapping just for these specific bitmaps?

----------
My games

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Mipmaps work on powers of two, so if your texture isn't POT that might be it. You'll need the transparent border I think. You may be able to change the texture wrapping parameters with some GL calls and see if that helps.

Space cpp
Member #16,322
May 2016

The textures are 512x512.

----------
My games

Bob
Free Market Evangelist
September 2000
avatar

You probably want

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Or something like that.

--
- Bob
[ -- All my signature links are 404 -- ]

Space cpp
Member #16,322
May 2016

Ok, but I'm not using raw opengl, just allegro. And I need the solution to work with both direct3d and opengl backends.

----------
My games

amarillion
Member #940
January 2001
avatar

It's still possible to mix raw opengl calls in your allegro code.

Look for example at ex_opengl.c, it's full of them.

As for mixing opengl and directx, it might make things difficult. Do you also write both HLSL and GLSL shaders? It should still be possible though. ex_shader.cpp uses this construct:

/* The ALLEGRO_CFG_* defines are actually internal to Allegro so don't use them
 * in your own programs.
 */
#ifdef ALLEGRO_CFG_D3D
   #include "allegro5/allegro_direct3d.h"
#endif
#ifdef ALLEGRO_CFG_OPENGL
   #include "allegro5/allegro_opengl.h"
#endif

Personally I just standardize on opengl, easy enough!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

You have to program it for both backends. I don't know how to do it with DX, but with OpenGL you create a texture yourself using the appropriate parameters and then pass it to Allegro.

Bob
Free Market Evangelist
September 2000
avatar

Can we see more code as to how you're drawing the primitives?

Incidentally, when Allegro creates a bitmap, does it set the right texture wrap state?

--
- Bob
[ -- All my signature links are 404 -- ]

Space cpp
Member #16,322
May 2016

Do you also write both HLSL and GLSL shaders?

This set of textures uses only the default allegro shader. Though, I use 2 other shaders for different things (in both shader languages).

Bob said:

Can we see more code as to how you're drawing the primitives?

I'm using FastDraw, internally all drawing is handled by al_draw_indexed_prim.

----------
My games

SiegeLord
Member #7,827
October 2006
avatar

This seems like an easy feature to add. Let me give it a shot. It'll look something like this: al_get/set_bitmap_wrapping(bmp, ALLEGRO_CLAMP/MIRROR/WRAP/etc).

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Bob
Free Market Evangelist
September 2000
avatar

I suspect the texture coordinates are wrong, instead of the texture wrap modes.

--
- Bob
[ -- All my signature links are 404 -- ]

Space cpp
Member #16,322
May 2016

I made the following program to test the issue:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_primitives.h> 3#include "allegro5/allegro_image.h" 4#include <allegro5/allegro_color.h> 5 6#include <stdio.h> 7 8 9 10void draw_tinted_scaled_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh) 11{ 12 13 ALLEGRO_VERTEX vtx[4]; 14 int indices[6] = { 0, 1, 2, 2, 3, 0 }; 15 16 vtx[0].x = dx; vtx[0].y = dy; vtx[0].u = sx; vtx[0].v = sy; 17 vtx[1].x = dx; vtx[1].y = dy + dh; vtx[1].u = sx; vtx[1].v = sy + sh; 18 vtx[2].x = dx + dw; vtx[2].y = dy + dh; vtx[2].u = sx + sw; vtx[2].v = sy + sh; 19 vtx[3].x = dx + dw; vtx[3].y = dy; vtx[3].u = sx + sw; vtx[3].v = sy; 20 21 for (int i = 0; i < 4; i++) 22 { 23 vtx[i].z = 0; 24 vtx[i].color = tint; 25 } 26 27 al_draw_indexed_prim(vtx, NULL, bitmap, indices, 6, ALLEGRO_PRIM_TRIANGLE_LIST); 28 29} 30 31 32 33int main() 34{ 35 36 ALLEGRO_BITMAP *texture = NULL; 37 ALLEGRO_DISPLAY *display = NULL; 38 39 if (!al_init() ) { printf("al_init Failed!"); return -1; } 40 if (!al_init_image_addon() ) { printf("Failed to initialize al_init_image_addon!"); return -1; } 41 if (!al_init_primitives_addon() ) { printf("al_init_primitives_addon failed!"); return -1; } 42 43 display = al_create_display(1280, 720); 44 if (!display) 45 { 46 printf("al_create_display Failed!"); 47 return -1; 48 } 49 50 al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR | ALLEGRO_MIPMAP); 51 texture = al_load_bitmap("texture.png"); if (!texture) { printf("Failed to load texture.png"); return -1; } 52 53 al_clear_to_color(al_map_rgb_f(1,1,1) ); 54 55 56 const float bitmap_width = al_get_bitmap_width(texture); 57 const float bitmap_height = al_get_bitmap_height(texture); 58 float draw_width = bitmap_width; 59 float draw_height = bitmap_height; 60 61 float x = 0.5f; 62 float y = 0.5f; 63 const float min_size = 16.0f; 64 65 do 66 { 67 68 draw_tinted_scaled_bitmap(texture, al_map_rgb_f(1,1,1), 0.0f, 0.0f, bitmap_width, bitmap_height, 69 x, y, draw_width, draw_height); 70 71 x += draw_width; 72 draw_width *= 0.5; 73 draw_height *= 0.5f; 74 75 } while (draw_width >= min_size && draw_height >= min_size); 76 77 al_flip_display(); 78 79 80 al_rest(3.0); 81 82 al_destroy_bitmap(texture); 83 al_destroy_display(display); 84 85 return 0; 86 87}

After playing a bit with the x and y coordinates my conclusion is that non-round values causes the problem. If the bitmap is drawn at 0,0 no bleeding occurs. Change one of the variables to 0.5f and it bleeds.
Removing the mipmap flag also prevents this, but the image will look awful pixelated.
I'm attaching the texture and a screenshot of my result where x and y are both 0.5f.

----------
My games

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Allegro's texture coordinates are integers.

Edit
Also, I don't see the bleeding in your image. The circles look fine to me anyway.

Space cpp
Member #16,322
May 2016

Zoom in in the smaller ones, you will see some red and blue pixels on top and also some blue pixels on the left.

----------
My games

Go to: