Using Glulookat() Causes The Objects To Spin
Solution 1:
In your code there are 2 issues.
gluLookAt
sets up a view matrix. But this is not all.gluLookAt
multiplies the view matrix to the current matrix on the matrix stack, which is chosen byglMatrixMode
. So your code concatenates the new view matrix to the existing view matrix. This causes that the objects start to spin rapidly.
Set the Identity matrix before you call gluLookAt
to solve this issue. This causes that the model view matrix is set from scratch, independent on its former state.
glLoadIdentity()
gluLookAt(0, 0, 0, facing[0], facing[1], lookingZ, 0, 1, 0)
This won't solve you issue completely, because at the point when you set the view matrix, then current matrix on the model view matrix stack is the concatenation of the projection matirx and the view matrix. This cause the
glLoadIdentity
also skips the projection matrix. This behaviour can be solved with ease. Put the view matrix on the model view matrix stack (GL_MODELVIEW
) and the projection matrix to the projection matrix stack (GL_PROJECTION
):
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (width/height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
An much better and completely working solution is to apply a rotation matrix around the x and y axis to the view matrix. First apply the rotation matrix around the y axis (up vector) then the current view matrix and finally the rotation on the x axis:
view-matrix = rotate-X * view-matrix * rotate-Y
For this the current view matrix has to be read by glGetFloatv(GL_MODELVIEW_MATRIX)
:
modelview = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()
glRotate(-change[1]*0.1, 1, 0, 0)
glMultMatrixf(modelview)
glRotate(change[0]*0.1, 0, 1, 0)
Note, this has to be done instead of:
glLoadIdentity()
gluLookAt(0, 0, 0, facing[0], facing[1], lookingZ, 0, 1, 0)
Complete main
function (renderingEngine.py), with the suggested changes:
defmain(world,x,y,z,width,height,renderDistance):
pygame.init()
pygame.display.set_mode((width,height), DOUBLEBUF | OPENGL)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthMask(GL_TRUE)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glFrontFace(GL_CCW)
glShadeModel(GL_SMOOTH)
glDepthRange(0.0, 1.0)
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (width/height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
#pygame.mouse.set_visible(False)
facing = [0, 0, False]
whileTrue:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
pygame.mouse.set_visible(True)
pygame.quit()
return# TODO: Add pause
newMousePos = pygame.mouse.get_pos()
change = (newMousePos[0]-(width/2), newMousePos[1]-(height/2))
pygame.mouse.set_pos([width / 2, height / 2])
if facing[2]:
facing[0] -= change[0]
else:
facing[0] += change[0]
facing[1] += change[1]
while facing[0] > width:
facing[0] = 2*width-facing[0]
facing[2] = not facing[2]
while facing[0] < 0:
facing[0] = 0-facing[0]
facing[2] = not facing[2]
if facing[1] < 0:
facing[1] = 0if facing[1] > height:
facing[1] = height
radius = (width**2+height**2)**.5+1
lookingZ = (-1*facing[0]**2-facing[1]**2+radius**2)**.5if facing[2]:
lookingZ *= -1#print(lookingZ, facing[0], facing[1], radius)print(facing[0], facing[1], lookingZ)
#glLoadIdentity()#gluLookAt(0, 0, 0, facing[0], facing[1], lookingZ, 0, 1, 0)
modelview = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()
glRotate(-change[1]*0.1, 1, 0, 0)
glMultMatrixf(modelview)
glRotate(change[0]*0.1, 0, 1, 0)
xmin = round(x-renderDistance[0])
ymin = round(y-renderDistance[1])
zmin = round(z-renderDistance[2])
if xmin < 0:
xmin = 0if ymin < 0:
ymin = 0if zmin < 0:
zmin = 0
xmax = round(x+renderDistance[0])
ymax = round(y+renderDistance[1])
zmax = round(z+renderDistance[2])
dims = world.dims()
if xmax > dims[0]:
xmax = dims[0]
if ymax > dims[1]:
ymax = dims[1]
if zmax > dims[2]:
zmax = dims[2]
selection = world.select_data(xrange = (xmin, xmax), yrange = (ymin, ymax), zrange = (zmin, zmax))
blocks = selection.iterate(ignore=(None,))
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for bl in blocks:
locations = bl[0]
block = bl[1]
cube(locations[0] - x, locations[1] - y, locations[2] - z, block)
#print(locations[0],locations[1],locations[2])
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glOrtho(0.0, width, 0.0, height, -1.0, 1.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glDisable(GL_DEPTH_TEST)
crosshair(width/2, height/2, 20)
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glCullFace(GL_BACK)
pygame.display.flip()
time.sleep(.01)
Post a Comment for "Using Glulookat() Causes The Objects To Spin"