The relevant methods to see are: init, genTexture, onDisplayEvent and table_leg_model.
The 'wood1.png' is a 64x64 image.
Code :
import Image
from math import cos
from math import pi
from math import sin
from numpy import array
from numpy import uint8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from sys import argv
# Classes ----------------------------------------------------------------------
class AppGL(object):
def __init__(self, title, position=(100, 100), size=(400, 400)):
# Properties -----------------------------------------------------------
self.angle_delta = 4.0
self.position = position
self.rotateX = [0, 1.0, 0.0, 0.0]
self.rotateY = [0, 0.0, 1.0, 0.0]
self.size = size
self.translate = [0.0, 0.0, 0.0]
self.textures_index = {
'wood1': 0,
}
self.textures = array([0] * len(self.textures_index), uint8)
#-----------------------------------------------------------------------
# General initialization
glClearColor(0.0, 0.0, 0.0, 1.0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
glGenTextures(len(self.textures), self.textures)
self.genTexture('wood1', 'textures/wood1.png')
#-----------------------------------------------------------------------
# GLUT initialization --------------------------------------------------
glutInit(argv)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowPosition(*self.position)
glutInitWindowSize(*self.size)
glutCreateWindow(title)
#-----------------------------------------------------------------------
# Callbacks ------------------------------------------------------------
glutDisplayFunc(self.onDisplayEvent)
glutKeyboardFunc(self.onKeyEvent)
glutMotionFunc(self.onMouseMotionEvent)
glutMouseFunc(self.onMouseButtonEvent)
glutReshapeFunc(self.onReshapeEvent)
glutSpecialFunc(self.onSpecialKeyEvent)
#-----------------------------------------------------------------------
# Arrays ---------------------------------------------------------------
data = []
#data.extend(table_model(0.4, 40))
data.extend(table_leg_model())
#data.extend(table_model(0.2, 40))
glInterleavedArrays(GL_T2F_V3F, 0, array(data, "f"))
#-----------------------------------------------------------------------
def genTexture(self, index, path):
img = Image.open(path)
texture_data = array(list(img.getdata()), uint8)
glBindTexture(GL_TEXTURE_2D, self.textures[self.textures_index[index]])
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)
def onDisplayEvent(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
gluLookAt(0, 0, 4, 0, 0, -1, 0, 1, 0)
glTranslatef(*self.translate)
glRotatef(*self.rotateX)
glRotatef(*self.rotateY)
# Visual scene ---------------------------------------------------------
glPushMatrix()
# Table -----------------------~
#glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(0, 80, 2), "d"))
#glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(1, 80, 2), "d"))
#glDrawElements(GL_QUAD_STRIP, 80, GL_UNSIGNED_INT, array(xrange(0, 80), "d"))
getMatrixHead()
glTranslatef(-0.1, -0.1, 0)
#glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(80, 90), "d"))
glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(0, 10), "d"))
#getMatrixHead()
#glTranslatef(0, 0, 1)
#glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(90, 170, 2), "d"))
#glDrawElements(GL_POLYGON, 39, GL_UNSIGNED_INT, array(xrange(91, 170, 2), "d"))
#glDrawElements(GL_QUAD_STRIP, 80, GL_UNSIGNED_INT, array(xrange(90, 170), "d"))
glPopMatrix()
#-----------------------------------------------------------------------
glutSwapBuffers()
def onKeyEvent(self, key, x, y):
change = True
if key == 'a':
self.translate[0] += 1
elif key == 'd':
self.translate[0] -= 1
elif key == 's':
self.translate[1] += 1
elif key == 'w':
self.translate[1] -= 1
elif key == 'q':
self.translate[2] += 1
elif key == 'e':
self.translate[2] -= 1
else:
change = False
if change: glutPostRedisplay()
def onMouseMotionEvent(self, x, y):
pass
def onMouseButtonEvent(self, button, state, x, y):
pass
def onReshapeEvent(self, width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, width / height, 1.0, 100.0)
glMatrixMode(GL_MODELVIEW)
def onSpecialKeyEvent(self, key, x, y):
change = True
if key == GLUT_KEY_UP:
self.rotateX[0] += self.angle_delta
elif key == GLUT_KEY_DOWN:
self.rotateX[0] -= self.angle_delta
elif key == GLUT_KEY_LEFT:
self.rotateY[0] += self.angle_delta
elif key == GLUT_KEY_RIGHT:
self.rotateY[0] -= self.angle_delta
else:
change = False
if change: glutPostRedisplay()
def run(self):
glutMainLoop()
#-------------------------------------------------------------------------------
# Functions --------------------------------------------------------------------
def getMatrixHead():
glPopMatrix()
glPushMatrix()
def table_model(radius, number_of_points):
delta = 2 * pi / (number_of_points - 1)
points = []
for i in xrange(number_of_points):
points.extend((radius * cos(i * delta), radius * sin(i * delta), 0.05))
points.extend((radius * cos(i * delta), radius * sin(i * delta), 0))
return points
def table_leg_model():
return (
0, 0, 0, 0.2, 0,
0, 1, 0, 0.2, 1.0,
1, 0, 0, 0, 0,
1, 1, 0, 0, 1.0,
#0, 0, 0.2, 0, 0,
#0, 1, 0.2, 0, 1.0,
#1, 0, 0.2, 0.2, 0,
#1, 1, 0.2, 0.2, 1.0,
#0, 0, 0, 0.2, 0,
#0, 1, 0, 0.2, 1.0,
)
#-------------------------------------------------------------------------------
# Main -------------------------------------------------------------------------
if __name__ == '__main__':
AppGL("Moe's Tavern", (300, 100), (800, 600)).run()
#-------------------------------------------------------------------------------
The source code can also be found here ~> https://github.com/EPadronU/TavernGL/blob/master/appgl.py
I'll just run down the list of what stroke me curious:
The function getMatrixHead
makes no sense, at least the naming. At best it will just drop what's been on the stack and make a copy of what's below.
Then you make the typical newbie error of trying to "initialize" OpenGL. Don't do that. Except for loading textures or VBO data make OpenGL calls only from the display function and nowhere else. If you made a backtrace whenever a OpenGL function is called it should only happen because ultimately because display was called. If you had done it that way you'd not have made OpenGL called before there was an actual OpenGL context: Only after a OpenGL context has been created OpenGL calls have an effect. If using GLUT that's after calling glutCreateWindow
Now look at that code:
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
glGenTextures(len(self.textures), self.textures)
self.genTexture('wood1', 'textures/wood1.png')
#-----------------------------------------------------------------------
# GLUT initialization --------------------------------------------------
glutInit(argv)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowPosition(*self.position)
glutInitWindowSize(*self.size)
glutCreateWindow(title)
You're making OpenGL calls before there is a context. If you had written it in the following way it would have worked (I also took the liberty at giving it a nice informative loading screen)
import Image
from math import cos
from math import pi
from math import sin
from numpy import array
from numpy import uint8
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from sys import argv
# Classes ----------------------------------------------------------------------
class AppGL(object):
def __init__(self, title, position=(100, 100), size=(400, 400)):
# Properties -----------------------------------------------------------
self.angle_delta = 4.0
self.position = position
self.rotateX = [0, 1.0, 0.0, 0.0]
self.rotateY = [0, 0.0, 1.0, 0.0]
self.size = size
self.translate = [0.0, 0.0, 0.0]
self.textures = dict()
#-----------------------------------------------------------------------
# GLUT initialization --------------------------------------------------
glutInit(argv)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowPosition(*self.position)
glutInitWindowSize(*self.size)
glutCreateWindow(title)
#-----------------------------------------------------------------------
# Callbacks ------------------------------------------------------------
glutDisplayFunc(self.onDisplayEvent)
glutKeyboardFunc(self.onKeyEvent)
glutMotionFunc(self.onMouseMotionEvent)
glutMouseFunc(self.onMouseButtonEvent)
glutReshapeFunc(self.onReshapeEvent)
glutSpecialFunc(self.onSpecialKeyEvent)
#-----------------------------------------------------------------------
# Arrays ---------------------------------------------------------------
self.tablelegmodel = array( list(table_leg_model()), "f")
#-----------------------------------------------------------------------
def loadTexture(self, path):
if path in self.textures.keys():
glBindTexture(GL_TEXTURE_2D, self.textures[path])
return
glDrawBuffer(GL_FRONT)
glClearColor(0.25, 0.25, 0.75, 1.)
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glRasterPos3f(-0.9, 0.9, 0)
glDisable(GL_TEXTURE_2D)
glDisable(GL_LIGHTING)
glutBitmapString(GLUT_BITMAP_HELVETICA_18, "Loading Texture " + path)
glFinish()
glDrawBuffer(GL_BACK)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
img = Image.open(path)
texture_data = array(list(img.getdata()), uint8)
texID = array([0], uint8)
glGenTextures(1, texID)
texID = texID[0]
self.textures[path] = texID
glBindTexture(GL_TEXTURE_2D, texID)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data)
def onDisplayEvent(self):
width, height = self.size
aspect = float(width) / float(height)
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, aspect, 1.0, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(0, 0, 4, 0, 0, -1, 0, 1, 0)
glTranslatef(*self.translate)
glRotatef(*self.rotateX)
glRotatef(*self.rotateY)
# Visual scene ---------------------------------------------------------
glEnable(GL_DEPTH_TEST)
glPushMatrix()
glTranslatef(-0.1, -0.1, 0)
self.loadTexture('textures/wood1.png')
glEnable(GL_TEXTURE_2D)
glInterleavedArrays(GL_T2F_V3F, 0, self.tablelegmodel)
glDrawElements(GL_QUAD_STRIP, 10, GL_UNSIGNED_INT, array(xrange(0, 10), "d"))
glPopMatrix()
#-----------------------------------------------------------------------
glutSwapBuffers()
def onKeyEvent(self, key, x, y):
if key == 'a':
self.translate[0] += 1
elif key == 'd':
self.translate[0] -= 1
elif key == 's':
self.translate[1] += 1
elif key == 'w':
self.translate[1] -= 1
elif key == 'q':
self.translate[2] += 1
elif key == 'e':
self.translate[2] -= 1
else:
return
glutPostRedisplay()
def onMouseMotionEvent(self, x, y):
pass
def onMouseButtonEvent(self, button, state, x, y):
pass
def onReshapeEvent(self, width, height):
self.size = width, height
glutPostRedisplay()
def onSpecialKeyEvent(self, key, x, y):
if key == GLUT_KEY_UP:
self.rotateX[0] += self.angle_delta
elif key == GLUT_KEY_DOWN:
self.rotateX[0] -= self.angle_delta
elif key == GLUT_KEY_LEFT:
self.rotateY[0] += self.angle_delta
elif key == GLUT_KEY_RIGHT:
self.rotateY[0] -= self.angle_delta
else:
return
glutPostRedisplay()
def run(self):
glutMainLoop()
#-------------------------------------------------------------------------------
def table_model(radius, number_of_points):
delta = 2 * pi / (number_of_points - 1)
points = []
for i in xrange(number_of_points):
points.append((radius * cos(i * delta), radius * sin(i * delta), 0.05))
points.append((radius * cos(i * delta), radius * sin(i * delta), 0))
return points
def table_leg_model():
return (
0, 0, 0, 0.2, 0,
0, 1, 0, 0.2, 1.0,
1, 0, 0, 0, 0,
1, 1, 0, 0, 1.0,
#0, 0, 0.2, 0, 0,
#0, 1, 0.2, 0, 1.0,
#1, 0, 0.2, 0.2, 0,
#1, 1, 0.2, 0.2, 1.0,
#0, 0, 0, 0.2, 0,
#0, 1, 0, 0.2, 1.0,
)
#-------------------------------------------------------------------------------
# Main -------------------------------------------------------------------------
if __name__ == '__main__':
AppGL("Moe's Tavern", (300, 100), (800, 600)).run()
#-------------------------------------------------------------------------------