如何使用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 :(得分:2)
您正在使用正交投影,该投影将坐标投影为(0,0)到(640,640)的矩形形式:
gluOrtho2D(0.0,640.0,0.0,640.0)
但是您的窗口大小是(600,600):
glutInitWindowSize(600,600)
这将导致(0,0)到(640,640)范围内的坐标从(0,0 )到(600,600),由glVertex2f
:
但是当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 Specification和Shader了解最新的渲染方式。
无论如何,我建议使用双缓冲
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()
答案 1 :(得分:1)
您的代码有几个问题。
您要搜索的答案在“红皮书”(即OpenGL编程指南)中进行了说明,尤其是在附录G,编程技巧中。我还建议您阅读附录H,不变性。可通过以下链接找到在线版本:https://www.glprogramming.com/red/
也是
您对每个点都使用glBegin / glEnd对,这对 资源。您可以使用一个glBegin / glEnd对绘制一个完整的圆:
glBegin(GL_POINTS)
glColor3f(1.0, 0.0, 0.0)
for i in range(361):
x=float(50*cos(i*pi/180.0))+320
y=float(50*sin(i*pi/180.0))+320
glVertex2f(x,y)
glEnd()
您正在使用非常密集的GL_POINTS集来绘制圆,但这不会影响正确的圆。如果半径较小,则将对同一窗口像素进行多次栅格化。如果您增加足够的半径,将导致一组未连接的点。在您的情况下,我将使用GL_LINE_LOOP:
glBegin(GL_LINE_LOOP)
glColor3f(1.0, 0.0, 0.0)
for i in range(0, 360, 5):
x=float(50*cos(i*pi/180.0))+320
y=float(50*sin(i*pi/180.0))+320
glVertex2f(x,y)
glEnd()