2017-01-28 42 views
0

使用pyopengl,我試圖創建一個圓柱體。圓柱體的頂部不是圓形的,而底部如下面鏈接的圖像所示。我想知道如何解決這個問題,如果它的方式,我已經編碼或只是我做的方式不適用於pyopengl。我正在使用Pygame 1.9.2,Python 3.5和PyOpenGL-3.1.0。pyopengl - 創建一個沒有使用gluCylinder函數的圓柱體

https://i.stack.imgur.com/KYPLY.jpg

import pygame 
from pygame.locals import * 

from OpenGL.GL import * 
from OpenGL.GLU import * 





def securityCamera(radius,halflength,slices): 
    glBegin(GL_TRIANGLES) 
    for i in range(1,slices+1): 
     angleSize=(2*math.pi)/slices 
     theta=i*angleSize 
     nextTheta=(i+1)*angleSize 

     glColor3fv((0/256,0/256,0/256)) 

     glVertex3f(radius*math.cos(nextTheta), halflength, radius*math.cos(nextTheta)) 
     glVertex3f(radius*math.cos(theta), halflength, radius*math.sin(theta)) 
     glVertex3f(0.0, halflength, 0.0) 

     glVertex3f(radius*math.cos(nextTheta), -halflength, radius*math.sin(nextTheta)) 
     glVertex3f(radius*math.cos(theta), -halflength, radius*math.sin(theta)) 
     glVertex3f(0.0, -halflength, 0.0) 

    glEnd() 

    glBegin(GL_QUADS) 
    for i in range(1,slices+1): 
     angleSize=(2*math.pi)/slices 
     theta=i*angleSize 
     nextTheta=(i+1)*angleSize 


     glColor3fv((256/256,256/256,256/256)) 
     glVertex3f(radius*math.cos(theta), halflength, radius*math.sin(theta)) 
     glVertex3f(radius*math.cos(nextTheta), halflength, radius*math.cos(nextTheta)) 
     glVertex3f(radius*math.cos(theta), -halflength, radius*math.sin(theta)) 
     glVertex3f(radius*math.cos(nextTheta), -halflength, radius*math.sin(nextTheta)) 
    glEnd() 

回答

0

氣缸可以被劃分成兩個圓和連接兩個矩形管/片。爲了避免重複某些頂點,我使用了GL_TRIANGLE_FAN(用於圈)和GL_TRIANGLE_STRIP(用於管),而不是GL_TRIANGLEGL_QUAD。如果你想了解更多關於這些的信息,我建議你看看this的答案。

下面是顯示與紅色端,藍色端,和在中間的綠色管旋轉圓筒演示(重要的代碼是在draw_cylinder功能):

import pygame 
from pygame.locals import * 
from OpenGL.GL import * 
from OpenGL.GLU import * 
import math 
import sys 

def draw_cylinder(radius, height, num_slices): 
    r = radius 
    h = height 
    n = float(num_slices) 

    circle_pts = [] 
    for i in range(int(n) + 1): 
     angle = 2 * math.pi * (i/n) 
     x = r * math.cos(angle) 
     y = r * math.sin(angle) 
     pt = (x, y) 
     circle_pts.append(pt) 

    glBegin(GL_TRIANGLE_FAN)#drawing the back circle 
    glColor(1, 0, 0) 
    glVertex(0, 0, h/2.0) 
    for (x, y) in circle_pts: 
     z = h/2.0 
     glVertex(x, y, z) 
    glEnd() 

    glBegin(GL_TRIANGLE_FAN)#drawing the front circle 
    glColor(0, 0, 1) 
    glVertex(0, 0, h/2.0) 
    for (x, y) in circle_pts: 
     z = -h/2.0 
     glVertex(x, y, z) 
    glEnd() 

    glBegin(GL_TRIANGLE_STRIP)#draw the tube 
    glColor(0, 1, 0) 
    for (x, y) in circle_pts: 
     z = h/2.0 
     glVertex(x, y, z) 
     glVertex(x, y, -z) 
    glEnd() 

pygame.init() 
(width, height) = (800, 600) 
screen = pygame.display.set_mode((width, height), OPENGL | DOUBLEBUF) 
clock = pygame.time.Clock() 
rotation = 0.0 

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      sys.exit() 

    rotation += 1.0 
    glClear(GL_COLOR_BUFFER_BIT) 
    glClear(GL_DEPTH_BUFFER_BIT) 
    glEnable(GL_DEPTH_TEST) 

    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    gluPerspective(30, float(width)/height, 1, 1000) 
    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity() 
    glTranslate(0, 0, -50)#move back far enough to see this object 
    glRotate(rotation, 0, 1, 0)#NOTE: this is applied BEFORE the translation due to OpenGL multiply order 

    draw_cylinder(5, 10, 20) 
    pygame.display.flip() 
    clock.tick(60) 

順便提及,你可能已經意識到像glBeginglVertex這樣的固定功能方法是古老而過時的,但我認爲這並不會讓人傷心。有了這樣的代碼,你基本上一次發送一個頂點到GPU,這不是非常有效。如果您後來遇到性能問題,您可能需要關注一下VBO。希望這可以幫助!

相關問題