Re: Difficulty with the shaders tutorial
Nicolas Rougier <[email protected]>
| Newsgroups | gmane.comp.python.opengl.user |
|---|---|
| Message-ID | <[email protected]> |
No need to go for OpenGL 3.0 to use shaders.
Here is code that do what you want (translated from glumpy):
Color are transformed using the alpha channel of the image (see fragment code) and the color lookup table is a 1d texture. Fill it with any color sequence you want.
Nicolas
On Feb 16, 2012, at 20:09 , Derakon wrote:
> On further investigation, those functions weren't available because I
> didn't have an OpenGL context yet. My bad. Moving the set-up to later
> on in the program (the first paint call) instead gives these errors:
>
> RuntimeError: ('Shader compile failure (0): 0(3) : error C7533: global
> variable gl_ModelViewProjectionMatrix is deprecated after version
> 120\n0(3) : error C7533: global variable gl_Vertex is deprecated after
> version 120\n', ['#version 330\n void main() {\n
> gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n
> }'], GL_VERTEX_SHADER)
>
> Feel free to correct me, but it looks like this means that the
> tutorial is using deprecated concepts? GL_VERSION is 3.3.0 and
> GL_SHADER_VERSION is "3.30 NVIDIA via Cg compiler", for what it's
> worth.
>
> -Chris
>
> On Thu, Feb 16, 2012 at 10:05 AM, Derakon <[email protected]> wrote:
>> I'm trying to figure out OpenGL 3. Well, really I'm trying to figure
>> out fragment shaders so I can do a false-color filter for my
>> monochrome camera displays, but the fragment shader tutorial is also
>> an OpenGL 3 tutorial, so it's off the deep end I go. I took a look at
>> the shaders tutorial:
>> http://pyopengl.sourceforge.net/context/tutorials/shader_1.xhtml
>>
>> The first problem I run into is literally a context problem: I have no
>> idea what the high-level structure of the tutorial is because it's
>> broken up into chunks of a few lines at a time separated by
>> explanatory text. That'd be fine if the script were repeated without
>> those interruptions at some point, or if the chunks of program were
>> bigger, but as it stands the code part of the tutorial is very hard to
>> read.
>>
>> The second problem I have is also a context problem: OpenGLContext
>> doesn't exist for me. I have a standard Windows Python 2.7 / PyOpenGL
>> / numpy install. Fortunately I have some prior experience with OpenGL
>> and guess that I can work around this by using WX rendering contexts
>> instead. So I adapt the tutorial script to this standalone program:
>> http://pastebin.com/KWwi1Ahi
>>
>> However, when I run this, I get the following error when the first
>> call to shaders.compileShader is made:
>> OpenGL.error.NullFunctionError: Attempt to call an undefined alternate
>> function (glCreateShader, glCreateShaderObjectARB), check for
>> bool(glCreateShader) before calling
>>
>> Amusingly, calling glGetBoolean(glCreateShader) throws *another* error:
>> KeyError: ('Unknown specifier
>> <OpenGL.platform.baseplatform.glCreateShader object at
>> 0x00000000031360F0>', 'Failure in cConverter
>> <OpenGL.converters.SizedOutput object at 0x0000000002E27748>',
>> (<OpenGL.platform.baseplatform.glCreateShader object at
>> 0x00000000031360F0>,), 1, <OpenGL.wrapper.glGetIntegerv object at
>> 0x000000000305D4C8>)
>>
>> -Chris
>
> ------------------------------------------------------------------------------
> Virtualization & Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> PyOpenGL Homepage
> http://pyopengl.sourceforge.net
> _______________________________________________
> PyOpenGL-Users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/pyopengl-users
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
PyOpenGL Homepage
http://pyopengl.sourceforge.net
_______________________________________________
PyOpenGL-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyopengl-users
glut-colorizer.py
(text/x-python-script, 5.9 KB)
import os, sys, ctypes
import numpy as np
import OpenGL.GL as gl
import OpenGL.GLUT as glut
class ShaderException(Exception):
pass
class Shader:
def __init__(self, vertex_code = None, fragment_code = None):
self.uniforms = {}
self.handle = gl.glCreateProgram()
self.linked = False
self._build_shader(vertex_code, gl.GL_VERTEX_SHADER)
self._build_shader(fragment_code, gl.GL_FRAGMENT_SHADER)
self._link()
def _build_shader(self, strings, shader_type):
count = len(strings)
if count < 1:
return
shader = gl.glCreateShader(shader_type)
gl.glShaderSource(shader, strings)
gl.glCompileShader(shader)
status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS)
if not status:
if shader_type == gl.GL_VERTEX_SHADER:
raise (ShaderException,
'Vertex compilation: ' + gl.glGetShaderInfoLog(shader))
elif shader_type == gl.GL_FRAGMENT_SHADER:
raise (ShaderException,
'Fragment compilation:' + gl.glGetShaderInfoLog(shader))
else:
raise (ShaderException,
gl.glGetShaderInfoLog(shader))
else:
gl.glAttachShader(self.handle, shader)
def _link(self):
gl.glLinkProgram(self.handle)
temp = ctypes.c_int(0)
gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, ctypes.byref(temp))
if not temp:
gl.glGetProgramiv(self.handle,
gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp))
log = gl.glGetProgramInfoLog(self.handle)
raise(ShaderException, 'Linking: '+ log)
else:
self.linked = True
def bind(self):
gl.glUseProgram(self.handle)
def unbind(self):
gl.glUseProgram(0)
def uniformf(self, name, *vals):
loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
self.uniforms[name] = loc
if len(vals) in range(1, 5):
{ 1 : gl.glUniform1f,
2 : gl.glUniform2f,
3 : gl.glUniform3f,
4 : gl.glUniform4f
}[len(vals)](loc, *vals)
def uniformi(self, name, *vals):
loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
self.uniforms[name] = loc
if len(vals) in range(1, 5):
{ 1 : gl.glUniform1i,
2 : gl.glUniform2i,
3 : gl.glUniform3i,
4 : gl.glUniform4i
}[len(vals)](loc, *vals)
def uniform_matrixf(self, name, mat):
loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
self.uniforms[name] = loc
gl.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))
def display():
gl.glClearColor(1,1,1,1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glEnable(gl.GL_BLEND)
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glColor(1,1,1,1)
gl.glEnable( gl.GL_TEXTURE_1D )
gl.glActiveTexture( gl.GL_TEXTURE1 )
gl.glBindTexture( gl.GL_TEXTURE_1D, lut_id)
gl.glEnable( gl.GL_TEXTURE_2D )
gl.glActiveTexture( gl.GL_TEXTURE0 )
gl.glBindTexture( gl.GL_TEXTURE_2D, image_id)
# gl.glTexSubImage2D (gl.GL_TEXTURE_2D, 0, 0, 0,
# 512, 512, gl.GL_ALPHA, gl.GL_FLOAT, image)
shader.bind()
shader.uniformi('texture', 0)
shader.uniformi('lut', 1)
gl.glBegin(gl.GL_QUADS)
gl.glTexCoord2f(0, 1), gl.glVertex2i(0, 0)
gl.glTexCoord2f(0, 0), gl.glVertex2i(0, 512)
gl.glTexCoord2f(1, 0), gl.glVertex2i(512, 512)
gl.glTexCoord2f(1, 1), gl.glVertex2i(512, 0)
gl.glEnd()
shader.unbind()
glut.glutSwapBuffers()
def reshape(width,height):
gl.glViewport(0, 0, width, height)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(0, width, 0, height, -1, 1)
gl.glMatrixMode(gl.GL_MODELVIEW)
def keyboard( key, x, y ):
if key == '\033':
sys.exit( )
if __name__ == '__main__':
glut.glutInit(sys.argv)
glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH)
glut.glutCreateWindow('glut-colorizer')
glut.glutReshapeWindow(512,512)
glut.glutDisplayFunc(display)
glut.glutReshapeFunc(reshape)
glut.glutKeyboardFunc(keyboard )
fragment = """
uniform sampler2D texture;
uniform sampler1D lut;
void main()
{
vec2 uv = gl_TexCoord[0].xy;
vec4 color = texture2D(texture, uv);
gl_FragColor = texture1D(lut,color.a);
}"""
vertex = """
void main()
{
gl_FrontColor = gl_Color;
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
}"""
shader = Shader(vertex,fragment)
# Image to be displayed
image = np.random.uniform(0,1,(64,64)).astype(np.float32)
image_id = gl.glGenTextures(1)
gl.glEnable(gl.GL_TEXTURE_2D)
gl.glBindTexture(gl.GL_TEXTURE_2D, image_id)
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA32F_ARB, 64, 64, 0,
gl.GL_ALPHA, gl.GL_FLOAT, image)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
# Color lookup table (R,G,B)
lut = np.zeros((512,3)).astype(np.float32)
lut[:,0] = np.linspace(0,1,512)
lut[:,1] = np.linspace(1,0,512)
lut[:,2] = .5
lut_id = gl.glGenTextures(1)
gl.glEnable(gl.GL_TEXTURE_1D)
gl.glBindTexture(gl.GL_TEXTURE_1D, lut_id)
gl.glTexImage1D(gl.GL_TEXTURE_1D, 0, gl.GL_RGB, 512, 0,
gl.GL_RGB, gl.GL_FLOAT, lut)
gl.glTexParameterf(gl.GL_TEXTURE_1D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
gl.glTexParameterf(gl.GL_TEXTURE_1D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
glut.glutMainLoop()