Re: Depth buffer attachment problem [SOLVED]
Nicolas Rougier <[email protected]> Tue, 25 Feb 2014 13:12:12 +0100
| Newsgroups | gmane.comp.python.opengl.user |
|---|---|
| Message-ID | <[email protected]> |
I found the bug. I was not re-setting attributes between calls to the two different program that lead to the weird behaviour. It also fixed my framebuffer problem. Now I understand the utility of VAO... Sorry for the noise. Here is the corrected version. Nicolas On 25 Feb 2014, at 12:19, Nicolas Rougier <[email protected]> wrote: > > > I investigated furthermore and my problem may come from my misunderstanding on vertex/index buffers. I attach an simple example where 2 programs are built (cube and quad): > > - cube is a rotating cube using vcube and icube (vertex and index buffer) and TRIANGLES. > - quad is a simple quad using vquad (vertex buffer) and TRIANGLE_STRIP. > > In the "display" method, one can choose to display the rotating cube (if 1) or the quad (if 0). > The rotating cube runs fine on my machine but the quad display does not. It is like the quad is using the cube vertex buffer and the display appears broken (cube vertices have been divided by 2 and it impacts the quad). It's very similar to the bug I first reported here and this makes me think there's no connection with the framebuffer. > > > Also, the quad seems to be able to use the cube texture information while I did not set the "u_texture" information in that program. Obviously I'm doing something wrong but I can't see it. Finally, binding the texture (see line #DEBUG) blacks out the texture. A lot of weird things are happening indeed. > > Any help appreciated. > > > Nicolas > > > > > <fbo-glut.py> > > The texture can be downloaded from: http://www.loria.fr/~rougier/tmp/crate.npy > > > > > On 25 Feb 2014, at 10:51, Nicolas Rougier <[email protected]> wrote: > >> >> 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 >> >> >> >> <fbo-glut.py> >> >> >> >> >> 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 > > ------------------------------------------------------------------------------ > 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, 11.1 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 makecube():
""" 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
cube_vertex = """
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;
}
"""
cube_fragment = """
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = texture2D(u_texture, v_texcoord);
}
"""
quad_vertex = """
attribute vec2 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
void main()
{
gl_Position = vec4(a_position, 0.0, 1.0);
v_texcoord = a_texcoord;
}
"""
quad_fragment = """
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
if( v_texcoord.x > 0.5 )
gl_FragColor = texture2D(u_texture, v_texcoord);
else
gl_FragColor = vec4(vec3(.25),1.0) + 0.75*texture2D(u_texture, v_texcoord);
}
"""
def display():
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
if 1:
gl.glUseProgram(cube)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vcube)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, icube)
stride = vcube_data.strides[0]
offset = ctypes.c_void_p(0)
loc = gl.glGetAttribLocation(cube, "a_position")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, stride, offset)
offset = ctypes.c_void_p(vcube_data.dtype["a_position"].itemsize)
loc = gl.glGetAttribLocation(cube, "a_texcoord")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
gl.glDrawElements(gl.GL_TRIANGLES, icube_data.size, gl.GL_UNSIGNED_INT, None)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
gl.glUseProgram(0)
else:
gl.glUseProgram(quad)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vquad)
stride = vquad_data.strides[0]
offset = ctypes.c_void_p(0)
loc = gl.glGetAttribLocation(quad, "a_position")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
offset = ctypes.c_void_p(vquad_data.dtype["a_position"].itemsize)
loc = gl.glGetAttribLocation(quad, "a_texcoord")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
gl.glUseProgram(0)
glut.glutSwapBuffers()
def reshape(width,height):
gl.glViewport(0, 0, width, height)
gl.glUseProgram(cube)
projection = perspective( 35.0, width/float(height), 2.0, 10.0 )
loc = gl.glGetUniformLocation(cube, "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(cube)
loc = gl.glGetUniformLocation(cube, "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 quad program
# --------------------------------------
quad = gl.glCreateProgram()
vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
gl.glShaderSource(vertex, quad_vertex)
gl.glShaderSource(fragment, quad_fragment)
gl.glCompileShader(vertex)
gl.glCompileShader(fragment)
gl.glAttachShader(quad, vertex)
gl.glAttachShader(quad, fragment)
gl.glLinkProgram(quad)
gl.glDetachShader(quad, vertex)
gl.glDetachShader(quad, fragment)
gl.glUseProgram(quad)
# Get data & build quad buffers
# --------------------------------------
dtype = [('a_position', np.float32, 2), ('a_texcoord', np.float32, 2)]
vquad_data = np.zeros(4, dtype=dtype)
vquad_data["a_position"] = [ (-1,-1), (-1,+1), (+1,-1), (+1,+1) ]
vquad_data["a_texcoord"] = [ ( 0, 0), ( 0, 1), ( 1, 0), ( 1, 1) ]
vquad_data["a_position"] = 0 # DEBUG: this shoudl result in no fragment at all
vquad_data["a_texcoord"] = 0 # DEBUG: this shoudl result in no fragment at all
vquad = gl.glGenBuffers(1)
print("quad vertices buffer name is: %d" % vquad)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vquad)
gl.glBufferData(gl.GL_ARRAY_BUFFER, vquad_data.nbytes, vquad_data, gl.GL_STATIC_DRAW)
# Bind quad attributes
# --------------------------------------
stride = vquad_data.strides[0]
offset = ctypes.c_void_p(0)
loc = gl.glGetAttribLocation(quad, "a_position")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
offset = ctypes.c_void_p(vquad_data.dtype["a_position"].itemsize)
loc = gl.glGetAttribLocation(quad, "a_texcoord")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
# Build & activate cube program
# --------------------------------------
cube = gl.glCreateProgram()
vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
gl.glShaderSource(vertex, cube_vertex)
gl.glShaderSource(fragment, cube_fragment)
gl.glCompileShader(vertex)
gl.glCompileShader(fragment)
gl.glAttachShader(cube, vertex)
gl.glAttachShader(cube, fragment)
gl.glLinkProgram(cube)
gl.glDetachShader(cube, vertex)
gl.glDetachShader(cube, fragment)
gl.glUseProgram(cube)
# Get data & build cube buffers
# --------------------------------------
vcube_data, icube_data = makecube()
# DEBUG: this result in quad resizing, this should not (quad is supposed to use vquad)
vcube_data["a_position"] *= 0.5
vcube = gl.glGenBuffers(1)
print("cube vertices buffer name is: %d" % vcube)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vcube)
gl.glBufferData(gl.GL_ARRAY_BUFFER, vcube_data.nbytes, vcube_data, gl.GL_STATIC_DRAW)
icube = gl.glGenBuffers(1)
print("cube indices buffer name is: %d" % icube)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, icube)
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, icube_data.nbytes, icube_data, gl.GL_STATIC_DRAW)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
# Bind cube attributes
# --------------------------------------
stride = vcube_data.strides[0]
offset = ctypes.c_void_p(0)
loc = gl.glGetAttribLocation(cube, "a_position")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, stride, offset)
offset = ctypes.c_void_p(vcube_data.dtype["a_position"].itemsize)
loc = gl.glGetAttribLocation(cube, "a_texcoord")
gl.glEnableVertexAttribArray(loc)
gl.glVertexAttribPointer(loc, 2, gl.GL_FLOAT, False, stride, offset)
# Create & bind cube texture
# --------------------------------------
crate = np.load("crate.npy")
texture = gl.glGenTextures(1)
gl.glActiveTexture(gl.GL_TEXTURE0)
# BUG: Does not work if put here
# 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(cube, "u_texture")
gl.glUniform1i(loc, texture)
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
# Create & bind cube 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(cube, "u_model")
gl.glUniformMatrix4fv(loc, 1, False, model)
loc = gl.glGetUniformLocation(cube, "u_view")
gl.glUniformMatrix4fv(loc, 1, False, view)
loc = gl.glGetUniformLocation(cube, "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()