如何使用glReadPixels()获得像素颜色的值?我做了很多尝试,但是得到了错误的价值。

我的背景色是blue(0,1,1),我绘制了一个边界颜色为red(1,0,0)的圆,我想获取任何边界点的颜色。所以它一定给我红色。但我正在获得背景色。

这是我在Python3和OpenGL中的代码

from OpenGL.GLU import *
from OpenGL.GLUT import *
import time
from  math import *
import numpy
import sys

def init():

    glClearColor(0.0,1.0,1.0,0.0)
    glClear(GL_COLOR_BUFFER_BIT)
    glPointSize(3.0)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0.0,640.0,0.0,640.0)

def circle():

    for i in range(361):
        m=float(50*cos(i*pi/180.0))+320
        n=float(50*sin(i*pi/180.0))+320
        setpixc(m,n)

    print(m,n)
    redinput()

def redinput():

    global x,y
    x=int(input("enter x:"))
    y=int(input("enter y:"))
    setpixc(x,y)
    pixel=[]
    c=glReadPixels(x,y,1.0,1.0,GL_RGB,GL_UNSIGNED_BYTE,None)
    print(c)
    string_pixels=numpy_pixel.tolist()
    print(string_pixels)

def setpixc(xcor,ycor):

    glBegin(GL_POINTS)
    glColor3f(1.0,0.0,0.0)
    glVertex2f(xcor,ycor)
    glEnd()
    glFlush()

def Display():

    circle()
    print("hello")

def main():

    glutInit(sys.argv)

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutInitWindowSize(600,600)
    glutInitWindowPosition(10,10)
    glutCreateWindow("line-dda")

    glutDisplayFunc(Display)

    init()
    glutMainLoop()

main()

最佳答案

您正在使用正交投影,该投影将坐标投影为矩形形式(0,0)至(640,640):

gluOrtho2D(0.0,640.0,0.0,640.0)


但是您的窗口大小是(600,600):

glutInitWindowSize(600,600)


这导致通过glVertex2f将(0,0)到(640,640)范围内的坐标绘制到(0,0)到(600,600)的视口中:

但是,当glReadPixels读取坐标时,则必须使用视口(像素)坐标。

要解决您的问题,您可以将窗口大小从(600,600)更改为(640,640):

glutInitWindowSize(640, 640)


现在例如

x=270
y=320


将返回红色像素。



请注意,如果您不想更改窗口大小,则必须将输入坐标缩放600/640。

scale = 600/640
c=glReadPixels(x*scale,y*scale,1.0,1.0,GL_RGB,GL_UNSIGNED_BYTE,None)


例如

x = 270 * 600 / 640 = 253
y = 320 * 600 / 640 = 300




还要注意,从glBegin / glEnd序列开始绘制已经有好几年了。
阅读有关Fixed Function Pipeline的信息,并参阅Vertex SpecificationShader了解最新的渲染方式。

无论如何,我建议使用双缓冲

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)


并在绘制整个圆之后进行一次缓冲区交换。跳过glFlush中的setpixc调用,并将单个glutSwapBuffers调用添加到Display函数中,并且不要忘记在渲染之前清除显示内容:

def Display():

    glClear(GL_COLOR_BUFFER_BIT)
    circle()

    glutSwapBuffers()
    glutPostRedisplay()

    redinput()
    print("hello")


如果要单点画圆,则取决于您

def circle():
    glPointSize(3.0)
    glColor3f(1.0,0.0,0.0)
    glBegin(GL_POINTS)
    for i in range(360):
        m=float(50*cos(i*pi/180.0))+320
        n=float(50*sin(i*pi/180.0))+320
        glVertex2f(m,n)
    glEnd()


或连贯的一行:

def circle():
    glLineWidth(3.0)
    glColor3f(1.0,0.0,0.0)
    glBegin(GL_LINE_LOOP)
    for i in range(360):
        m=float(50*cos(i*pi/180.0))+320
        n=float(50*sin(i*pi/180.0))+320
        glVertex2f(m,n)
    glEnd()




如果要通过单击鼠标来获取像素的颜色,可以通过glutMouseFunc设置鼠标回调:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from math import *

def init():
    global width, height

    glClearColor(0.0, 1.0, 1.0, 0.0)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0.0, width, 0.0, height)

def circle():
    glLineWidth(3.0)
    glColor3f(1.0, 0.0, 0.0)
    glBegin(GL_LINE_LOOP)
    for i in range(360):
        m=float(50*cos(i*pi/180.0))+320
        n=float(50*sin(i*pi/180.0))+320
        glVertex2f(m, n)
    glEnd()

def Mouse(button, state, x, y):
    global mouse_x, mouse_y, get_input

    if button == GLUT_LEFT_BUTTON and state == GLUT_DOWN:
        mouse_x = x
        mouse_y = height - y # the y coordinate of the mouse has to be flipped
        get_input = True

def redinput(x, y):
    c = glReadPixels(x, y, 1.0, 1.0, GL_RGB,GL_UNSIGNED_BYTE, None)
    print(c)

def Display():
    global mouse_x, mouse_y, get_input

    glClear(GL_COLOR_BUFFER_BIT)
    circle()

    glutSwapBuffers()
    glutPostRedisplay()

    if get_input:
        redinput(mouse_x, mouse_y)
        get_input=False

def main():
    global width, height

    glutInit(sys.argv)

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
    glutInitWindowSize(width, height)
    glutInitWindowPosition(10, 10)
    glutCreateWindow("line-dda")

    glutDisplayFunc(Display)
    glutMouseFunc(Mouse)

    init()
    glutMainLoop()

width   = 640
height  = 640
mouse_x = 0
mouse_y = 0
get_input = False
main()

关于python - 如何在Python和OpenGL中使用glReadPixels?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52126087/

10-11 00:49