opengl中橡皮筋技术的实现

修改添加项:

C/C++ 中的 __WINDOWS

linker 中的 opengl32.lib glu32.lib glaux.lib

实验注意点:

橡皮筋技术的关键在于控制图形随着用户的操作(鼠标移动)而不断发生着变化,此时需要擦除原有的图形同时生成新的图形。橡皮筋技术有两种实现方法:

一种是利用颜色的异或操作,对原有图形并不是擦除,而是在绘制一条同样的直线段并与原图形进行异或操作,此时原图形会从屏幕上消失;另一种是利用双缓存

技术,绘制图形是分别绘制到两个缓存,交替显示。这里我们利用双缓存技术实现橡皮筋技术。

程序中经常使用的函数:

1/鼠标函数,对鼠标在窗口范围内的按键按下或松开时间进行处理:glutMouseFunc(MousePlot);其中MousePot函数是鼠标响应函数,

void MousePlot(Glint button,Glint action,Glint xMouse,Glint yMouse);

2/处理鼠标移动的注册函数:

当一个或多个鼠标按键被按下时在窗口内移动的注册函数:glutMotionFunc(MouseMove);

当鼠标按键没有被按下时在窗口内移动的注册函数:glutPassiveMotionFunc(PassiveMouseMove);

void Mousemove(Glint xMouse,Glint yMouse); void PassiveMouseMove(Glint xMouse,Glint yMouse);

3/指定窗口双缓存:glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

4/确定窗口的高度以解决坐标对应的问题,glutReshapeFunc(ChangeSize),当窗口的大小发生变化是调用的函数。该函数的原型为void ChangeSize(int w,int h);

w和h表示变化后窗口的宽度和高度。glViewport(0,0,w,h);重新指定窗口的显示区域。

程序及注释如下:

#include"gl/glut.h"
int ipointnum=0;//已确定点的数目
int x1=0,x2=0,y1=0,y2=0;//确定的点坐标
int winWidth=400,winHeight=300;//窗口的宽度和高度
void Initial(void)
{
    glClearColor(1.0f,1.0f,1.0f,1.0f);//设置窗口的背景颜色
}

void ChangeSize(int w,int h)
{
    winWidth=w;winHeight=h;//保存当前窗口的大小
    glViewport(0,0,w,h);//指定窗口显示区域
    glMatrixMode(GL_PROJECTION);//指定设置投影参数
    glLoadIdentity();//调用单位矩阵,去掉以前的投影参数设置
    gluOrtho2D(0.0,winWidth,0.0,winHeight);//设置投影参数
}
void Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);//用当前背景色填充窗口
    glColor3f(1.0f,0.0f,0.0f);//指定当前的绘图颜色
    if(ipointnum>=1)
    {
        glBegin(GL_LINES);//绘制直线段
        glVertex2i(x1,y1);
        glVertex2i(x2,y2);
        glEnd();
    }
    glutSwapBuffers();//交换缓冲区
}
void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse)
{
    if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN)
    {
        if(ipointnum==0||ipointnum==2)
        {
            ipointnum=1;
            x1=xMouse;y1=winHeight-yMouse;//确定直线段的第一个端点
        }
        else
        {
            ipointnum=2;
            x2=xMouse;y2=winHeight-yMouse;//确定直线段的第二个端点
            glutPostRedisplay();//指定窗口重新绘制
        }
    }
    if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN)
    {
        ipointnum=0;
        glutPostRedisplay();
    }
}
void PassiveMouseMove(GLint xMouse,GLint yMouse)
{
    if(ipointnum==1)
    {
       x2=xMouse;
       y2=winHeight-yMouse;//将当前鼠标位置指定为直线的未固定端点
       glutPostRedisplay();
    }
}
int main(int argc,char *argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//使用双缓存及RGB模型
    glutInitWindowSize(400,300);//指定窗口的大小
    glutInitWindowPosition(100,100);//指定窗口在屏幕上的位置
    glutCreateWindow("橡皮筋技术");
    glutDisplayFunc(Display);
    glutReshapeFunc(ChangeSize);//指定窗口再整形回调函数
    glutMouseFunc(MousePlot);//指定鼠标响应函数
    glutPassiveMotionFunc(PassiveMouseMove);//指定鼠标移动响应函数
    Initial();
    glutMainLoop();//启动主GLUT时间处理循环
    return 0;
}

时间: 2024-10-09 13:45:47

opengl中橡皮筋技术的实现的相关文章

OpenGL中实现双缓冲技术

在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);.这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲. 2. 调用glutDisplayFunc(display)注册回调函数时, 在回调函数中所有绘制操作完成后调用glutSwapBuffers()交换两个缓冲区指针. 3. 调用

什么是OpenGL中的深度、深度缓存、深度测试?

原文来自http://blog.csdn.net/xiaoquanhuang/article/details/6613705 1)直观理解 深度其实就是该象素点在3d世界中距离摄象机的距离,深度缓存中存储着每个象素点(绘制在屏幕上的)的深度值!深度测试决定了是否绘制较远的象素点(或较近的象素点),通常选用较近的,而较远优先能实现透视的效果!!! 2)Z值(深度值).Z buffer(深度缓存) 下面先讲讲Z坐标.Z坐标和X.Y坐标一样.在变换.裁减和透视除法后,Z的范围为-1.0~1.0.Dep

利用键盘实现橡皮筋技术

键盘输入注册函数:glutKeyboardFunc(Key);它指定了程序在运行状态时,按下键盘上的任意一个键都会调用Ker函数: void Key(unsigned char key,int x,int ,y):参数key的取值是一个字符值或对应的ASCLL编码,而(x,y)则是按下键盘时窗口中当前屏幕光标相对于 窗口左上角的位置坐标. 代码如下: #include"gl/glut.h" int ipointnum=0;//已确定点的数目 int x1=0,x2=0,y1=0,y2=

C# GDI+ 实现橡皮筋技术

原文 C# GDI+ 实现橡皮筋技术 应该有很多人都在寻找这方面的资料,看看下面我做的,或许对你会有所帮助,但愿如此. 为了实现橡皮筋技术,我用了两种方法: 第一种是利用ControlPaint.DrawReversibleLine(Point start,Point end, Color BackColor)方法,原理:在屏幕上指定的起始点和结束点内绘制具有指定背景色的可逆线,再次绘制同一条线会逆转该方法的结果.使用该方法绘制线类似于反转屏幕的一个区域,不过它提供了更好的性能适用于更广泛的颜色

OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间使用.OpenGL3.0已经废弃此方法.每个glVertex与GPU进行一次通信,十分低效. glBegin(GL_TRIANGLES); glVertex(0, 0); glVertex(1, 1); glVertex(2, 2); glEnd(); 2.显示列表(glCallList) 每个gl

openGL中的混合

    之前在项目中就使用过混合,但是研究的不深入,近期美术的一个需求让我下决心重新深入的研究了一下混合以及它在cocos2d-x中的使用,在这里分享给大家. 混合(blend,有些翻译书上把它称作混融,以下简称混合),在openGL中,当一个输入的片元通过了所有相关的片元测试,就可以在与颜色缓存中当前的内容通过某种方式进行合并了.最简单的,也是默认的方式,就是直接覆盖已有的值,实际上不能称作是合并.除此之外,我们也可以将帧缓存中已有的颜色与输入的片元颜色进行混合.这是在openGL流程上的定义

OpenGL中的颜色混合功能(一)

我们知道,材料属性和光照参数可以极大地增加图形的逼真度,但除此之外,我们在对现实世界进行建模时,有许多效果是通过混合颜色的方式实现的.透明的物体,像是玻璃水杯,在它后面发射过来的光会与透明物体的颜色混合在一起.这种透明在OpenGL中的实现方式,是通过首先绘制背景物体,然后把前景物体(比如水杯)与颜色缓冲区中已经存在的颜色进行混合而实现的.在这一过程中,颜色的alpha值成分发挥了重要作用. 颜色的混合功能 在一般情况下,OpenGL在渲染时把颜色值存放在颜色缓冲区中,把每个片段(像素)的深度值

OpenGL中创建聚光灯的效果

现在,我们使用如下的数组来指定一个光源的位置: // 指定光源位置的数组 GLfloat lightPos[] = {0.0f, 0.0f, 75.0f, 1.0f}; // 设置光源0的位置 glLightfv(GL_LIGHT0,GL_POSITION,lightPos); lightPos数组的最后一个值在此为1.0,它表示光源的实际位置就在(X,Y,Z)所表示的位置.在默认情况下,光线从这个位置均匀地向四周发射.如果我们把lightPos数组的最后一个值设为0.0,可以使光源看上去像是来

转:LoadRunner中参数化技术详解

LoadRunner中参数化技术详解 LoadRunner在录制脚本的时候,只是忠实的记录了所有从客户端发送到服务器的数据,而在进行性能测试的时候,为了更接近真实的模拟现实应用,对于某些信息需要每次提交不同的数据,或者使用多个不同的值进行循环输入.这时,在LoadRunner中就可以进行参数化设置,以使用多个不同的值提交应用请求. [参数化]使用指定数据源中的值来替换脚本录制生成的语句中的参数. [好处] l  减少脚本的大小 l  提供使用不同的值执行脚本的能力,更加真实的模拟现实应用. [参