Problem with seeing through textures with alpha

Started by isaacais, April 25, 2013, 23:10:01

Previous topic - Next topic

isaacais

I am new to this forums, but I am not new to Java, and I have been working with LWJGL for around 2 months.  I am making a Minecraft clone right now, and I have found a problem that I can't seem to figure out.  I am rendering leaves, which are see through.  They are not looking the way I want them to look in some places.  The best explanations are shown through screenshots.  Here are some examples of the problems:

Notice how there are strips of the color of the sky when you look through see-through blocks.


This is what a block looks like through the ground when you look in the opposite direction.  You can see other sides besides the top side of the block.  There aren't any strips of the sky's color either.  At the bottom right you can see part of a strip of the sky's color.


This is another problem, you can see a face of a block through one texture, but not the other.


I have been trying to figure this problem out for around a week, so I came to this forum to see if I could get any help from experts.  Does anyone have any idea why this is happening to me?  Thanks for the help!

quew8

We are probably going to need some more information. (You have no idea how much better it is to read code than make random lunges into the cold dark). Specifically the code encompassing: setting up OpenGl state, rendering, any hidden face removal you may do (and maybe any other rendering optimizations you do) shaders if you use them.
Also personally, I'm not sure I quite understand your first problem (you're sure you mean transparent and not translucent?). As far as minecraft is concerned, I would expect to see patches of sky looking through a leaves block.

broumbroum

With transparent textures, the problem arises when the rendering passes overlap each other.  Although you could enable depth testing (which is the case I believe) and alpha test, it's not worthful for we have to deal within the cube objects, that testing is not possible. It's clear that you have to render things that are in the background first in the loop, before to continue rendering on the foreground. I don't know very much what the minecraft code looks like, anyway. ;)

The easy way, check if any one of the "rocky" cube faces in gray are rendered _after_ the green grass patches. That would be the reason why the blue sky appears instead of the gray.

isaacais

In response to quew8, I do not use any shaders, and the first problem is where there are walls that are being rendered by leaves that can only be seen through leaves, which I don't understand.  I've tried making right, left, front, and back walls of blocks not rendered, but you can still see walls the color of the sky by looking through the top of the leaves.  Also, this is my code for setting up the OpenGL state:
      customCamera.applyGLStuff();
      glEnable(GL_DEPTH_TEST);
      glDepthFunc(GL_LEQUAL);
      if(culling)
      {
         glEnable(GL_CULL_FACE);
         glCullFace(GL_BACK);
      }
      else
      {
         glDisable(GL_CULL_FACE);
      }
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glGetFloat(GL_PROJECTION_MATRIX, perspectiveProjectionMatrix);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 0, -1);
      glGetFloat(GL_PROJECTION_MATRIX, orthographicProjectionMatrix);
      glLoadMatrix(perspectiveProjectionMatrix);
      glMatrixMode(GL_MODELVIEW);
      glDisable(GL_TEXTURE_2D);
      Textures.init();
In the camera class, the applyGLStuff method:
      glViewport(0, 0, Display.getWidth(), Display.getHeight());
      if (GLContext.getCapabilities().GL_ARB_depth_clamp)
      {
         glEnable(GL_DEPTH_CLAMP);
      }
      glPushAttrib(GL_TRANSFORM_BIT);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      aspectRatio = (float) (Display.getWidth()) / (float) (Display.getHeight());
      GLU.gluPerspective(fov, aspectRatio, zNear, renderDistance);
      glPopAttrib();
Also, I learned how to use most of this stuff off of thecodinguniverse.
Now, I my hidden face removal is very long, so I don't know where to put it.  I have tried tweaking the hidden face removal many times, and it doesn't make any difference to my problems.

In response to broumbroum, I am sure I have enabled the depth testing function LEQUAL, and I do not know what alpha test is.  I have looked at Minecraft's code a lot, and even modded it a bit.  Why would I need to test if the leaves' faces are rendering after the opaque blocks?  And it is not grass, I do have grass, but I switched the world generation to use leaves for testing purposes.  Also, another thing to note is that this terrain is basically a huge tub of leaves with dirt around it and below it (in response to another part of quew8's statement about expecting to see sky through leaves), and trees on top of it.

I hope that I helped you answer my question, thankyou for responding!

EDIT: I forgot to mention something, I use vertex arrays for rendering (I put the verticies of each block from each section of the world into 3 buffers, vertex, color, and texture), and here is my code for rendering each section of the world:
      glPushMatrix();
      glEnable(GL_TEXTURE_2D);
      Textures.terrain.bind();
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTranslatef(posX, 0, posZ);
      glColor3f(1, 1, 1);
      
      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);
      
      glVertexPointer(3, 0, vertex);
      glTexCoordPointer(2, 0, texture);
      glColorPointer(4, 0, color);
      
      glDrawArrays(GL_QUADS, 0, verticies);
      
      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY);

      glDisable(GL_TEXTURE_2D);
      glPopMatrix();
Thanks in advance!

broumbroum

Quote from: isaacais on April 27, 2013, 17:12:51
...
In response to broumbroum, I am sure I have enabled the depth testing function LEQUAL, and I do not know what alpha test is.  I have looked at Minecraft's code a lot, and even modded it a bit.  Why would I need to test if the leaves' faces are rendering after the opaque blocks?  And it is not grass, I do have grass, but I switched the world generation to use leaves for testing purposes.  Also, another thing to note is that this terrain is basically a huge tub of leaves with dirt around it and below it (in response to another part of quew8's statement about expecting to see sky through leaves), and trees on top of it.

....
hi ,the opengl alpha test function is more or less like the stencil test function. Where the test passes or not, the fragment is drawn or it is blocked, resp. Hence alpha testing improves your code, since you are rendering in a three dimensional space, which includes POV movements and therefore the objects may be masked eventually, something you cannot check in realtime (unless you perform ray tracing, occlusion culling, don't you ??). here's the doc about common alpha testing : http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node96.html .:)

isaacais

"It's important to note, that if you wanted to use the glAlphaFunc() and glEnable(GL_ALPHA_TEST), sorting is not necessary. However, using the Alpha Function you are restricted to completely transparent or completely opaque blending, there is no in between. Sorting and using the Blendfunc() is a little more work, but it allows for semi-transparent objects." from http://nehe.gamedev.net/tutorial/picking_alpha_blending_alpha_testing_sorting/16005/
I want to have semi-transparent object.  Also, I am using BlendFunc, but it still isn't working.  My BlendFunction is here:
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
I am not sure if the blend function is being used correctly.  Thanks for your response!

broumbroum

(NeHe are a bit old tutos, so i don't recommend 'em.)
Blending should be ok with glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA). However, you might be looking for a _texture blending_ function which is often confusing with the blendfunc :
gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_BLEND);
see http://waltermilner.com/joglblogl/texblend.htm .
using the texEnv blending (which you can set to various "mixtures" like, I use it, GL_MODULATE ), you can do correct semi-transparent textured objects but sorted or use alphafunc (It must be ok with Minecraft textures, because there are either full transparent  or opaque pîxels, see pic attached).

black is transparent and the web isn't ...

isaacais

Thankyou for your response.  I tried everything listed on the page, but there was either distortion, or no change (GL_REPLACE and GL_MODULATE).  I am not sure why this is still happening.  Thanks!