Вы используете ортогональную проекцию, которая проецирует координаты в прямоугольную форму (0, 0) до (640, 640) :
gluOrtho2D(0.0,640.0,0.0,640.0)
Но ваш размер окна (600, 600) :
glutInitWindowSize(600,600)
Это приводит к тому, что координаты в диапазоне от (0, 0) до (640, 640) отображаются в области просмотра из (0, 0) * От 1018 * до (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
считается устаревшим в течение нескольких лет.
Прочтите о конвейере с фиксированными функциями и посмотрите Вершинные спецификации и Шейдер для современного способа рендеринга.
В любом случае, я рекомендую использовать двойную буферизацию
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()