Re: Depth buffer attachment problem

Nicolas Rougier <[email protected]> Tue, 25 Feb 2014 10:51:32 +0100
Newsgroups gmane.comp.python.opengl.user
Message-ID <[email protected]>
While trying to write a strip-down example, I accidentally reproduced the same kind of output using GL_TRIANGLE_TRIP instead of GL_TRIANGLES. Here is the source (which doesn't work as expected using the indices buffer: no output).

That le me think I may have introduced the same kind of bug in the other source. I'm still investigating why the index buffer doesn't work (and texture actually). I didn't thoroughy check for errors yet, pardon me if it is very obvious...


(The crate.npy is a 256x256 RGB texture stored as a numpy array. You'll need to replace it or discard it.)


Nicolas






On 25 Feb 2014, at 10:01, rndblnch <[email protected]> wrote:

> Nicolas Rougier <Nicolas.Rougier <at> inria.fr> writes:
> 
>> First image is direct rendering (no framebuffer) and is ok. Second image
> is indirect rendering (rendering
>> to texture then displaying the texture, the left washed-out part is ok, it
> comes from the fragment shader
>> for testing purposes).
>> 
>> I suspect the depth buffer is not really attached but I did not get any
> error along the way.
> 
> did you clear the depth buffer between the binding of the FBO and the rendering?
> 
> the code (even with dependencies) would help for analysis.
> 
> renaud
> 
> 
> 
> 
> ------------------------------------------------------------------------------
> Flow-based real-time traffic analytics software. Cisco certified tool.
> Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
> Customize your own dashboards, set traffic alerts and generate reports.
> Network behavioral analysis & security monitoring. All-in-one tool.
> http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
> _______________________________________________
> PyOpenGL Homepage
> http://pyopengl.sourceforge.net
> _______________________________________________
> PyOpenGL-Users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/pyopengl-users

------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk

_______________________________________________
PyOpenGL Homepage
http://pyopengl.sourceforge.net
_______________________________________________
PyOpenGL-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyopengl-users
fbo-glut.py (text/x-python-script, 8 KB)
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2014, Nicolas P. Rougier. All rights reserved.
# Distributed under the terms of the new BSD License.
# -----------------------------------------------------------------------------
import sys
import math
import ctypes
import numpy as np
import OpenGL.GL as gl
import OpenGL.GLUT as glut


def rotate(M, angle, x, y, z, point=None):
    angle = math.pi * angle / 180
    c, s = math.cos(angle), math.sin(angle)
    n = math.sqrt(x * x + y * y + z * z)
    x /= n
    y /= n
    z /= n
    cx, cy, cz = (1 - c) * x, (1 - c) * y, (1 - c) * z
    R = np.array([[cx * x + c, cy * x - z * s, cz * x + y * s, 0],
                  [cx * y + z * s, cy * y + c, cz * y - x * s, 0],
                  [cx * z - y * s, cy * z + x * s, cz * z + c, 0],
                  [0, 0, 0, 1]], dtype=M.dtype).T
    M[...] = np.dot(M, R)
    return M

def translate(M, x, y=None, z=None):
    y = x if y is None else y
    z = x if z is None else z
    T = np.array([[1.0, 0.0, 0.0, x],
                  [0.0, 1.0, 0.0, y],
                  [0.0, 0.0, 1.0, z],
                  [0.0, 0.0, 0.0, 1.0]], dtype=M.dtype).T
    M[...] = np.dot(M, T)
    return M

def frustum(left, right, bottom, top, znear, zfar):
    M = np.zeros((4, 4), dtype=np.float32)
    M[0, 0] = +2.0 * znear / (right - left)
    M[2, 0] = (right + left) / (right - left)
    M[1, 1] = +2.0 * znear / (top - bottom)
    M[3, 1] = (top + bottom) / (top - bottom)
    M[2, 2] = -(zfar + znear) / (zfar - znear)
    M[3, 2] = -2.0 * znear * zfar / (zfar - znear)
    M[2, 3] = -1.0
    return M

def perspective(fovy, aspect, znear, zfar):
    h = math.tan(fovy / 360.0 * math.pi) * znear
    w = h * aspect
    return frustum(-w, w, -h, h, znear, zfar)


def cube():
    """ Generate vertices & indices for a filled cube """

    vtype = [('a_position', np.float32, 3),
             ('a_texcoord', np.float32, 2)]
    itype = np.uint32

    # Vertices positions
    p = np.array([[ 1, 1, 1], [-1, 1, 1], [-1,-1, 1], [ 1,-1, 1],
                  [ 1,-1,-1], [ 1, 1,-1], [-1, 1,-1], [-1,-1,-1]])

    # Texture coords
    t = np.array([[0, 0], [0, 1], [1, 1], [1, 0]])

    faces_p = [0,1,2,3, 0,3,4,5, 0,5,6,1, 1,6,7,2, 7,4,3,2, 4,7,6,5]
    faces_t = [0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3]

    vertices = np.zeros(24,vtype)
    vertices['a_position'] = p[faces_p]
    vertices['a_texcoord'] = t[faces_t]

    indices = np.resize( np.array([0,1,2,0,2,3], dtype=np.uint32), 6*(2*3))
    indices += np.repeat( 4*np.arange(6), 6)

    return vertices, indices


vertex_code = """
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
attribute vec3 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
    gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0);
    v_texcoord = a_texcoord;
}
"""

fragment_code = """
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
    gl_FragColor = texture2D(u_texture, v_texcoord);
}
"""

def display():
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
    gl.glUseProgram(program)
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbuffer)
    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ibuffer)
    gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
    #gl.glDrawElements(gl.GL_TRIANGLES, ibuffer.size, gl.GL_UNSIGNED_INT, None)
    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
    gl.glUseProgram(0)
    glut.glutSwapBuffers()

def reshape(width,height):
    gl.glViewport(0, 0, width, height)
    gl.glUseProgram(program)
    projection = perspective( 35.0, width/float(height), 2.0, 10.0 )
    loc = gl.glGetUniformLocation(program, "u_projection")
    gl.glUniformMatrix4fv(loc, 1, False, projection)
    gl.glUseProgram(0)

def keyboard(key, x, y):
    if key == '\033': sys.exit( )

def timer(fps):
    global theta, phi
    theta += .5
    phi += .5
    model = np.eye(4, dtype=np.float32)
    rotate(model, theta, 0,0,1)
    rotate(model, phi, 0,1,0)
    gl.glUseProgram(program)
    loc = gl.glGetUniformLocation(program, "u_model")
    gl.glUniformMatrix4fv(loc, 1, False, model)
    gl.glUseProgram(0)
    glut.glutTimerFunc(1000/fps, timer, fps)
    glut.glutPostRedisplay()


# GLUT init
# --------------------------------------
glut.glutInit()
glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH)
glut.glutCreateWindow('Rotating cube')
glut.glutReshapeWindow(512,512)
glut.glutReshapeFunc(reshape)
glut.glutDisplayFunc(display)
glut.glutKeyboardFunc(keyboard)
glut.glutTimerFunc(1000/60, timer, 60)


# Build & activate program
# --------------------------------------
# Request a program and shader slots from GPU
program  = gl.glCreateProgram()
vertex   = gl.glCreateShader(gl.GL_VERTEX_SHADER)
fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)

# Set shaders source
gl.glShaderSource(vertex, vertex_code)
gl.glShaderSource(fragment, fragment_code)

# Compile shaders
gl.glCompileShader(vertex)
gl.glCompileShader(fragment)

# Attach shader objects to the program
gl.glAttachShader(program, vertex)
gl.glAttachShader(program, fragment)

# Build program
gl.glLinkProgram(program)

# Get rid of shaders (no more needed)
gl.glDetachShader(program, vertex)
gl.glDetachShader(program, fragment)

# Make program the default program
gl.glUseProgram(program)


# Get data & build buffer
# --------------------------------------
vertices, indices = cube()

# Request a buffer slot from GPU
vbuffer = gl.glGenBuffers(1)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbuffer)
gl.glBufferData(gl.GL_ARRAY_BUFFER, vertices.nbytes, vertices, gl.GL_STATIC_DRAW)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)

# Request a buffer slot from GPU
ibuffer = gl.glGenBuffers(1)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, ibuffer)
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, gl.GL_STATIC_DRAW)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
# print indices.size, indices.nbytes, indices.dtype

# Bind attributes
# --------------------------------------
stride = vertices.strides[0]
offset = ctypes.c_void_p(0)
loc = gl.glGetAttribLocation(program, "a_position")
gl.glEnableVertexAttribArray(loc)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbuffer)
gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, stride, offset)

offset = ctypes.c_void_p(vertices.dtype["a_position"].itemsize)
loc = gl.glGetAttribLocation(program, "a_texcoord")
gl.glEnableVertexAttribArray(loc)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbuffer)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)

# Create & bind texture
# --------------------------------------
crate = np.load("crate.npy")
texture = gl.glGenTextures(1)
gl.glBindTexture(gl.GL_TEXTURE_2D, texture)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, crate.shape[1], crate.shape[0],
                0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, crate)
loc = gl.glGetUniformLocation(program, "u_texture")
gl.glUniform1i(loc, texture)

# Create & bind matrices
# --------------------------------------
view = np.eye(4,dtype=np.float32)
model = np.eye(4,dtype=np.float32)
projection = np.eye(4,dtype=np.float32)
translate(view, 0,0,-7)
phi, theta = 60,20
rotate(model, theta, 0,0,1)
rotate(model, phi, 0,1,0)
loc = gl.glGetUniformLocation(program, "u_model")
gl.glUniformMatrix4fv(loc, 1, False, model)
loc = gl.glGetUniformLocation(program, "u_view")
gl.glUniformMatrix4fv(loc, 1, False, view)
loc = gl.glGetUniformLocation(program, "u_projection")
gl.glUniformMatrix4fv(loc, 1, False, projection)

# OpenGL initalization
# --------------------------------------
gl.glClearColor(0.30, 0.30, 0.35, 1.00)
gl.glEnable(gl.GL_DEPTH_TEST)

# Enter mainloop
# --------------------------------------
glut.glutMainLoop()