关于OpenGL的一个小问题。
RT。我准备做一个3D Modeller的程序,读取点线面数据,在窗口复现结构模型。主要是一些型材(圆管、工字钢等等)、板材。但是有一个小问题,模型生成之后,因为都是一个颜色,重合在一起,无法分别有多少构件,以及边界都在什么位置
有什么方法可以在每个构件的边界上绘制出边线或者轮廓线,可以分辨。比如下图这种
这个是我实验用的代码,绘制了两根圆管,尝试在端部绘制了两条线,但是显示效果不对。
程序代码:
from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * import math def cross(a, b): #原点为O,计算OAB平面的法向 return [a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0]] def cylinder_between(P1, P2, rad): v = [P2[0]-P1[0], P2[1]-P1[1], P2[2]-P1[2]] #P1指向P2的矢量 height = math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]) #圆柱体长度(高度) axis = (1, 0, 0) if math.hypot(v[0], v[1]) < 0.001 else cross(v, (0, 0, 1)) #获得O(原点)、P1和P2的法向,用于旋转 angle = -math.atan2(math.hypot(v[0], v[1]), v[2])*180/math.pi #P1指向P2的矢量的旋转角度 glPushMatrix() glTranslate(P1[0], P1[1], P1[2]) # 平移 glRotate(angle, *axis) # 旋转 # glColor(0.5, 1, 0.5) # glutWireCylinder(rad, height, 32, 16) glColor(0, 0, 1) glutSolidCylinder(rad, height, 32, 16) # #绘制构件边界线 ----------显示效果不对, glColor(1,1,1) lineAmount = 50 glBegin(GL_LINE_LOOP) for i in range(0,lineAmount): x = rad * math.sin(i * 2 * math.pi / lineAmount) y = rad * math.cos(i * 2 * math.pi / lineAmount) glVertex2f(x, y) glEnd() glTranslate(P2[0], P2[1], P2[2]) # 平移 glBegin(GL_LINE_LOOP) for i in range(0,lineAmount): x = rad * math.sin(i * 2 * math.pi / lineAmount) y = rad * math.cos(i * 2 * math.pi / lineAmount) glVertex2f(x, y) glEnd() glPopMatrix() def draw(): glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, wnd_w/wnd_h, 0.1, 10) glMatrixMode(GL_MODELVIEW) glLoadIdentity() # 视点设置,可以按照坐标系定义来理解:相机位于坐标原点, X正轴指向视线方向,Z轴为视角向上的方向 gluLookAt(2, 2, 2, # 视点(相机)在世界坐标的位置,即坐标原点 -0.2, -0.5, 0.7, # 视向点, 即 X正轴某点 0, 0, 1) # 视点(相机)向上的点,Z轴正向某点 glClearColor(0.5, 0.5, 0.5, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # glEnable(GL_DEPTH_TEST) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) # causes wire frame # GL_FILL --------- 填充模式 # GL_LINE --------- 线框模式 # GL_POINT --------- 点模式 # glColor(1, 1, 0.5) cylinder_between([0.2, 0.4, -0.5], [-0.2, -0.4, 0.5], 0.3) # glColor(0.5, 1, 0.5) cylinder_between([-0.2, -0.4, 0.5], [-0.6, -1.2, 2.0], 0.3) glutSwapBuffers() glutPostRedisplay() def SetupRC(): # 设置灯光和渲染效果的函数,如未使用该函数,绘制出的模型无高亮和阴影,无法体现出立体感 # Light values and coordinates光照 值与坐标;环境光,漫射光,镜面光,光的坐标, ambientLight = [0.4, 0.4, 0.4, 1.0] diffuseLight = [0.7, 0.7, 0.7, 1.0] specular = [0.9, 0.9, 0.9, 1.0] lightPos = [-50.0, 200.0, 200.0, 1.0] specref = [0.6, 0.6, 0.6, 1.0] glEnable(GL_DEPTH_TEST) # Hidden surface removal glEnable(GL_CULL_FACE) # Do not calculate inside of solid object glFrontFace(GL_CCW) glEnable(GL_LIGHTING) # Setup light 0 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight) glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight) glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight) glLightfv(GL_LIGHT0, GL_SPECULAR, specular) # Position and turn on the light glLightfv(GL_LIGHT0, GL_POSITION, lightPos) glEnable(GL_LIGHT0) # Enable color tracking glEnable(GL_COLOR_MATERIAL) # Set Material properties to follow glColor values glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE) # All materials hereafter have full specular reflectivity with a moderate shine glMaterialfv(GL_FRONT, GL_SPECULAR, specref) glMateriali(GL_FRONT, GL_SHININESS, 64) glClearColor(0.0, 0.0, 0.0, 1.0) # 背景黑色 wnd_w, wnd_h = 1000, 1000 # 窗口尺寸 glutInit() # OpenGL初始化 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) # 设置显示模式 glutInitWindowSize(wnd_w, wnd_h) # 设置窗口尺寸 glutInitWindowPosition(0, 0) # 设置窗口位置(相对于显示器的左上角) glutCreateWindow("cylinder") # 创建窗口 # glViewport(0,0,300,300); glutDisplayFunc(draw) # 调用绘图函数 SetupRC() # 设置灯光效果 glutMainLoop() #进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环。