pyopengl不使用gluCylinder函数创建圆柱体

2024-09-30 16:24:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用opengl创建一个圆柱体。圆柱体的顶部不是圆形,而底部如下图所示。我想知道如何解决这个问题,如果这是我编写它的方式,或者只是我做它的方式不适用于pyopengl。我使用的是pygame1.9.2、python3.5和PyOpenGL-3.1.0。在

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()

Tags: fromimport方式mathsincosgltheta
1条回答
网友
1楼 · 发布于 2024-09-30 16:24:59

一个圆柱体可以分成两个圆和一个连接这两个圆的矩形管/薄板。为了避免重复某些顶点,我使用了GL_TRIANGLE_FAN(对于圆)和GL_TRIANGLE_STRIP(对于管状体),而不是{}和{}。如果你想了解更多,我建议你看看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发送一个顶点,这不是很有效。如果你想以后再去看看VBOs的性能,你可能会发现问题。希望这有帮助!在

相关问题 更多 >