简体   繁体   English

Pygame、OpenGL:将 3D rgb 值投影到 2D 表面

[英]Pygame, OpenGL: Project 3D rgb values to 2D surface

With Pygame and OpenGL, I plot a red and a green sphere in 3D - close and far in z-direction:使用 Pygame 和 OpenGL,我在 3D 中绘制了一个红色和一个绿色的球体 - 在 z 方向上的近距离和远距离:

球体

I would like to retrieve the rgb values of this image in the 2D plane of my view.我想在我视图的 2D 平面中检索此图像的 rgb 值。 I got stuck with my Pygame and OpenGL approach marked as 1 and 2 in the following code snippet as they return solely black pixels.我在下面的代码片段中被我的 Pygame 和 OpenGL 方法标记为12 ,因为它们只返回黑色像素。

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)

My questions are:我的问题是:

How can I project from 3D to the defined 2D surface?如何从 3D 投影到定义的 2D 表面? I tried to insert gluUnproject before glReadPixels , but I do not entirely understand what this function returns, here:我试图在glReadPixels之前插入gluUnproject ,但我不完全理解这个函数返回什么,这里:

obj_x=0.0414213539903457, obj_y=0.0414213539903457, obj_z=-0.09999999851062896: 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)

Concerning 2 : How can I tell glReadPixels to read from the defined surface?关于2 :如何告诉glReadPixels从定义的表面读取?

The parameters to glReadPixels specify the window rectangle which should be read. glReadPixels的参数指定应该读取的窗口矩形。 The first 2 parameters specify the window coordinates of the first pixel that is read from the frame buffer and the 3rd and 4th parameter specify the dimensions of the pixel rectangle (width and height).前两个参数指定从帧缓冲区读取的第一个像素的窗口坐标,第三个和第四个参数指定像素矩形的尺寸(宽度和高度)。

The parameters to read the entire window (framebuffer) are 0, 0, border_x, border_y :读取整个窗口(framebuffer)的参数是0, 0, border_x, border_y

pixels = GL.glReadPixels(0, 0, border_x, border_y, GL.GL_RGB, GL.GL_INT)   

Note, you can choose the color values as integer values ( GL.GL_BYTE , GL.GL_INT ) or floating point values in the range [0.0, 1.0] ( GL.GL_FLOAT ).请注意,您可以将颜色值选择为整数值( GL.GL_BYTEGL.GL_INT )或 [0.0, 1.0] 范围内的浮点值( GL.GL_FLOAT )。

eg The following code will print 1.0 , because the red color channel of the red point in the middle of the view is read: eg 下面的代码会打印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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM