2017-01-28 6 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_TRIANGLEGL_QUADの代わりに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に一度に1つずつ頂点を送りますが、効率的ではありません。後でパフォーマンスの問題に遭遇した場合は、VBOを確認することをお勧めします。お役に立てれば!

関連する問題