Odd jagged appearance of mip-mapped textures in OpenGL using "glGenerateMipmap" - opengl

I am experimenting with mip-maps for the first time in OpenGL. I followed this tutorial, which builds on this code. In the fragment shader I did the following modification:
vec2 uv = UV;
uv.y = 1-UV.y;
color = texture( myTextureSampler, uv, 1 ).rgb;
... which flips the y axis values (part of the tutorial exercise to get the texture right). It also sets the LOD bias on the final row, so that I can view the coarser details in the texture.
I also modified the cpp file of the tutorial:
line 29, turned off super-sampling anti-aliasing:
// glfwWindowHint(GLFW_SAMPLES, 4);
line 87, create the mip-maps:
GLuint Texture = loadDDS("uvtemplate.DDS");
glBindTexture(GL_TEXTURE_2D, Texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
from line 183, implemented simple camera movement (to get a good overview of its appearance):
...
GLfloat rot = 0.0;
do{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
rot += 0.003;
View = glm::lookAt(
glm::vec3(glm::cos(rot)*4.8, glm::cos(rot/3)*1.3+ 1.3 ,glm::sin(rot)*2.9),
glm::vec3(0,0,0),
glm::vec3(0,1,0));
MVP = Projection * View * Model;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
...
I expected to see a blurred version of the input texture, instead it looks awful:
The jagged edges on the bottom side of the "1" makes no sense to me at all. They appear on some of the figures in the texture, but not others.
The input texture format is .DDS, could that somehow be the source of the problem? Could it be a bug in my driver? I am on Ubuntu Linux 16.04, with the newest drivers as found in the PPA:s. Searched online, found nothing on this topic.
edit: I also experimented with some openGL settings, like this:
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
GLfloat anisoVal;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisoVal);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoVal);
but it did nothing.

The source of the problem was an old driver. The computer I was working on had a special setup where non-standard PPAs had replaced the ubuntu (Canonical) supported ones. I could not access some of those outside of a special intra-net (at customer). Didnt read the error messages at sudo apt-get update.
The lesson from my question: The sort of bugs that can arise, and how they can bite you is unpredictable if you do not update your graphics drivers.... even if you think you have updated them.... double and tripple check. Thanks to #derhass and #Rabbid76 for leaving helpful remarks.

Related

Shadow acne on Nvidia graphics card

A partner and I are working on a small demo in OpenGL. We are doing simple shadow mapping. He uses an ATI and Intel HD graphics 4000 and everything works fine. I use a GTX 560 TI and get shadow acne although we use the same code.
When I'm moving the whole shadow is flickering. To set up the depth buffer of our framebuffer we do the following:
glBindTexture(GL_TEXTURE_2D,_t_depth->name());
glTexImage2D(
GL_TEXTURE_2D,0,
GL_DEPTH_COMPONENT32,
width,height,
0, GL_DEPTH_COMPONENT, GL_FLOAT,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D,0);
glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,_t_depth->name(),0);
The relevant part of the vertex shader is:
uniform mat4 u_lightspace_MVP;
layout(location=0) in vec3 v_position;
...
vec4 shadowcoord_x=u_lightspace_MVP*vec4(v_position,1.0);
shadowcoord_x/=shadowcoord_x.w;
The relevant part of the fragment shader is:
if (texture(s_shadowMap,shadowcoord_x.xy).r>shadowcoord_x.z-0.0001)
I have tried different bias values but either it doesn't affect the acne or there is no shadow at all. I also tried to use sampler2DShadow with textureProj() and texture() as the lookup function. Nothing seems to work. This issue doesn't only affect the shadows but also the volumetric lighting effect where shadowmaps are also used.
On the other hand clipping with gl_ClipDistance works fine on my Nvidia but not on his graphic cards.
After further trial and error approaches I finally got rid of the acne. The only thing I had to do was to halve the precision of the shadow map from 32bit to 16bit. The initialization looks like this now:
glBindTexture(GL_TEXTURE_2D,_t_depth->name());
glTexImage2D(
GL_TEXTURE_2D,0,
GL_DEPTH_COMPONENT16,
width,height,
0, GL_DEPTH_COMPONENT, GL_FLOAT,0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D,0);
glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,_t_depth->name(),0);
Now I'm also using sampler2DShadow and textureProj() in the fragment shader for depth testing and everything works fine.
Still I'm curious why it didn't work with 32 bit on my Nvidia but on an ATI.

glPoint Alpha Blending issue

I am having issues alpha blending glPoints. The alpha blending works correctly when the glPoint is over the background but when a glPoint overlaps another glPoint the background color is visible rather then the underlying glPoint.
// create texture
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
// Draw
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, tex);
....
glDrawArrays(GL_POINTS, 0, numberOfPoints);
// Frag Shader
uniform sampler2D Texture;
void main(void)
{
gl_FragColor = texture2D(Texture, gl_PointCoord);
}
What am i doing wrong?
It looks like the depth test is causing your issues. What happens is, as you describe, a point in front is drawn first and the depth value is replaced. Then the point behind is rasterized but all the fragments fail the depth test so nothing more is rendered/blended.
As Andon M. Coleman pointed out, you really need to sort the fragments in order of depth for correct alpha blending (exact order independent transparency is currently impractical for particles although you could try some of the approximate techniques. averaging all colour using alpha values as a weight can give decent results too).
Especially for the particle density you have and the lack of variation among particles there probably won't be much difference between sorting and not sorting. In this case, make sure you draw all the opaque stuff first, with depth testing enabled and then draw the particles. You want to keep depth testing enabled so your particles aren't drawn when they're behind opaque things however you don't want them to obscure each other - you want to use the depth buffer for testing but not write depth values. For this, use glDepthMask

OpenGL - How to read Alpha from a texture

I want the alpha value to be read for each pixel from the texture, so that some pixels completely disappear. The texture file(targa format) does contain the proper alpha channel.
Screenshot: http://i43.tinypic.com/2i79s1x.png
Here are the options I am using:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGR, //changing GL_BGR to anything else doesn't do a thing :? also tried GL_BGRA.
GL_UNSIGNED_BYTE, targaImage);
I have also tried most of the combinations of parameters for the glBlendFunc but none achieves the effect, alhtough I might have skipped it. This is the one that gets the regular blending done right(based on the alpha from glColor):
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Rectangle drawing:
glColor4f(1,1,1,0.5);
mRect->Render();
If I set alpha to 1 it is fully opaque, but there is still white in the bottom right, meaning that the alpha is read from the texture but the white polygon beneath it is visible. So I need to make the polygon disappear somehow, but the texture to remain visible.
So that's how I achieve this in the picture. I have also experimented with this:
glAlphaFunc(GL_GREATER, 0.49);
glEnable(GL_ALPHA_TEST);
It only proves that the alpha of each ,,fragment'' of my rectangle is 0.5.
This texture file has a gradient that has full red around the blue circle in the middle, but the alpha goess from 0 in the top-left to full in the bottom-right(it's not the red color fading to white).
I would supply the whole code but it has more than 2k lines and I have split everything into classes, so I am just pulling out the parts I think are important.
Do I need my own shader to do this? I have only made my first contact with OpenGL and C++ a couple of weeks ago and I'm not into them yet, so if that's the solution I would appreciate a link to a tutorial that deals with alpha and GLSL.
Thank you :)
It looks like you're using the old, fixed function pipeline. With that you must properly configure the texture environment. Specifically you want the texture to modulate or replace the base color. Either is fine, but I presume replace mode is better suited for you.
After binding the texture set the mode using glTexEnvi, in your case specifically
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Also I want to remind you, that you actually must enable blending (glEnable(GL_BLEND);)
If you look at the reference page for glTexEnv I think you easily grasp how ridiculously complex the state space for the fixed function texture environment pipeline became. I strongly suggest you don't bother with it and go directly for using the programmable pipeline, i.e. fragment shaders. Yes, their learning curve is significantly steeper, but with shaders you can actually write something legible like
#version 330
uniform sampler3D sampler_albedo;
uniform sampler2D sampler_diffuse;
out vec4 outcolor;
main()
{
float albedo = texture(sampler_albedo, texcood);
vec4 diffuse = texture(sampler_diffuse, texcoord);
outcolor = mix(basecolor, diffuse.rgb, diffuse.a) * albedo;
}
instead of spending over 15 lines setting up the texture environment and register combiners.

OpenGL CubeMap Texture Dimensions

After struggling all weekend, I finally have a sphere reflecting its environment in OpenGL. It almost looks good. Problem is, certain features don't line up. I can't find much information on the topic of OpenGL sphere mapping, outside of a two page section in the Red Book and a few scattered, and mostly unfinished forum topics. Not sure it's necessary, but I included my code where I load the textures. After trial and error, I found that having symmetrical dimensions freom 0 to 512 gets the best results, but they still aren't perfect (and the dimensions have to be powers of two, or it crashes). Does any one know of any strategies to get textures that line up more correctly?
void loadCubemapTextures(){
glGenTextures(1, &cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glDrawBuffer(GL_AUX1);
glReadBuffer(GL_AUX1);
glMatrixMode(GL_MODELVIEW);
//Generate cube map textures
for(int i = 0; i < 6; i++){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//Viewing Transformation
gluLookAt(pos[0], pos[1], pos[2],
view_pos[i][0], view_pos[i][1], view_pos[i][2],
top[i][0], top[i][1], top[i][2]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, 1.0, cubemapRadius + 1, 200.0);
glMatrixMode(GL_MODELVIEW);
render();
glCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, 0, 0, 256, 256, 0);
}
Your walls lack enough features to make their orientation and location clear, but I would bet those are the issue.
The values you have in view_pos and top are what define those. Among the things that look suspicious:
the black at the bottom of the shere comes from the face that captured the front view. It should be at the top (ie it's either flipped, or rotated 180).
likewise, the black that comes from the back of the view (in the center of the sphere) looks turned by a quarter of a circle (as black goes on the left rather than being on the top).
the reflection of the map sphere looks weird. It lacks resolution to figure out exactly what this is.
Anyways, to fix it, you can either make sure your values are what is expected from a proper cube-map definition (as in check all the specification), or just do a bunch of trial and error, after adding enough geometry to figure out what the orientation of each face is.
The problem had nothing to do with coordinates, thanks for the input though. I had forgotten to set the view matrix... a simple call to gluViewport inside the for-loop fixed it for me.

texture on cube-side with opengl

hello i want to use a texture on a cube (created by glutsolidcube()), how can i define where the texture is pictured at?
(for example on the "frontside" of a cube)
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
glColor4f(0.8,0.7,0.11,1.0);
glPushMatrix();
glScalef(4, 1.2, 1.5);
glTranslatef( 0, 0.025, 0);
glutSolidCube(0.1);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
thanks
Not possible, since glutSolidCube() only generates vertexes and normals, not texture coordinates.
However, there are workarounds.
Unfortunately, using glutSolidCube is impossible, as it doesn't support texturing. What I'd suggest is a tutorial that explains the process that may help you. It's a bit outdated, but NeHe's texturing tutorial has some code that explains how to draw a cube, and the code is commented to explain which side is which for you.