OpenGL多线绘制异常:循环仅生成单条线的问题排查
解决你的OpenGL连线问题
我看了你的代码,问题主要出在两个地方:坐标列表的生成逻辑错误,以及画线的循环嵌套完全没必要。咱们一步步来修正:
1. 先修正坐标列表pos的生成
你现在生成pos的方式完全搞错了,[[[a, b] for a in pos_x] for b in pos_y]会创建一个三维列表,每个元素都是重复的组合,根本不是你需要的“每个点的(x,y)坐标对”。正确的做法是把pos_x和pos_y里的对应元素配对,改成这样:
pos = list(zip(pos_x, pos_y))
这样pos里的每个元素就是(x, y)的元组,直接就能用来取坐标。
2. 修正画线的循环逻辑
你原来的嵌套循环for n in range(lol-1)完全多余,而且会导致同一个终点被重复添加多次。GL_LINES的规则是每两个连续的顶点组成一条线段,所以我们只需要遍历每个点,连接它和下一个点就行。另外,如果你要画闭合的图形(比如正八边形),别忘了把最后一个点和第一个点连起来。
修正后的画线代码应该是这样:
glBegin(GL_LINES) glColor3f(0.0, 1.0, 0.0) # 连接相邻的点 for m in range(lol): # 当前点 x1, y1 = pos[m] # 下一个点,最后一个点的下一个是第一个点 x2, y2 = pos[(m+1) % lol] glVertex2f(x1, y1) glVertex2f(x2, y2) glEnd()
把glBegin(GL_LINES)和glEnd()放在循环外面,这样所有线段都在同一个批次里绘制,效率更高,逻辑也更清晰。
3. 其他小问题修正
- 你原来的
glClear只在初始化时调用了一次,要是后面加旋转的话,画面会重叠,应该把glClear放到主循环里。 - 绘制点的时候,也可以把所有点放在同一个
glBegin(GL_POINTS)里,不用循环一次就调用一次glBegin/glEnd。
完整修正后的代码
import pygame from pygame.locals import * from OpenGL.GL import * from OpenGL.GLU import * import numpy as np import math as mt pos_x = [] pos_y = [] pos= [] lol = 8 def point_pos(p, r): for i in range(p): t = 2 * mt.pi * i / p x = r * mt.cos(t) pos_x.append(x) y = r * mt.sin(t) pos_y.append(y) # 正确生成坐标列表 pos = list(zip(pos_x, pos_y)) # 绘制所有点 glBegin(GL_POINTS) glColor3f(1.0, 0.0, 0.0) # 把点设为红色,和绿色的线区分开 for x, y in pos: glVertex2f(x, y) glEnd() # 绘制所有连线 glBegin(GL_LINES) glColor3f(0.0, 1.0, 0.0) for m in range(lol): x1, y1 = pos[m] x2, y2 = pos[(m+1) % lol] glVertex2f(x1, y1) glVertex2f(x2, y2) glEnd() def main(): pygame.init() display = (800,600) pygame.display.set_mode(display, DOUBLEBUF|OPENGL) gluPerspective(90, (display[0]/display[1]), 0.1, 50.0) glTranslatef(0.0,0.0, -5) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() # 每次循环都清除缓冲区,避免画面重叠 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) point_pos(lol, 2) pygame.display.flip() pygame.time.wait(10) main()
这样运行之后,你就能看到一个由红色点和绿色线组成的正八边形了。如果要画3D的正八面体,那还需要调整坐标生成的逻辑(加入z轴),不过先把2D的连线问题解决,再扩展到3D会更顺利~
内容的提问来源于stack exchange,提问作者user10372214
相关产品推荐
相关产品推荐

