OpenGL GL_LINES端点没有加入

时间:2010-12-26 00:43:47

标签: opengl

alt text我遇到了GL_LINES块的问题......下面示例中的行不会在末端连接(尽管有时它会随机决定连接一个或两个角)。相反,端点在彼此的1个像素内(留下一个未完全平方的角;如果这是有意义的话)。这是一个绘制实心1像素矩形的简单块。

 glBegin(GL_LINES);

  glColor3b(cr, cg, cb);

  glVertex3i(pRect->left, pRect->top, 0);
  glVertex3i(pRect->right, pRect->top, 0);

  glVertex3i(pRect->right, pRect->top, 0);
  glVertex3i(pRect->right, pRect->bottom, 0);

  glVertex3i(pRect->right, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->bottom, 0);

  glVertex3i(pRect->left, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->top, 0);

 glEnd();

下面的示例似乎可以解决问题,给我一个锋利的方角;但是我不能接受它,因为我不知道它为什么这样做......

 glBegin(GL_LINES);

  glColor3b(cr, cg, cb);

  glVertex3i(pRect->left, pRect->top, 0);
  glVertex3i(pRect->right + 1, pRect->top, 0);

  glVertex3i(pRect->right, pRect->top, 0);
  glVertex3i(pRect->right, pRect->bottom + 1, 0);

  glVertex3i(pRect->right, pRect->bottom, 0);
  glVertex3i(pRect->left - 1, pRect->bottom, 0);

  glVertex3i(pRect->left, pRect->bottom, 0);
  glVertex3i(pRect->left, pRect->top - 1, 0);

 glEnd();

任何OpenGL程序员都可以提供帮助,我将不胜感激:)

图片是屏幕截图的放大视图。如您所见,左上角未连接。右上角是。看不到左下角和右下角,没有连接。

视口设置为每个坐标1到1个像素。

glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, __nRendererWidth, __nRendererHeight, 0, -1, 100);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable (GL_TEXTURE_2D);

4 个答案:

答案 0 :(得分:13)

来自question 14.090 of the OpenGL FAQ

  

14.090如何获得线条的精确像素化?

     

OpenGL规范允许使用各种线条渲染硬件,因此可能无法进行精确的像素化。

     

您可能希望阅读OpenGL规范并熟悉钻石退出规则。熟悉此规则将为您提供获得精确像素化的最佳机会。简而言之,钻石退出规则指定每个像素内存在菱形区域。仅当该线的数学定义退出该像素内刻的菱形时,才会通过线栅格化像素。

然后从OpenGL Core Profile specification的第3.5节开始:

  

由于钻石退出规则的初始条件和最终条件可能难以实现,因此允许使用其他线段栅格化算法,但须遵守以下规则:

     
      
  1. 算法生成的片段坐标在x或y窗口坐标中与菱形退出规则生成的相应片段的偏差不得超过一个单位。
  2.   
  3. 算法产生的碎片总数可能与钻石退出规则产生的碎片总数不同,不超过一个。
  4.   
  5. 对于x-major线,不会产生位于同一窗口坐标列中的两个碎片(对于y主线,同一行中不得出现两个碎片)。
  6.   
  7. 如果两个线段共享一个公共端点,并且两个线段都是x-major(从左到右或从右到左)或y-major(从下到上或从顶部到顶部)到底部),然后栅格化两个段可能不会产生重复的片段,也不会省略任何片段,以便中断连接段的连续性。
  8.   

所以,答案是规范不需要像你期望的那样加入行。如果你的线都是x-major或者所有y-major,那么上面的规则#4会给你预期的输出,但是在你的矩形中,你在x-major和y-major线之间交替。

如果您希望保证连接的线条没有间隙或重叠,则应使用GL_LINE_LOOP(或GL_LINE_STRIP呈现未连接的系列,而不是GL_LINES }。

答案 1 :(得分:5)

由于您正在绘制闭合多边形,因此您可能希望使用GL_LINE_LOOP

答案 2 :(得分:3)

结果,最好只使用GL_QUADS绘制线条。不像使用GL_LINES那样简单,但它有效:

glBegin(GL_QUADS);

    glColor3b(bRed, bGreen, bBlue);

    // Draw the top line
    glVertex2i(left, top);
    glVertex2i(right + 1, top);
    glVertex2i(right + 1, top + 1);
    glVertex2i(left, top + 1);

    // Draw the right line
    glVertex2i(right, top);
    glVertex2i(right + 1, top);
    glVertex2i(right + 1, bottom + 1);
    glVertex2i(right, bottom);

    // Draw the bottom line
    glVertex2i(left, bottom);
    glVertex2i(right + 1, bottom);
    glVertex2i(right + 1, bottom + 1);
    glVertex2i(left, bottom + 1);

    // Draw the left line
    glVertex2i(left, top);
    glVertex2i(left + 1, top);
    glVertex2i(left + 1, bottom + 1);
    glVertex2i(left, bottom);

glEnd();

答案 3 :(得分:1)

我无法完全解决这个问题,但这些链接对于遇到同样问题的人来说有点帮助......我意识到这是一个很多人都经历过的广泛问题(而且这是一个如此强大的库让人感到羞耻很难执行这样的原始操作,比如用像素单位精度绘制一条线。)

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=235566 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=237621