2017-01-28 22 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_TRIANGLE и GL_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) 

Кстати, вы, вероятно, знаете, что методы фиксированной функции, такие как glBegin и glVertex, действительно древние и устаревшие, но я думал, что это не помешает упоминать. С помощью такого кода вы в основном отправляете вершины по одному на GPU, что не очень эффективно. Вы можете захотеть взглянуть на VBOs, если позже столкнетесь с проблемами производительности. Надеюсь это поможет!

 Смежные вопросы

  • Нет связанных вопросов^_^