Mipmap causing texture bleeding
Space cpp

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?

Edgar Reynaldo

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

The textures are 512x512.

Bob

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.

Space cpp

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

amarillion

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

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

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?

Space cpp

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.

SiegeLord

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).

Bob

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

Space cpp

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.

Edgar Reynaldo

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

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

Thread #618450. Printed from Allegro.cc