pyopengl 不显示预期的结构

pyopengl does not show the intended structure

我只是想学习用 pyopengl 绘制 3d 对象。我试图绘制的第一件事是以下代码。坐标 posat,即原子的位置应该是 bcc 晶格,但我远没有得到像立方体这样的东西。添加了输出。 请让我知道我在这里做什么:

#!/usr/bin/env python

import math
import sys

import ase
import ase.io.vasp
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
from pygame.locals import *

#  inpfile = sys.argv[1]
#  cell = ase.io.vasp.read_vasp(inpfile)
#  numat = len(cell.get_positions())
#  posat = cell.get_positions()
posat = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1], [.5, .5, .5], [1, 1, 0],
         [0, 1, 1], [1, 0, 1], [1, 1, 1]]
numat = len(posat)

print(posat)
#  print(posat[1][0])

pygame.init()
pygame.display.set_caption('vcrys')
display = (1000, 750)
scree = pygame.display.set_mode(display, DOUBLEBUF | OPENGL)

glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glShadeModel(GL_SMOOTH)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)

glEnable(GL_LIGHT0)
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])

sphere = gluNewQuadric()


def atoms(qx, qy, qz, cr, cg, cb, r):
  glTranslatef(qx, qy, qz)
  glColor4f(cr, cg, cb, 1)
  gluSphere(sphere, r, 1080, 1080)


glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0] / display[1]), 0.01, 50.0)

glMatrixMode(GL_MODELVIEW)
gluLookAt(0, -10, 0, 0, 0, 0, 0, 0, 1)
viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)
glLoadIdentity()

# init mouse movement and center mouse on screen
displayCenter = [scree.get_size()[i] // 2 for i in range(2)]
mouseMove = [0, 0]
pygame.mouse.set_pos(displayCenter)

up_down_angle = 0.0
paused = False
run = True
while run:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      run = False
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN:
        run = False
      if event.key == pygame.K_PAUSE or event.key == pygame.K_p:
        paused = not paused
        pygame.mouse.set_pos(displayCenter)
    if not paused:
      if event.type == pygame.MOUSEMOTION:
        mouseMove = [event.pos[i] - displayCenter[i] for i in range(2)]
      pygame.mouse.set_pos(displayCenter)

  if not paused:
    # get keys
    keypress = pygame.key.get_pressed()
    # mouseMove = pygame.mouse.get_rel()

    # init model view matrix
    glLoadIdentity()

    # apply the look up and down
    #  up_down_angle += mouseMove[1] * 0.0001
    #  glRotatef(up_down_angle, .10, 0.0, 0.0)

    # init the view matrix
    glPushMatrix()
    glLoadIdentity()

    # apply the movment
    if keypress[pygame.K_w]:
      glTranslatef(0, 0, 0.1)
    if keypress[pygame.K_s]:
      glTranslatef(0, 0, -0.1)
    if keypress[pygame.K_d]:
      glTranslatef(-0.1, 0, 0)
    if keypress[pygame.K_a]:
      glTranslatef(0.1, 0, 0)
    if keypress[pygame.K_u]:
      glTranslatef(0.0, 0.1, 0)
    if keypress[pygame.K_l]:
      glTranslatef(0, -0.1, 0)

    # apply the left and right rotation
    #  glRotatef(mouseMove[0] * 0.01, 0.0, .01, 0.0)

    # multiply the current matrix by the get the new view matrix and store the final vie matrix
    glMultMatrixf(viewMatrix)
    viewMatrix = glGetFloatv(GL_MODELVIEW_MATRIX)

    # apply view matrix
    glPopMatrix()
    glMultMatrixf(viewMatrix)

    glLightfv(GL_LIGHT0, GL_POSITION, [1, -1, 1, 0])

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    glPushMatrix()

  for a in range(numat):
    atoms(posat[a][0], posat[a][1], posat[a][2], 1, 1, 1, 1 / 10)
  #  atoms(qx=0, cr=0, qy=0, cg=.5, qz=.2, cb=.2, r=1)
  #  atoms(-3, 0, 0, .2, .2, .5, 1)
  glPopMatrix()

  pygame.display.flip()
  #  paused = True
  #  pygame.time.wait(10)

pygame.quit()

glTranslate 定义一个平移矩阵并将当前矩阵与新的平移矩阵相乘。因此所有的翻译都是串联的。
使用glPushMatrix/glPopMatrx在指定平移前保存当前矩阵,绘制原子后恢复当前矩阵:

def atoms(qx, qy, qz, cr, cg, cb, r):
    glPushMatrix()
    glTranslatef(qx, qy, qz)
    glColor4f(cr, cg, cb, 1)
    gluSphere(sphere, r, 1080, 1080)
    glPopMatrix()