Continuing my misadventures in pyOpenGL, I've refactored the whole thing to use 4 buffers:
- tile vertices - all drawn at the start, probably never modified
- tile texture co-ords - not modified often (but enables support for animated tiles later)
- sprite vertices - modified often as sprites move around the map
- 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:
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.
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:
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