<p>您使用的是正交投影,它将坐标投影到矩形形式<em>(0,0)</em>到<em>(640,640)</em>:</p>
<pre><code>gluOrtho2D(0.0,640.0,0.0,640.0)
</code></pre>
<p>但你的窗口大小是<em>(600600)</em>:</p>
^{pr2}$
<p>这将导致从<em>(0,0)</em>到<em>(640,640)</em>范围内的坐标绘制到从<em>(0,0)</em>到<em>(600,600)</em>的视口中,方法是<a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glVertex.xm" rel="nofollow noreferrer">^{<cd1>}</a>:</p>
<p>但是当<a href="https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glReadPixels.xml" rel="nofollow noreferrer">^{<cd2>}</a>读取坐标时,您必须使用viewport(像素)坐标。在</p>
<p>要解决您的问题,您可以将窗口大小从<em>(600600)</em>更改为<em>(640640640)</em>:</p>
<pre><code>glutInitWindowSize(640, 640)
</code></pre>
<p>现在例如</p>
<pre><code>x=270
y=320
</code></pre>
<p>将返回红色像素。在</p>
<hr/>
<p>注意,如果不想更改窗口大小,则必须按<em>600/640</em>缩放输入坐标。在</p>
<pre><code>scale = 600/640
c=glReadPixels(x*scale,y*scale,1.0,1.0,GL_RGB,GL_UNSIGNED_BYTE,None)
</code></pre>
<p>例如</p>
<pre><code>x = 270 * 600 / 640 = 253
y = 320 * 600 / 640 = 300
</code></pre>
<hr/>
<p>进一步注意,由<code>glBegin</code>/<code>glEnd</code>序列绘制的方法已经被弃用了好几年。
阅读关于<a href="https://www.khronos.org/opengl/wiki/Fixed_Function_Pipeline" rel="nofollow noreferrer">Fixed Function Pipeline</a>的文章,并查看<a href="https://www.khronos.org/opengl/wiki/Vertex_Specification" rel="nofollow noreferrer">Vertex Specification</a>和<a href="https://www.khronos.org/opengl/wiki/Shader" rel="nofollow noreferrer">Shader</a>以获得最先进的渲染方式。在</p>
<p>无论如何,我建议使用双缓冲</p>
<pre><code>glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
</code></pre>
<p>在画出整个圆之后,进行一次缓冲区交换。跳过<code>setpixc</code>中的<code>glFlush</code>调用,并向<code>Display</code>函数添加一个<code>glutSwapBuffers</code>调用,并且不要忘记在呈现之前清除显示:</p>
<pre><code>def Display():
glClear(GL_COLOR_BUFFER_BIT)
circle()
glutSwapBuffers()
glutPostRedisplay()
redinput()
print("hello")
</code></pre>
<p>如果你想用单点画圆,那就看你了</p>
<pre><code>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()
</code></pre>
<p>或者一条相干线:</p>
<pre><code>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()
</code></pre>
<hr/>
<p>如果要通过鼠标单击获得像素的颜色,可以通过<a href="https://www.opengl.org/resources/libraries/glut/spec3/node50.html" rel="nofollow noreferrer">^{<cd9>}</a>设置鼠标回拨:</p>
<pre><code>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()
</code></pre>