Pygame、OpenGL:将 3D rgb 值投影到 2D 表面
Pygame, OpenGL: Project 3D rgb values to 2D surface
使用 Pygame 和 OpenGL,我在 3D 中绘制了一个红色和一个绿色球体 - 在 z 方向上近距离和远距离:
我想在我的视图的二维平面中检索此图像的 rgb 值。我在下面的代码片段中被标记为 1 和 2 的 Pygame 和 OpenGL 方法卡住了,因为它们 return只有黑色像素。
import pygame
from pygame.locals import DOUBLEBUF, OPENGL
import OpenGL.GL as GL
import OpenGL.GLU as GLU
x1, y1, z1 = 0, 0, -5
r1 = .2
x2, y2, z2 = 0, 1, -9
r2 = .2
border_x, border_y, border_z = 200, 200, 200
field_of_view_in_deg = 45
aspect_ratio = border_x/border_y
clip_near = .1
clip_far = 200
longitude_parts = 50
latitude_parts = 50
delay = 500
red = (1, 0, 0)
green = (0, 1, 0)
pygame.init()
win = pygame.display.set_mode((border_x, border_y), DOUBLEBUF | OPENGL)
surface = pygame.Surface((border_x, border_y))
GLU.gluPerspective(field_of_view_in_deg, aspect_ratio, clip_near, clip_far)
GL.glEnable(GL.GL_DEPTH_TEST)
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glPushMatrix()
GL.glTranslatef(x1, y1, z1)
GL.glColor3fv(red)
GLU.gluSphere(GLU.gluNewQuadric(), r1, longitude_parts, latitude_parts)
GL.glPopMatrix()
GL.glPushMatrix()
GL.glTranslatef(x2, y2, z2)
GL.glColor3fv(green)
GLU.gluSphere(GLU.gluNewQuadric(), r2, longitude_parts, latitude_parts)
GL.glPopMatrix()
# 1
pixels = pygame.PixelArray(surface)
# 2
pixels = GL.glReadPixels(border_x, border_y, border_x, border_y, GL.GL_RGB,
GL.GL_INT)
pygame.display.flip()
pygame.time.wait(delay)
我的问题是:
如何从 3D 投影到定义的 2D 表面?我试图在glReadPixels
之前插入gluUnproject
,但我不完全理解这个功能returns,这里:
obj_x=0.0414213539903457, obj_y=0.0414213539903457, obj_z=-0.09999999851062896:
modelview_matrix = GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX)
projection_matrix = GL.glGetDoublev(GL.GL_PROJECTION_MATRIX)
viewport = GL.glGetIntegerv(GL.GL_VIEWPORT)
obj_x, obj_y, obj_z = GLU.gluUnProject(border_x, border_y, 0,
modelview_matrix,
projection_matrix,
viewport)
关于 2:我如何告诉 glReadPixels
从定义的表面读取?
glReadPixels
的参数指定应读取的 window 矩形。前两个参数指定从帧缓冲区读取的第一个像素的 window 坐标,第三个和第四个参数指定像素矩形的尺寸(宽度和高度)。
读取整个window(帧缓冲区)的参数是0, 0, border_x, border_y
:
pixels = GL.glReadPixels(0, 0, border_x, border_y, GL.GL_RGB, GL.GL_INT)
请注意,您可以将颜色值选择为整数值 (GL.GL_BYTE
、GL.GL_INT
) 或 [0.0, 1.0] (GL.GL_FLOAT
) 范围内的浮点值。
例如下面的代码会打印1.0,因为读取的是视图中间的红色点的红色通道:
pixels = GL.glReadPixels(0, 0, border_x, border_y, GL.GL_RGB, GL.GL_FLOAT)
x, y = 100, 100
r = pixels[x][y][0]
print(r)
使用 Pygame 和 OpenGL,我在 3D 中绘制了一个红色和一个绿色球体 - 在 z 方向上近距离和远距离:
我想在我的视图的二维平面中检索此图像的 rgb 值。我在下面的代码片段中被标记为 1 和 2 的 Pygame 和 OpenGL 方法卡住了,因为它们 return只有黑色像素。
import pygame
from pygame.locals import DOUBLEBUF, OPENGL
import OpenGL.GL as GL
import OpenGL.GLU as GLU
x1, y1, z1 = 0, 0, -5
r1 = .2
x2, y2, z2 = 0, 1, -9
r2 = .2
border_x, border_y, border_z = 200, 200, 200
field_of_view_in_deg = 45
aspect_ratio = border_x/border_y
clip_near = .1
clip_far = 200
longitude_parts = 50
latitude_parts = 50
delay = 500
red = (1, 0, 0)
green = (0, 1, 0)
pygame.init()
win = pygame.display.set_mode((border_x, border_y), DOUBLEBUF | OPENGL)
surface = pygame.Surface((border_x, border_y))
GLU.gluPerspective(field_of_view_in_deg, aspect_ratio, clip_near, clip_far)
GL.glEnable(GL.GL_DEPTH_TEST)
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glPushMatrix()
GL.glTranslatef(x1, y1, z1)
GL.glColor3fv(red)
GLU.gluSphere(GLU.gluNewQuadric(), r1, longitude_parts, latitude_parts)
GL.glPopMatrix()
GL.glPushMatrix()
GL.glTranslatef(x2, y2, z2)
GL.glColor3fv(green)
GLU.gluSphere(GLU.gluNewQuadric(), r2, longitude_parts, latitude_parts)
GL.glPopMatrix()
# 1
pixels = pygame.PixelArray(surface)
# 2
pixels = GL.glReadPixels(border_x, border_y, border_x, border_y, GL.GL_RGB,
GL.GL_INT)
pygame.display.flip()
pygame.time.wait(delay)
我的问题是:
如何从 3D 投影到定义的 2D 表面?我试图在glReadPixels
之前插入gluUnproject
,但我不完全理解这个功能returns,这里:
obj_x=0.0414213539903457, obj_y=0.0414213539903457, obj_z=-0.09999999851062896:
modelview_matrix = GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX)
projection_matrix = GL.glGetDoublev(GL.GL_PROJECTION_MATRIX)
viewport = GL.glGetIntegerv(GL.GL_VIEWPORT)
obj_x, obj_y, obj_z = GLU.gluUnProject(border_x, border_y, 0,
modelview_matrix,
projection_matrix,
viewport)
关于 2:我如何告诉 glReadPixels
从定义的表面读取?
glReadPixels
的参数指定应读取的 window 矩形。前两个参数指定从帧缓冲区读取的第一个像素的 window 坐标,第三个和第四个参数指定像素矩形的尺寸(宽度和高度)。
读取整个window(帧缓冲区)的参数是0, 0, border_x, border_y
:
pixels = GL.glReadPixels(0, 0, border_x, border_y, GL.GL_RGB, GL.GL_INT)
请注意,您可以将颜色值选择为整数值 (GL.GL_BYTE
、GL.GL_INT
) 或 [0.0, 1.0] (GL.GL_FLOAT
) 范围内的浮点值。
例如下面的代码会打印1.0,因为读取的是视图中间的红色点的红色通道:
pixels = GL.glReadPixels(0, 0, border_x, border_y, GL.GL_RGB, GL.GL_FLOAT)
x, y = 100, 100
r = pixels[x][y][0]
print(r)