1
我想在平坦的表面上照射好的聚光燈。我知道每個頂點都進行了照明,因此在表面上創建了可能的頂點 - 請參閱此answer。然而,我得到了這些 - 用GL_QUADS和GL_LINE_STRIP來檢查我是否正確地做了事情。射在平坦表面上的射燈
這些顯然比較差。所以,
- 什麼需要我的機會,使聚光燈看起來更像一個圓形的表面?
- 如何更快地繪製這個場景?
注:我認識到,在這種情況下,正常計算並非嚴格必要,但在一般情況下,它是需要的。另外,我可以使用表面的顯示列表,因此只能繪製一次。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
from Numeric import *
lightPosition = np.array([10, 30, 20, 1])
view_rotation = np.array([0, 0, 0])
def init():
globAmb = [0.3, 0.3, 0.3, 1.0]
lightAmb = [0.0, 0.0, 0.0, 1.0]
lightDifAndSpec = [0.7, 0.7, 0.7, 1.0]
glutInit()
glClearColor(0.0, 0.0, 0.0, 0.0)
glEnable(GL_DEPTH_TEST)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glShadeModel(GL_SMOOTH)
glEnable(GL_LIGHTING)
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb)
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec)
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec)
glEnable(GL_LIGHT0)
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb)
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE)
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
def display():
glClearColor(0.0, 0.0, 0.0, 0.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
gluLookAt(0.0, 40.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(view_rotation[0], 1.0, 0.0, 0.0)
glRotatef(view_rotation[1], 0.0, 1.0, 0.0)
glRotatef(view_rotation[2], 0.0, 0.0, 1.0)
glPushMatrix()
pos = [0, 20, 0, 1]
direction = [0.0, -1.0, 0.0]
spotAngle = 20
glLightfv(GL_LIGHT0, GL_POSITION, pos)
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, spotAngle)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction)
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2)
glPushMatrix();
glDisable(GL_LIGHTING)
glTranslate(pos[0], 0.5* pos[1], pos[2])
glRotatef(-90.0, 1.0, 0.0, 0.0)
glColor3f(1.0, 1.0, 1.0)
PI = 3.141592
glutWireCone(3.0 * np.tan(spotAngle/180.0 * PI), pos[1], 10, 6)
glEnable(GL_LIGHTING)
glPopMatrix();
draw_cube()
glPopMatrix()
glFlush()
def reshape(w, h):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(w)/float(h), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def keyboard(key, x, y):
if key == chr(27):
sys.exit(0)
elif key == 'w':
view_rotation[0] += 10
display()
elif key == 's':
view_rotation[0] -= 10
display()
elif key == 'a':
view_rotation[1] -= 10
display()
elif key == 'd':
view_rotation[1] += 10
display()
else:
print "Unknown %s key" %(key)
def draw_cube():
glPushMatrix()
glRotatef(45, 0, 1, 0)
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, [183/256.0, 65/256.0, 14/256.0, 1.0]);
glMaterialfv(GL_FRONT, GL_SPECULAR, [1, 1, 1, 1]);
glMaterialfv(GL_FRONT, GL_SHININESS, [100.0]);
sz = 10
step = 1
for x in arange(-sz, sz, step):
for z in arange(-sz, sz, step):
v0 = np.array([x, sz, z])
v1 = np.array([x, sz, z+step])
v2 = np.array([x+step, sz, z+step])
v3 = np.array([x+step, sz, z])
#glBegin(GL_QUADS) # Uncomment to get the surface instead of lines.
glBegin(GL_LINE_STRIP)
n = get_normal_vector(v0, v1, v3)
glNormal(n[0], n[1], n[2])
glVertex3f(v0[0], v0[1], v0[2])
n = get_normal_vector(v1, v2, v0)
glNormal(n[0], n[1], n[2])
glVertex3f(v1[0], v1[1], v1[2])
n = get_normal_vector(v2, v3, v1)
glNormal(n[0], n[1], n[2])
glVertex3f(v2[0], v2[1], v2[2])
n = get_normal_vector(v3, v0, v2)
glNormal(n[0], n[1], n[2])
glVertex3f(v3[0], v3[1], v3[2])
glEnd()
glPopMatrix()
def get_normal_vector (v1, v2, v3):
v = np.cross(v2-v1, v3-v1)
n = np.sqrt(np.dot(v, v.conj()))
if n:
return v/n
else:
print v1
print v2
print v3
print v/n
sys.exit(-1)
glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(800, 800)
glutInitWindowPosition(300, 0)
glutCreateWindow('Lines')
init()
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutKeyboardFunc(keyboard)
glutMainLoop()
PS:我會使用着色器時,我有它的工作更新與源代碼的答案...
Python中的任何代碼示例?我發現了一些[教程](http://pyopengl.sourceforge.net/context/tutorials/index.xhtml),它可能包含我需要的東西...你知道的任何更好的來源? – Sardathrion 2012-07-05 15:08:25
對不起,我不知道任何python教程非手動:(但它應該是相當容易移植的C/C++版本。試試吧,讓我知道如果你遇到任何問題! – Ani 2012-07-05 15:10:05
嘗試使用不同的版本來編譯着色器,如「#version 120」或「#version 150」。 – Ani 2012-07-05 16:10:23