openGL 线型和线宽以及线抗锯齿

转自:http://www.tuicool.com/articles/vMz67rR

openGL 线型和线宽以及线抗锯齿

一、 线宽

Opengl 的线宽设置: glLineWidth(width); width 为 float 类型值,在 0~10.0 ,大于 10 以上按 10 来处理。

若开启线的反走样 glEnable(GL_LINE_SMOOTH); ,设置小数值才起作用,否则就四舍五入的处理整数了。

二、  线型

函数为 glLineStipple(factor, Pattern[PatternMode]);

其中 pattern 值可以是任意的你想要的,把 01 转换为 16 进制的值就可以了。 Factor 为缩放因子。

pattern 参数是由 1 或 0 组成的 16 位序列,它们根据需要进行重复,对一条特定的直线进行点画处理。从这个模式的低位开始,一个像素一个像素的进行处理。如果模式中对应的位是 1 ,就绘制这个像素,否则就不绘制。模式可以使用 factor 参数(表示重复因子)进行扩展,它与 1 和 0 的连续子序列相乘。因此,如果模式中出现了 3 个 1 ,并且 factor 是 2 ,那么它们就扩展为 6 个连续的 1 。必须以 GL_LINE_STIPPLE 为参数调用 glEnable() 才能启用直线点画功能。

三、线宽代码

<span style="font-size:14px;">void show_width_lines(int width,float red,float green,float blue)
{
  glColor3f(red,green,blue);
  
  width = 1.0f;
  float PI = 3.1415926;
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
  glColor3f(red,green,blue);
  //禁用反走样
  glDisable(GL_BLEND);
  glDisable(GL_LINE_SMOOTH);	
  
  // line_1	
  for (int i = 0; i < 8;i++ )
  {
    glLineWidth(width);	
    glBegin(GL_LINE_STRIP);
    glVertex3f(5,5*(i+1), 0.0);
    glVertex3f(100,5*(i+1)-qingxie_,0.0);
    glEnd();
    //直线宽度增加0.5
    width += 2.0;
  }
    
  //启用反走样
  glEnable(GL_BLEND);
  glEnable(GL_LINE_SMOOTH);
  glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);  // Antialias the lines
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  //初始化直线宽度
  width=1.0;	
  // line_2	
  glColor4f(0,green,0,1.0);
  for (int i = 0; i < 8;i++ )
  {	
    glLineWidth(width);
    glBegin(GL_LINE_STRIP);
    glVertex3f(5, 50+1*(i+1), 0.0);
    //glVertex3f(50,50+2*(i+1)-qingxie_, 0.0);
    glVertex3f(80,50+3*(i+1)+qingxie_, 0.0);
    //glVertex3f(100,50+4*(i+1)-qingxie_, 0.0);
    glVertex3f(120,50+5*(i+1)+qingxie_, 0.0);
    glEnd();
    //宽度累加
    width += 2.0;
  }
  glFlush();
}
</span>
四、线型代码
<span style="font-size:14px;">void show_dot_lines(int width,float red,float green,float blue)
{
  int PatternMode = 0;            //线型模式

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
  glColor3f(red,green,blue);
  int Pattern[6]=                  //定义了6种线型
  {
    //点线 1000100010001000, 表示实际画线的点,反序后转换成16进制就是0x1111 dotted
    //.  .  .  .  .  .  .  .  .  .  .  .  .  .
    //0x1111,
    0x0101,

    //点划线    1111111111100100  dot dash
    //____ . ____ . _____ . _____. _____
    0x27FF,
    //0x1C47,

    //中心线    1111111111001100  centre line
    //_____ _ _____ _ _____ _ _____ _ _____
    0x33FF,

    //虚线  1111110011111100   dashed
    //____  ____  ____  ____  ____  ____  ____
    0x3F3F,

    //双点划线  1111111100100100  double dot dash
    // ____ . . ____ . . ____ . . ____ . . ____
    0x24FF,

    //三点划线  111111110101010 tri_dot_dash
    // ____ . . ____ . . ____ . . ____ . . ____
    0x55FF
  };

  static float angle = 0.0;

  glEnable(GL_BLEND);
  glEnable(GL_LINE_SMOOTH);
  glEnable(GL_LINE_STIPPLE);
  //初始化直线宽度
  width=2.0;	
  // line_2	
  glColor3f(0,0,blue);
  for (int i = 0; i<6; i++)
  {
    int PatternMode = i;
    glLineStipple(1, Pattern[PatternMode]);
    glLineWidth(width);	
    glBegin(GL_LINES);
    glVertex3f(1,23+i*5, 0.0);
    glVertex3f(50,23+i*5-qingxie_, 0.0);
    glEnd();
  }

  width = 1.0;
  glColor3f(red,0,0);
  for (int i = 0; i<6; i++)
  {
    int PatternMode = i;
    glLineStipple(1, Pattern[PatternMode]);
    glLineWidth(width);	
    glBegin(GL_LINES);
    glVertex3f(20,50+i*5, 0.0);
    glVertex3f(50,50+i*5-qingxie_, 0.0);
    glEnd();
  }

  glDisable(GL_LINE_STIPPLE); 
  glFlush();

}</span>

五、结果

线的线宽

很明显,绿色线开启反走样,而淡红色的没有。

线型--点划线的实现效果

开启的反走样,为fastest. 当然你可以根据你效果与效率之间选择自己需要的。

六、 全部 实现代码和工程

<span style="font-size:14px;">
#include <Windows.h>
#include "glew.h"
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"./glew32.lib")
#include <math.h>
//

#include "glut.h"
#include<stdio.h>
#include<stdlib.h>


#define drawOneLine(x1,y1,x2,y2) glBegin(GL_LINES);glVertex3f((x1),(y1),0); glVertex3f((x2),(y2),0);glEnd();

#define  qingxie_  2.0
// function declear
void init (void)
{
  glClearColor (1.0, 1.0, 1.0, 0.0);  // Set display-window color to white.
  glMatrixMode (GL_PROJECTION);       // Set projection parameters.
  gluOrtho2D (0.0, 200.0, 0.0, 150.0);
}

void show_width_lines(int width,float red,float green,float blue)
{
  glColor3f(red,green,blue);
  
  width = 1.0f;
  float PI = 3.1415926;
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
  glColor3f(red,green,blue);
  //禁用反走样
  glDisable(GL_BLEND);
  glDisable(GL_LINE_SMOOTH);	
  
  // line_1	
  for (int i = 0; i < 8;i++ )
  {
    glLineWidth(width);	
    glBegin(GL_LINE_STRIP);
    glVertex3f(5,5*(i+1), 0.0);
    glVertex3f(100,5*(i+1)-qingxie_,0.0);
    glEnd();
    //直线宽度增加0.5
    width += 2.0;
  }
    
  //启用反走样
  glEnable(GL_BLEND);
  glEnable(GL_LINE_SMOOTH);
  glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);  // Antialias the lines
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  //初始化直线宽度
  width=1.0;	
  // line_2	
  glColor4f(0,green,0,1.0);
  for (int i = 0; i < 8;i++ )
  {	
    glLineWidth(width);
    glBegin(GL_LINE_STRIP);
    glVertex3f(5, 50+1*(i+1), 0.0);
    //glVertex3f(50,50+2*(i+1)-qingxie_, 0.0);
    glVertex3f(80,50+3*(i+1)+qingxie_, 0.0);
    //glVertex3f(100,50+4*(i+1)-qingxie_, 0.0);
    glVertex3f(120,50+5*(i+1)+qingxie_, 0.0);
    glEnd();
    //宽度累加
    width += 2.0;
  }
  glFlush();
}

void Line3f(GLfloat fromX, GLfloat fromY, GLfloat fromZ,
      GLfloat toX, GLfloat toY, GLfloat toZ)
{
  glBegin(GL_LINES);
  glVertex3f(fromX, fromY, fromZ);
  glVertex3f(toX, toY, toZ);
  glEnd();
}


void show_dot_lines(int width,float red,float green,float blue)
{
  int PatternMode = 0;            //线型模式

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
  glColor3f(red,green,blue);
  int Pattern[6]=                  //定义了6种线型
  {
    //点线 1000100010001000, 表示实际画线的点,反序后转换成16进制就是0x1111 dotted
    //.  .  .  .  .  .  .  .  .  .  .  .  .  .
    //0x1111,
    0x0101,

    //点划线    1111111111100100  dot dash
    //____ . ____ . _____ . _____. _____
    0x27FF,
    //0x1C47,

    //中心线    1111111111001100  centre line
    //_____ _ _____ _ _____ _ _____ _ _____
    0x33FF,

    //虚线  1111110011111100   dashed
    //____  ____  ____  ____  ____  ____  ____
    0x3F3F,

    //双点划线  1111111100100100  double dot dash
    // ____ . . ____ . . ____ . . ____ . . ____
    0x24FF,

    //三点划线  111111110101010 tri_dot_dash
    // ____ . . ____ . . ____ . . ____ . . ____
    0x55FF
  };

  static float angle = 0.0;

  glEnable(GL_BLEND);
  glEnable(GL_LINE_SMOOTH);
  glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);  // 反走样的fastest效果,也可以根据需要选择GL_NICEST.etc.
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  glEnable(GL_LINE_STIPPLE);	
  
  //初始化直线宽度
  width=5.0;	
  // line_2	
  glColor3f(0,0,blue);
  for (int i = 0; i<6; i++)
  {
    int PatternMode = i;
    glLineStipple(i, Pattern[PatternMode]);
    glLineWidth(width);	
    glBegin(GL_LINES);
    glVertex3f(1,23+i*5, 0.0);
    glVertex3f(50,23+i*5-qingxie_, 0.0);
    glEnd();
  }

  width = 1.0;
  glColor3f(red,0,0);
  for (int i = 0; i<6; i++)
  {
    int PatternMode = i;
    glLineStipple(i, Pattern[PatternMode]);
    glLineWidth(width);	
    glBegin(GL_LINES);
    glVertex3f(2,50+i*5, 0.0);
    glVertex3f(50,50+i*5-qingxie_, 0.0);
    glEnd();
  }

  glDisable(GL_LINE_STIPPLE); 
  glDisable(GL_BLEND);
  glFlush();

}

void pointFun()
{
  float red = 1.0,green = 0.5,blue = 0.5;
  glClear (GL_COLOR_BUFFER_BIT);
  
  // 去掉注释就可以看线宽效果了。
  //show_width_lines(5,red,green,blue);
  show_dot_lines(5,red,green,blue);
  glFlush();
}

int main (int argc, char** argv)
{
  glutInit (&argc, argv);                         // Initialize GLUT.
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);   // Set display mode.
  glutInitWindowPosition (50, 100);   // Set top-left display-window position.
  glutInitWindowSize (1000, 800);      // Set display-window width and height.
  //glutFullScreen();
  glutCreateWindow ("An Example OpenGL Program By Qiu"); // Create display window.
  init();                           // Execute initialization procedure.

  // draw position.
  glTranslatef(50.0f, 50.0f,0.0f);

  glutDisplayFunc (pointFun);       // Send graphics to display window.
  glutMainLoop ( );// Send graphics to display window.                  // Display everything and wait.
  return 0;
}
</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值