Add 2d texture and GLSL shaders

This commit is contained in:
Runar Tenfjord 2012-10-28 08:44:16 +01:00
parent cad11d37e8
commit 8651f5c205
13 changed files with 506 additions and 181 deletions

View file

@ -16,6 +16,8 @@
extern char errorMessage[256];
void setErrorMessage(const char *err);
int glCheck();
// opengl font
extern void *_fonts;
int initText(void);
@ -56,6 +58,18 @@ static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
int initGLExt(void);
class TextureRect2D {
public:
GLuint m_id;
GLuint m_width;
GLuint m_height;
GLuint m_depth;
TextureRect2D(int width, int height, int depth, void *data);
~TextureRect2D();
void blit(float x, float y);
void copy(GLenum mode);
};
struct ClientBufferAttrib {
int enabled;
GLenum type;

View file

@ -19,6 +19,7 @@ cdef extern from "GLTools.h":
ctypedef ssize_t GLsizeiptr
char errorMessage[256]
int glCheck()
int stbi_write_png(char *filename, int w, int h, int comp, void *data, int stride_in_bytes)
@ -30,6 +31,14 @@ cdef extern from "GLTools.h":
int isGLExtLoaded
int c_initGLExt "initGLExt"()
cdef cppclass c_TextureRect2D "TextureRect2D":
GLuint m_width
GLuint m_height
GLuint m_depth
c_TextureRect2D(int width, int height, int depth, void *data)
void blit(float x, float y)
void copy(GLenum mode)
cdef cppclass c_ClientBuffer "ClientBuffer":
c_ClientBuffer(GLenum target)
void bind()

View file

@ -30,6 +30,7 @@ cdef extern from "GL/glfw3.h":
void glLightf(GLenum light, GLenum pname, GLfloat param)
void glLightfv(GLenum light, GLenum pname, GLfloat *params )
void glLightModeli(GLenum pname, GLint param)
void glLightModelfv(GLenum pname, GLfloat *params)
void glLoadIdentity()
void glLoadMatrixd(GLdouble *m)
void glMaterialfv(GLenum face, GLenum pname, GLfloat *params)
@ -245,6 +246,8 @@ cdef extern from "GL/glfw3.h":
GL_POINT
GL_LINE
GL_FILL
GL_POLYGON_OFFSET_LINE
GL_POLYGON_OFFSET_FILL
# ShadingModel
GL_FLAT

View file

@ -16,6 +16,9 @@ cdef class ClientBuffer:
raise GLError('OpenGL 2.1 function pointers not found')
self.thisptr = new c_ClientBuffer(target)
if not glCheck():
raise GLError(errorMessage)
def __dealloc__(self):
cdef c_ClientBuffer *tmp

View file

@ -143,6 +143,14 @@ cdef class Material:
mat[0] = fmin(fmax(0., self.shininess), 128)
glMaterialfv(self.mode, GL_SHININESS, mat)
cpdef ambientLight(ColorRGBA col):
'''
Set global ambient light color.
'''
cdef float c_col[4]
col.setFloatVector(c_col)
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c_col)
cdef class Light:
'''
Abstraction of OpenGL light

View file

@ -159,6 +159,8 @@ LINE_SMOOTH = GL_LINE_SMOOTH
POINT = GL_POINT
LINE = GL_LINE
FILL = GL_FILL
POLYGON_OFFSET_LINE = GL_POLYGON_OFFSET_LINE
POLYGON_OFFSET_FILL = GL_POLYGON_OFFSET_FILL
# ShadingModel
FLAT = GL_FLAT

View file

@ -14,6 +14,13 @@ cpdef InitGLExt():
'''
if not c_initGLExt():
raise GLError(errorMessage)
cpdef int Check():
'''
Check for OpenGL errors
'''
if not glCheck():
raise GLError(errorMessage)
cpdef BlendFunc(unsigned int sfactor, unsigned int dfactor):
'''
@ -86,7 +93,6 @@ cpdef DrawElements(unsigned int mode, int count, int type, indices):
try:
offset = indices
glDrawElements(mode, count, type, <void *>offset)
print
except TypeError:
glDrawElements(mode, count, type, getVoidPtr(indices))
@ -95,7 +101,7 @@ cpdef Enable(unsigned int cap):
Enable server-side GL capabilities
'''
glEnable(cap)
cpdef LineWidth(float width):
'''
Specify the width of rasterized lines

View file

@ -8,6 +8,38 @@ void setErrorMessage(const char *err) {
strncpy(errorMessage, err, 255);
}
int glCheck() {
switch(glGetError()) {
case GL_NO_ERROR:
return 1;
case GL_INVALID_ENUM:
setErrorMessage("GL_INVALID_ENUM");
break;
case GL_INVALID_VALUE:
setErrorMessage("GL_INVALID_VALUE");
break;
case GL_INVALID_OPERATION:
setErrorMessage("GL_INVALID_OPERATION");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
setErrorMessage("GL_INVALID_FRAMEBUFFER_OPERATION");
break;
case GL_OUT_OF_MEMORY:
setErrorMessage("GL_OUT_OF_MEMORY");
break;
default:
setErrorMessage("GL_UNKNOWN");
break;
}
return 0;
}
// load font
void *_fonts;
@ -178,6 +210,83 @@ int initGLExt(void)
return 1;
}
// opengl texture rectangle
TextureRect2D::TextureRect2D(int width, int height, int depth, void *data = NULL) {
GLint iformat, format;
m_width = width;
m_height = height;
m_depth = depth;
if (depth == 4) {
iformat = GL_RGBA8;
format = GL_RGBA;
} else {
iformat = GL_RGB8;
format = GL_RGB;
}
glGenTextures(1, &m_id);
glBindTexture(GL_TEXTURE_RECTANGLE, m_id);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (!data) {
char *colorBits = new char[width * height * depth];
memset(colorBits, 0, width * height * depth);
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, colorBits);
delete[] colorBits;
} else {
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, data);
}
glBindTexture(GL_TEXTURE_RECTANGLE, 0);
}
TextureRect2D::~TextureRect2D() {
glDeleteTextures(1, &m_id);
}
void TextureRect2D::blit(float x, float y) {
glEnable(GL_TEXTURE_RECTANGLE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE, m_id);
glColor3ub(255,255,255);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(x, y, 0);
glTexCoord2f(m_width, 0);
glVertex3f(x + m_width, y, 0);
glTexCoord2f(m_width, m_height);
glVertex3f(x + m_width, y + m_height, 0);
glTexCoord2f(0, m_height);
glVertex3f(x, y + m_height, 0);
glEnd();
glBindTexture(GL_TEXTURE_RECTANGLE, 0);
glDisable(GL_TEXTURE_RECTANGLE);
}
void TextureRect2D::copy(GLenum mode = GL_BACK) {
glReadBuffer(mode);
glEnable(GL_TEXTURE_RECTANGLE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE, m_id);
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE,0,0,0,0,0,m_width, m_height);
glBindTexture(GL_TEXTURE_RECTANGLE, 0);
glDisable(GL_TEXTURE_RECTANGLE);
}
// opengl buffer interface
ClientBuffer::ClientBuffer(GLenum target = GL_ARRAY_BUFFER) {
pglGenBuffers(1, &m_id);

View file

@ -23,7 +23,7 @@ cdef class ShaderProgram:
def __repr__(self):
return "()"
cpdef bint isValid(self):
'''
Return status
@ -94,4 +94,282 @@ cdef class ShaderProgram:
ret = prog.build(vertex_src, fragment_src)
if not ret:
raise GLError(errorMessage)
raise GLError(errorMessage)
@classmethod
def flat(cls):
cdef ShaderProgram ret = ShaderProgram()
ret.build(GLSL_VERTEX_FLAT, GLSL_FRAG_FLAT)
return ret
@classmethod
def pongDiffuse(cls, int lights):
cdef ShaderProgram ret = ShaderProgram()
if lights < 1 or lights > 8:
raise GLError('lights must be between 1 and 8')
INIT = "#define MAX_LIGHTS %d" % lights
FRAG_SRC = "\n".join((INIT, GLSL_FRAG_PONG_COMMON, GLSL_FRAG_PONG_DIFFUSE))
ret.build(GLSL_VERTEX_PONG, FRAG_SRC)
return ret
@classmethod
def pongSpecular(cls, int lights):
cdef ShaderProgram ret = ShaderProgram()
if lights < 1 or lights > 8:
raise GLError('lights must be between 1 and 8')
INIT = "#define MAX_LIGHTS %d" % lights
FRAG_SRC = "\n".join((INIT, GLSL_FRAG_PONG_COMMON, GLSL_FRAG_PONG_SPECULAR))
ret.build(GLSL_VERTEX_PONG, FRAG_SRC)
return ret
# simple flat shader for overlay & background
cdef char *GLSL_VERTEX_FLAT = \
"""
varying vec4 col;
void main(void)
{
col = gl_Color;
gl_Position = ftransform();
}
"""
cdef char *GLSL_FRAG_FLAT = \
"""
varying vec4 col;
void main (void)
{
gl_FragColor = col;
}
"""
# two sided per-pixel phong shader
# ref: http://www.gamedev.net/page/resources/_/technical/opengl/creating-a-glsl-library-r2428
cdef char *GLSL_VERTEX_PONG = \
"""
varying vec3 normal;
varying vec3 vertex;
void main()
{
// Calculate the normal
normal = normalize(gl_NormalMatrix * gl_Normal);
// Transform the vertex position to eye space
vertex = vec3(gl_ModelViewMatrix * gl_Vertex);
gl_Position = ftransform();
}
"""
cdef char *GLSL_FRAG_PONG_COMMON = \
"""
varying vec3 normal;
varying vec3 vertex;
float calculateAttenuation(in int i, in float dist)
{
return(1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation * dist * dist));
}
void directionalLight(in int i, in vec3 N, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 L = normalize(gl_LightSource[i].position.xyz);
float nDotL = dot(N, L);
if (nDotL > 0.0)
{
vec3 H = gl_LightSource[i].halfVector.xyz;
float pf = pow(max(dot(N,H), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * nDotL;
specular += gl_LightSource[i].specular * pf;
}
ambient += gl_LightSource[i].ambient;
}
void pointLight(in int i, in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);
float dist = length(D);
float attenuation = calculateAttenuation(i, dist);
float nDotL = dot(N,L);
if (nDotL > 0.0)
{
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);
float pf = pow(max(dot(R,E), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
specular += gl_LightSource[i].specular * attenuation * pf;
}
ambient += gl_LightSource[i].ambient * attenuation;
}
void spotLight(in int i, in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);
float dist = length(D);
float attenuation = calculateAttenuation(i, dist);
float nDotL = dot(N,L);
if (nDotL > 0.0)
{
float spotEffect = dot(normalize(gl_LightSource[i].spotDirection), -L);
if (spotEffect > gl_LightSource[i].spotCosCutoff)
{
attenuation *= pow(spotEffect, gl_LightSource[i].spotExponent);
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);
float pf = pow(max(dot(R,E), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
specular += gl_LightSource[i].specular * attenuation * pf;
}
}
ambient += gl_LightSource[i].ambient * attenuation;
}
void calculateLighting(in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
// Just loop through each light, and add
// its contributions to the color of the pixel.
for (int i = 0; i < MAX_LIGHTS - 1; i++)
{
if (gl_LightSource[i].position.w == 0.0)
directionalLight(i, N, shininess, ambient, diffuse, specular);
else if (gl_LightSource[i].spotCutoff == 180.0)
pointLight(i, N, V, shininess, ambient, diffuse, specular);
else
spotLight(i, N, V, shininess, ambient, diffuse, specular);
}
}
"""
cdef char *GLSL_FRAG_PONG_SPECULAR = \
"""
void main()
{
// Normalize the normal. A varying variable CANNOT
// be modified by a fragment shader. So a new variable
// needs to be created.
vec3 n = normalize(normal);
vec4 ambient, diffuse, specular, color;
// Initialize the contributions.
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// In this case the built in uniform gl_MaxLights is used
// to denote the number of lights. A better option may be passing
// in the number of lights as a uniform or replacing the current
// value with a smaller value.
calculateLighting(n, vertex, gl_FrontMaterial.shininess,
ambient, diffuse, specular);
color = gl_FrontLightModelProduct.sceneColor +
(ambient * gl_FrontMaterial.ambient) +
(diffuse * gl_FrontMaterial.diffuse) +
(specular * gl_FrontMaterial.specular);
// Re-initialize the contributions for the back
// pass over the lights
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// Now caculate the back contribution. All that needs to be
// done is to flip the normal.
calculateLighting(-n, vertex, gl_BackMaterial.shininess,
ambient, diffuse, specular);
color += gl_BackLightModelProduct.sceneColor +
(ambient * gl_BackMaterial.ambient) +
(diffuse * gl_BackMaterial.diffuse) +
(specular * gl_BackMaterial.specular);
color = clamp(color, 0.0, 1.0);
gl_FragColor = color;
}
"""
cdef char *GLSL_FRAG_PONG_DIFFUSE = \
"""
void main()
{
// Normalize the normal. A varying variable CANNOT
// be modified by a fragment shader. So a new variable
// needs to be created.
vec3 n = normalize(normal);
vec4 ambient, diffuse, specular, color;
// Initialize the contributions.
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// In this case the built in uniform gl_MaxLights is used
// to denote the number of lights. A better option may be passing
// in the number of lights as a uniform or replacing the current
// value with a smaller value.
calculateLighting(n, vertex, gl_FrontMaterial.shininess,
ambient, diffuse, specular);
color = gl_FrontLightModelProduct.sceneColor +
(ambient * gl_FrontMaterial.ambient) +
(diffuse * gl_FrontMaterial.diffuse);
// Re-initialize the contributions for the back
// pass over the lights
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// Now caculate the back contribution. All that needs to be
// done is to flip the normal.
calculateLighting(-n, vertex, gl_BackMaterial.shininess,
ambient, diffuse, specular);
color += gl_BackLightModelProduct.sceneColor +
(ambient * gl_BackMaterial.ambient) +
(diffuse * gl_BackMaterial.diffuse);
color = clamp(color, 0.0, 1.0);
gl_FragColor = color;
}
"""

52
gltools/@src/Texture.pxi Normal file
View file

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
#
# This file is part of gltools - See LICENSE.txt
#
cdef class TextureRect2D:
'''
Abstraction of OpenGL 2d rectangular texture used
for keeping a buffer of the screen content.
'''
def __init__(self, int width, int height, int depth = 3):
self.thisptr = new c_TextureRect2D(width, height, depth, NULL)
if not glCheck():
raise GLError(errorMessage)
def __dealloc__(self):
cdef c_TextureRect2D *tmp
if self.thisptr != NULL:
tmp = <c_TextureRect2D *>self.thisptr
del tmp
def __str__(self):
return "TextureRect2D%s" % repr(self)
def __repr__(self):
cdef c_TextureRect2D *tex = <c_TextureRect2D *>self.thisptr
args = tex.m_width, tex.m_height, tex.m_depth
return "(width = %d, height = %d, depth = %d)" % args
cpdef blit(self, float x = 0., float y = 0.):
'''
Blit content of the texture to the back buffer.
'''
cdef c_TextureRect2D *tex = <c_TextureRect2D *>self.thisptr
tex.blit(x, y)
cpdef copy(self, int mode = GL_BACK):
'''
Copy buffer content to texture.
'''
cdef c_TextureRect2D *tex = <c_TextureRect2D *>self.thisptr
tex.copy(mode)
@classmethod
def fromImage(cls, Image img):
'''
Create texture from existing image
'''
cpdef TextureRect2D ret = TextureRect2D.__new__(TextureRect2D)
ret.thisptr = new c_TextureRect2D(img.width, img.height, img.bytesPerPixel, img._buffer)
return ret

View file

@ -23,6 +23,8 @@ cdef class Material:
cdef readonly int mode
cpdef enable(self)
cpdef ambientLight(ColorRGBA col)
cdef class Light:
cdef public Material material
cdef public Point position
@ -31,6 +33,11 @@ cdef class Light:
cdef readonly int index
cpdef enable(self)
cpdef disable(self)
cdef class TextureRect2D:
cdef void *thisptr
cpdef blit(self, float x = ?, float y = ?)
cpdef copy(self, int mode = ?)
cdef class ClientBuffer:
cdef void *thisptr

View file

@ -18,6 +18,7 @@ include "GL.pxi"
include "ClientBuffer.pxi"
include "ShaderProgram.pxi"
include "Text.pxi"
include "Texture.pxi"
include "UI.pxi"
def test2d(double [:, ::1] arr):

View file

@ -50,177 +50,6 @@ indices = array.array('B',(
20,21,22, 22,23,20, # back
))
GLSL_VERTEX = \
"""
varying vec3 normal;
varying vec3 vertex;
void main()
{
// Calculate the normal
normal = normalize(gl_NormalMatrix * gl_Normal);
// Transform the vertex position to eye space
vertex = vec3(gl_ModelViewMatrix * gl_Vertex);
gl_Position = ftransform();
}
"""
GLSL_FRAG = \
"""
#define MAX_LIGHTS 3
varying vec3 normal;
varying vec3 vertex;
float calculateAttenuation(in int i, in float dist)
{
return(1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * dist +
gl_LightSource[i].quadraticAttenuation * dist * dist));
}
void directionalLight(in int i, in vec3 N, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 L = normalize(gl_LightSource[i].position.xyz);
float nDotL = dot(N, L);
if (nDotL > 0.0)
{
vec3 H = gl_LightSource[i].halfVector.xyz;
float pf = pow(max(dot(N,H), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * nDotL;
specular += gl_LightSource[i].specular * pf;
}
ambient += gl_LightSource[i].ambient;
}
void pointLight(in int i, in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);
float dist = length(D);
float attenuation = calculateAttenuation(i, dist);
float nDotL = dot(N,L);
if (nDotL > 0.0)
{
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);
float pf = pow(max(dot(R,E), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
specular += gl_LightSource[i].specular * attenuation * pf;
}
ambient += gl_LightSource[i].ambient * attenuation;
}
void spotLight(in int i, in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);
float dist = length(D);
float attenuation = calculateAttenuation(i, dist);
float nDotL = dot(N,L);
if (nDotL > 0.0)
{
float spotEffect = dot(normalize(gl_LightSource[i].spotDirection), -L);
if (spotEffect > gl_LightSource[i].spotCosCutoff)
{
attenuation *= pow(spotEffect, gl_LightSource[i].spotExponent);
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);
float pf = pow(max(dot(R,E), 0.0), shininess);
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
specular += gl_LightSource[i].specular * attenuation * pf;
}
}
ambient += gl_LightSource[i].ambient * attenuation;
}
void calculateLighting(in vec3 N, in vec3 V, in float shininess,
inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
// Just loop through each light, and add
// its contributions to the color of the pixel.
for (int i = 0; i < MAX_LIGHTS - 1; i++)
{
if (gl_LightSource[i].position.w == 0.0)
directionalLight(i, N, shininess, ambient, diffuse, specular);
else if (gl_LightSource[i].spotCutoff == 180.0)
pointLight(i, N, V, shininess, ambient, diffuse, specular);
else
spotLight(i, N, V, shininess, ambient, diffuse, specular);
}
}
void main()
{
// Normalize the normal. A varying variable CANNOT
// be modified by a fragment shader. So a new variable
// needs to be created.
vec3 n = normalize(normal);
vec4 ambient, diffuse, specular, color;
// Initialize the contributions.
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// In this case the built in uniform gl_MaxLights is used
// to denote the number of lights. A better option may be passing
// in the number of lights as a uniform or replacing the current
// value with a smaller value.
calculateLighting(n, vertex, gl_FrontMaterial.shininess,
ambient, diffuse, specular);
color = gl_FrontLightModelProduct.sceneColor +
(ambient * gl_FrontMaterial.ambient) +
(diffuse * gl_FrontMaterial.diffuse) +
(specular * gl_FrontMaterial.specular);
// Re-initialize the contributions for the back
// pass over the lights
ambient = vec4(0.0);
diffuse = vec4(0.0);
specular = vec4(0.0);
// Now caculate the back contribution. All that needs to be
// done is to flip the normal.
calculateLighting(-n, vertex, gl_BackMaterial.shininess,
ambient, diffuse, specular);
color += gl_BackLightModelProduct.sceneColor +
(ambient * gl_BackMaterial.ambient) +
(diffuse * gl_BackMaterial.diffuse) +
(specular * gl_BackMaterial.specular);
color = clamp(color, 0.0, 1.0);
gl_FragColor = color;
}
"""
class MainWindow(gl.Window):
def __init__(self, width, height, title):
self.initialized = False
@ -280,9 +109,8 @@ class MainWindow(gl.Window):
)
# GLSL
glsl = self.program = gl.ShaderProgram()
glsl.build(GLSL_VERTEX, GLSL_FRAG)
glsl = self.program = gl.ShaderProgram.pongDiffuse(3)
# mesh
fsize = vertices.itemsize
buffer = self.buffer = gl.ClientBuffer()
@ -433,20 +261,25 @@ class MainWindow(gl.Window):
cam = self.cam
ui = self.insideUI(x, y)
update = False
if not ui and self.currentButton == gl.MOUSE.LEFT:
# rotate view
dx = x - lastx
dy = y - lasty
cam.rotateDeltas(dx, dy, target = self.mouseCenter)
update = True
elif not ui and self.currentButton == gl.MOUSE.RIGHT:
# pan view
cam.pan(lastx, lasty, x, y, target = self.mouseCenter)
update = True
#print 'onCursorPos ', x, y
self.lastPos = x, y
self.onRefresh()
if ui or update:
self.onRefresh()
def onMouseButton(self, button, action):
#print 'onMouseButton ', button, action