You are using an orthographic projection, which which projects the coordinates to the rectangle form (0, 0) to (640, 640):
gluOrtho2D(0.0,640.0,0.0,640.0)
But your window size is (600, 600):
glutInitWindowSize(600,600)
This causes that the coordinates in the range from (0, 0) to (640, 640) are drawn to the viewport from (0, 0) to (600, 600), by glVertex2f
:
But when the coordinates are read by glReadPixels
, then you would have to use viewport (pixel) coordinates.
To solve your is you can change the window size from (600, 600) to (640, 640):
glutInitWindowSize(640, 640)
Now e.g.
x=270
y=320
will return a red pixel.
Note, if you don't want to change the window size, then you would have to scale the input coordinates by 600/640.
scale = 600/640
c=glReadPixels(x*scale,y*scale,1.0,1.0,GL_RGB,GL_UNSIGNED_BYTE,None)
e.g.
x = 270 * 600 / 640 = 253
y = 320 * 600 / 640 = 300
Further note, that drawing by glBegin
/glEnd
sequences is deprecated since several years.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.
Anyway, I recommend to use double buffering
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
and to do a single buffer swap, after the entire circle was drawn. Skip the glFlush
call in setpixc
and add a single glutSwapBuffers
call to the Display
function and don't forget to clear the display before rendering:
def Display():
glClear(GL_COLOR_BUFFER_BIT)
circle()
glutSwapBuffers()
glutPostRedisplay()
redinput()
print("hello")
It is up to you if you want to draw the circle by single points
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()
or a coherent line:
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()
If you want to get the color of a pixel by a mouse click, the you can set a mouse call back by 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()