Pygame, OpenGL: проецирование 3D-значений rgb на 2D-поверхность - PullRequest
0 голосов
/ 06 января 2019

С помощью Pygame и OpenGL я рисую красную и зеленую сферы в 3D - близко и далеко в направлении z:

spheres

Я хотел бы получить значения rgb этого изображения в 2D плоскости моего обзора. Я застрял с моим подходом Pygame и OpenGL, отмеченным как 1 и 2 в следующем фрагменте кода, поскольку они возвращают только черные пиксели.

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 поверхность? Я пытался вставить gluUnproject до glReadPixels, но я не совсем понимаю, что возвращает эта функция, здесь:

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 читать с определенной поверхности?

1 Ответ

0 голосов
/ 06 января 2019

Параметры для glReadPixels указывают прямоугольник окна, который должен быть прочитан. Первые 2 параметра задают координаты окна первого пикселя, считываемого из буфера кадра, а 3-й и 4-й параметры определяют размеры прямоугольника пикселя (ширина и высота).

Параметры для чтения всего окна (кадровый буфер): 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)
...