Currently I have a texture atlas that is 2048 x 2048 pixels set up with three 512 x 512 textures stored, and I am only applying one texture to the object. So I used the following code to position the texture coordinates (from zero to 1) to the correct position on the texture atlas for that texture:
color = texture2D(tex_0, vec2(0.0, 1024.0/2048.0) + mod(texture_coordinate*vec2(40.0), vec2(1.0))*vec2(512.0/2048.0));
The problem is that when I apply this, there is a black border around the texture. I presume that this is because OpenGL can't blend the two pixels at the place of that border.
So how do I get rid of the border?
Edit*
I have already tried to move the starting and ending boundaries in toward the center of the texture and that didn't work.
Edit*
I found the source of the problem, the automatic mipmap generation is blending the textures in the texture atlas together. This means I have to write my own mipmapping function. (As far as I can tell)
If anyone has any better ideas, please do post.
Instead of using a normal 2D texture as the texture atlas with a grid of textures, I used the GL_2D_TEXTURE_ARRAY functionality to create a 3D texture that mipmapped correctly and repeated correctly. That way the textures did not blend together at higher mipmap levels.
Related
I am writing a small OpenGL tile map renderer in C# with OpenTK.
To render the tiles I first create a vertex array and then a vertex buffer.
At next I iterate over all tiles and dependent from the tile type I add two triangles to the vertex buffer with the corresponding vertices(texture coords, color, position).
To avoid texture expensive switching I use one big texture with all tile textures named texture atlas.
But I have a problem while working with a texture atlas.
The problem is that I get some artifacts at the edge of some tiles if I zooming out and moving the camera around.
The solutions I found on the internet were...
...to calculate texture coords with half pixel correction.
...to use a texture array
The first one I tried but it didn't worked how expected (More explained below).
The second one I don't know how to work with texture arrays and I couldn't find much about texture arrays on the internet.
I used the following texture filters:
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
Texture coords calculation with half pixel correction:
text_coord_x = (0.5f + pixel_x) / texture_width;
text_coord_y = (0.5f + pixel_x) / texture_height;
Texture coords calculation without half pixel correction:
text_coord_x = pixel_x / texture_width;
text_coord_y = pixel_y / texture_height;
One tile with half pixel correction:
One tile without half pixel correction:
Multiple tiles with half pixel correction:
Multiple tiles without half pixel correction:
For solve your problem with border at atlas you should left N pixel border around each sprite. This border should contain pixel information depends of tiling what you need. This border may be generated by lot 3d programs.
For example Blender can bake several textures into one with margin options:
Also N pixels width depends from mip levels of future atlas. So if you will add one pixel border then you can to use only single mip level (zero mip level). For two - you can use 0 mip and 1 mip level etc. Make sure that your use mip levels not more them border width was.
I am drawing a map texture and, on top of it, a colorbar texture. Both have alpha channel and I am using blending, set as
// Turn on blending
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
However, the following happens:
The texture on top (colorbar) with alpha channel imposes its black pixels, which I don't want to happen. The map texture should appear behind where the colorbar alpha = 0.
Is this related to the blending definitions? How should I change it?
Assuming the texture has an alpha channel and it's transparent in the right places, I suspect the issue is with the rendering order and depth testing.
Lets say you render the scale texture first. It blends correctly with a black background. Then you render the orange texture behind it, but the pixels from the scale texture have a higher depth value and cause the orange texture there to be discarded.
So, make sure you render all your transparent stuff in back to front order, or farthest to nearest.
Without getting into order independent transparency, a common approach to alpha transparency is as follows:
Enable the depth buffer
Render all your opaque geometry
Disable depth writes (glDepthMask)
Enable alpha blending (as in the OP's code)
Render your transparent geometry in farthest to nearest order
For particles you can sometimes get away without sorting and it'll still look OK. Another approach is using the alpha test or using alpha to coverage with a multisample framebuffer.
I have a 512X512 texture which holds a number of images that i want to use in my application. After adding the image data to the texture i save the texture coords for the individual images. Later i apply these on some quads that i am drawing. The texture has mipmapping activated.
When i take a screenshot of the rendered scene at exactly the same instance in two different runs of the applications, i notice that there are differences in the image only among those quads textured using this mipmapped texture. Can mipmapping cause such an issue?
My best guess is that it has to do with precisions in your shader. Check out this problem that I had (and fought with for a while) and my solution:
opengl texture mapping off by 5-8 pixels
It probably is a combination of mimapping's automatic scaling of your texture atlas and the precision hints in your shader code.
Also see the other linked question:
Why is a texture coordinate of 1.0 getting beyond the edge of the texture?
I have an assignment to render a terrain from a greyscale 8bit bmp and get colors to the terrain from a texture 24bit bmp. I managed to get a proper landscape with heights and so on, and also I get the colors from the texture bitmap. The problem is that the full color rendered terrain is very "blocky", it shows right colors and height but it's so blocky. I use glShadeModel(GL_SMOOTH) but it still looks so blocky, almost like I can see the pixels from the bitmap. So any hints are appreciated.
Do you use the bitmap as texture, or do you set vertex colours from the bitmap? I suggest you use a texture, using the planar vertex position as texture coordinate.
One thing you have to take into consideration is when you are rendering are you using GL_TRIANGLES or GL_TRIANGLESTRIPS this makes a difference on performance, second if you are using lighting you have to define your normals and each triangle or each vertex of each triangle, the problem then becomes tricky because almost every triangle is on a different plane. Not having proper normals would make it look blocky. The third thing that makes a difference is how big or small the triangles are; the smaller the triangles or the more divisions in your [x,z] plane increases you resolution thus increases the visual quality, but also slows down your frame rate. You have to find a good balance between the two.
This is for a 2D game with OpenGL:
Is it with using OpenGL possible to display a texture absolutely unfiltered, not streched or blurred?
So that when I have a BMP and convert it into an OpenGL texture, and then retrieve that texture and convert it back, I have no modifications or quality / data loss?
Sure, just disable filtering, that's made by setting the GL_MIN_FILTER and the GL_MAG_FILTER to GL_NEAREST. Also make sure that you draw the texture in a appropiate size so that texels are the same size as pixels.
As Matias said previously - one thing is to set GL_MIN_FILTER and GL_MAG_FITLER to GL_NEAREST (via glTexParameter*).
But for pixel-perfect rendering, there's another important thing- you don't want your texture to be rescaled to power-of-two. The easiest way is to specify the texture via the binding target GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D. On such bound texture, the texture coordinates are not in range (0..1,0..1) as usually, but (0..w, 0..h) instead. You can have per-texel indexing easily this way.