绘制几何体(二)

基本状态管理

OpenGl维护了很多状态和状态变量。

物体在进行渲染时可能会使用光照,纹理,隐藏表面消除,雾以及其他影响物体外观的状态。

在默认情况下这些状态大部分是处于不活动状态的,激活这些状态可能须要较大开销。

打开关闭使用这些状态下面函数:能够向下面函数传枚举值作为參数

Void glEnable();
Void glDiasble();

能够使用GLboolean glIsEnabled()函数查询某种状态是处于开启还是禁用。

大部分OpenGL函数能够用来设置更为复杂的状态变量,能够使用下面五个查询函数查询当前很多状态的当前值

glGetBooleanv(),glGetIntegerv(),glGetFloatv(),glGetDouble(),glGetPointerv();

显示点直线和多边形

为了控制被渲染点的大小,能够使用glPointSize()函数,并在參数中提供一个參数,标示所须要点的大小(像素单位)。

直线

能够指定不同宽度直线。也能够指定不同点画模式的直线。Void glLineWidth();

为了创建点画线能够使用glLineStipple()函数定义点画模式 然后用glEnable()函数启用直线点画的功能

glLineStipple(1,0x3F07);
glEnable(GL_LINE_STIPPLE);

函数原型 void glLineStipple(Glint factor,GLushort pattern);

Pattern是一个由0或者1组成的16位序列,它们依据须要进行反复。对一条特定直线进行点画处理。

从这个模式的低位開始。一个像素一个像素的进行处理。假设模型中相应1,就绘制,否则不绘制。模式能够使用factor參数扩展,它与1和0的连续子序列相乘,因此假设模式中出现了3个连续1,而且factor是2就扩展为6个1.

void drawOneLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2)
{
    glBegin(GL_LINES);
    glVertex2f((x1),(y1));
    glVertex2f((x2),(y2));
    glEnd();
}

void Init()
{
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);
}
void myDisplay()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1,1,1);
    //
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(1,0x0101);
    drawOneLine(50.0,125.0,150.0,125.0);
    glLineStipple(1,0x00ff);
    drawOneLine(150.0,125.0,250.0,125.0);
    glLineStipple(1,0x1C47);
    drawOneLine(250.0,125.0,350.0,125.0);
    //
    glLineWidth(5.0);
    drawOneLine(50.0,100.0,150.0,125.0);
    glLineStipple(1,0x00ff);
    drawOneLine(150.0,100.0,250.0,125.0);
    glLineStipple(1,0x1C47);
    drawOneLine(250.0,100.0,350.0,125.0);
    //
    glLineStipple(5,0x1C47);
    drawOneLine(50,25,350,25);
    glDisable(GL_LINE_STIPPLE);

    glFlush();

}

void reshape(int w,int h)
{
    glViewport(0,0,(GLsizei) w,(GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);

}

int _tmain(int argc, _TCHAR* argv[])
{

    glutInit(&argc,(char**)argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(400,400);
    glutCreateWindow("绘制几条线");
    Init();
    glutDisplayFunc(&myDisplay);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

点,轮廓或实心形式的多边形

多边形具有正反两面。

取决于哪一面朝向观察者,多边形可能会被渲染成不同的样子。

glPolygonMode(GLenum face,GLenum mode)函数 控制一个多边形正面和背面的画图模式。

Face參数能够是正反或者正或反。Mode參数能够是点。线或者填充,相应多边形被画成点,轮廓或者填充形式,在默认情况下,多边形正面和背面都是填充。

比如

glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_LINE);

反转和剔除多边形表面

依照约定。假设多边形的顶点以逆时针顺序出如今屏幕上,称为正面。

能够使用glFrontFace()函数向他传递一个參数表示希望他把多边形的哪一面作为正面。从而交换了OpenGL的正面和背面的概念

Void glFrontFace(GLenum mode);

默认情况下model是GL_CCW标示窗体坐标上的投影多边形的顶点顺序为逆时针方向的表面为正面。

GL_CW标示顺时针为正面。

在一个全然封闭的表面上。全部的背面多边形都是不可见的,由于它们总是被多边形正面所遮挡。假设观察者位于这个表面的外側,能够启用剔除功能。丢弃那些被OpenGL认定为背面的多边形。相似的假设观察者位于物体的内側,仅仅有背面是可见。为了告诉OpenGL丢弃那些不可见的背面和反面多边形,能够使用glCullFace()函数。当然在此之前须要打开剔除功能。

点画多边形

除了实心模式绘制。另一种窗体对齐的点画模式

glPolygonStipple()函数用于指定多边形点画模式。

void glPolyaonStipple(const GLubyte *mask);

定义填充多边形当前点画模式。

Mask參数是一个指向32X32位图的指针,后者被解释为0和1的掩码。

假设是1绘制0不绘制。

void Init()
{
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_FLAT);
}
void myDisplay()
{
    GLubyte fly[] = {
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
        0x03,0x80,0x01,0xc0,0x06,0xc0,0x03,0x60,
        0x40,0x60,0x06,0x20,0x04,0x30,0x0c,0x20,
        0x04,0x18,0x18,0x20,0x04,0x0c,0x30,0x20,
        0x04,0x06,0x60,0x20,0x44,0x03,0xc0,0x22,
        0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
        0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22,
        0x44,0x01,0x80,0x22,0x44,0x01,0x80,0xcc,
        0x66,0x01,0x80,0x66,0x33,0x01,0x80,0xcc,
        0x19,0x81,0x81,0x98,0x0c,0xc1,0x83,0x30,
        0x07,0xe1,0x87,0xe0,0x03,0x3f,0xfc,0xc0,
        0x03,0x31,0x8c,0xc0,0x03,0x33,0xcc,0xc0,
        0x06,0x64,0x26,0x60,0x0c,0xcc,0x33,0x30,
        0x18,0xcc,0x33,0x18,0x10,0xc4,0x23,0x08,
        0x10,0x63,0xc6,0x08,0x10,0x30,0x0c,0x08,
        0x10,0x18,0x18,0x08,0x10,0x00,0x00,0x08

    };

    GLubyte halftone[] ={
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
        0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,
    };

    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1,1,1);
    glRectf(25.0,25.0,125.0,125.0);
    glEnable(GL_POLYGON_STIPPLE);
    glPolygonStipple(fly);
    glRectf(125.0,25.0,225.0,125.0);
    glPolygonStipple(halftone);
    glRectf(225.0,25.0,325.0,125.0);
    glDisable(GL_POLYGON_STIPPLE);
    glFlush();
}

void reshape(int w,int h)
{
    glViewport(0,0,(GLsizei) w,(GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);

}

int _tmain(int argc, _TCHAR* argv[])
{

    glutInit(&argc,(char**)argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(400,400);
    glutCreateWindow("绘制若干个多边形");
    Init();
    glutDisplayFunc(&myDisplay);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

后面的章节使用显示列表来存储多边形点画模式来效率最大化

时间: 2024-10-13 10:05:48

绘制几何体(二)的相关文章

真实感海洋的绘制(二):使用快速傅里叶变换加速波形计算

真实感海洋的绘制(二):使用快速傅里叶变换加速波形计算 其实上一篇博文所写的\(H(\vec{x},t)?\),就是二维傅里叶变换的求和式,之前的暴力计算法属于二维的离散傅里叶变换(Discrete Fourier Transform, DFT),利用二维的快速傅里叶变换(Fast Fourier Transform, FFT)可以将复杂度从\(O(n^4)?\)降低到\(O(n^2\log{n})?\). 如果读者不熟悉FFT,强烈建议阅读<算法导论>相关章节,个人感觉没有什么资料讲得比&l

Android中View绘制优化二一---- 使用&lt;include /&gt;标签复用布局文件

本文原创, 转载请注明出处:http://blog.csdn.net/qinjuning 译二: 使用<include />标签复用布局文件  翻译地址:http://developer.android.com/training/improving-layouts/reusing-layouts.html#Merge 尽管Android通过内置了各种各样的控件提供了微小.可复用的交互性元素,也许你需要复用较大的 组件 ---- 某些特定布局文件 .为了更有效率复用的布局文件,你可以使用<

Qt绘制文本二 弧形路径 正弦函数路径

void WgtText::paintEvent(QPaintEvent *event) { QPainter painter(this); QString m_string("abcdefghijklmnopqrstuvwxy"); int font_size = 15; float x0 = font_size * m_string.count() * 0.5; int YSize = font_size * m_string.count() * 0.5; for(int i=0;

NeHe OpenGL教程 第十八课:二次几何体

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第十八课:二次几何体 二次几何体: 利用二次几何体,你可以很容易的创建球,圆盘,圆柱和圆锥. 二次曲面是一种画复合对象的方法,这种方法通常并不需要很多的三角形.我们将要使用第七课的代码.我们将要增加7个变量以及修改纹理以增加一些变化

Directx11学习笔记【十五】 基本几何体的绘制

本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/ 前面实现简单地形的教程,我们只是绘制了一个网格,这一次我们来学习一下几种基本几何体的绘制,包括平面网格.立方体.圆柱和球体等. 原来在GeometryGenerator类中只给出了CreateGrid一个方法来绘制网格,现在让我们添加其他方法绘制一些几何体. 为了方便绘制几何体方法的调用,GeometryGenerator类我们使用了单例模式.很简单,将构造函数设为pr

NeHe OpenGL教程 第二十二课:凹凸映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第二十二课:凹凸映射 凹凸映射,多重纹理扩展: 这是一课高级教程,请确信你对基本知识已经非常了解了.这一课是基于第六课的代码的,它将建立一个非常酷的立体纹理效果. 这一课由Jens Schneider所写,它基本上是由第6课改写而来

[ html canvas 绘制曲线三种方法 ] canvas绘图 绘制曲线三种方法属性实例演示

1 <!DOCTYPE html> 2 <html lang='zh-cn'> 3 <head> 4 <title>Insert you title</title> 5 <meta name='description' content='this is my page'> 6 <meta name='keywords' content='keyword1,keyword2,keyword3'> 7 <meta htt

微信二维码登录原理

在电脑上使用微信时,你可能已经发现微信不提供传统的账号密码登陆,取而代之的是通过扫描二维码进行登陆.今天就要研究下次登陆方式微信时如何实现的? 1.每次用户打开PC端登陆请求,系统返回一个唯一的uid,并将uid的信息绘制成二维码返回给用户.这里的uid一定是唯一的,否则就会造成你登陆了其他用户的账号或者其他用户登陆你的账号. 2.当用户使用登陆后的微信扫描该二维码的时候,会将这个uid和手机上的微信账号及密码产生的token进行绑定,并上传到服务器. 3.WEB通过JS不断的向后端发起请求,查

android性能优化练习:过度绘制

练习:https://github.com/zhangbz/AndroidUIPorblems 查看过度绘制 在开发者选项中开启"调试GPU过度绘制" 判断标准 无色:没有过度绘制,即只绘制了一次 蓝色:一倍过度绘制 绿色:二倍过度绘制 淡红色:三倍过度绘制 红色:四倍或以上过度绘制 实践 其中"This is test"四次或以上倍数过度绘制,其背景三倍,按钮两倍,按钮中的文字三倍,背景一倍. Mainactivity优化 首先分析布局文件,发现嵌套的Linear