Friday, January 19, 2018

python - How do I sort with both depth and y-axis in OpenGL?


Continuing my misadventures in pyOpenGL, I've refactored the whole thing to use 4 buffers:



  1. tile vertices - all drawn at the start, probably never modified

  2. tile texture co-ords - not modified often (but enables support for animated tiles later)

  3. sprite vertices - modified often as sprites move around the map

  4. sprite texture co-ords - modified often as sprites animate


My draw loop binds each buffer, and calls drawArrays() twice. I have enabled depth testing, and clear the depth buffer on each draw:


glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH)

...
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

For the moment, I've hard-coded the z coordinate for each of the things I'm drawing, just to be sure they're definitely in the right order - grass tiles are at 0.9, the tree (4 tiles) is set to -1.0 and the sprites are at 0.0. This is what I get:


sprites occluded by grass tiles


In a previous attempt to build this engine without openGL, I was using Tkinter canvas images, which ended up very slow. To get the draw order right, I had to sort all the objects by their y-coordinate plus their z-coordinate, because it is all on a 2D plane. I want something similar, here. I don't understand why the grass tiles cause this problem, when they should be drawn right at the back. GL_DEPTH_TEST is definitely enabled - if I disable it by commenting out the glEnable() call, the sprites are drawn on top of everything (including on top of the trees). I want an illusion of depth by being able to walk behind high-sticking-up objects.





I've continued hacking away at this, and I've gotten a little further by modifying my shader:


fragment_shader = shaders.compileShader("""
uniform sampler2D u_image;

varying vec2 v_texCoords;

void main()
{
vec4 tex = texture2D(u_image, v_texCoords);
if(tex.a < 1.0)

discard;
gl_FragColor = tex; //texture2D(u_image, v_texCoords);
}
""", GL_FRAGMENT_SHADER)

By checking for transparent pixels and throwing them away, I get a lot closer to my goal, however it is still not quite right, and I do not know how to fix it.


Transparency from the shader enter image description here enter image description here


The wizard is at z:-0.5, and the tree trunk is at z:-0.2; it is doing what I'm telling it to do, just not what I want it to do. If I put them on the same z-level, the trunk is drawn over the wizard when he stands in front of the tree, and correctly when he stands behind it:


enter image description here


I don't just want depth sorting, I also want to sort on the y-axis. How can I do this in OpenGL?





No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...