OpenGL 实现Interpolation插值算法

这是一个静态插值算法的效果,图形学中插值算法应用十分广,如动画,photoshop, autocAD等软件画曲线,还有shader中的渐变上色也是一个硬件支持的插值算法。

Interpolation是很低层的算法,在图形学中可以说无处不在。

本程序通过设置两个vector,然后就可以在这两个vector之间插入点,得到不同的效果

如两个vector不同长度可以得到:

如果长度相同,就可以得到一个扇形:

全部自家定义的函数实现的,主要代码:

一)计算两个向量的夹角,返回夹角大小:

float calVecTheta(Vector2f vfir, Vector2f vsec)
{
	float r = sqrtf(vfir.x * vfir.x + vfir.y * vfir.y);
	Vector2f vfirNor;
	vfirNor.x = vfir.x / r;
	vfirNor.y = vfir.y / r;

	r = sqrtf(vsec.x * vsec.x + vsec.y * vsec.y);
	Vector2f vsecNor;
	vsecNor.x = vsec.x / r;
	vsecNor.y = vsec.y / r;

	float theta = acosf(vfirNor.x * vsecNor.x + vfirNor.y * vsecNor.y);
	return theta;
}

二) 实现插值公式

void interpolateTwoVectors(Vector2f &vout, Vector2f &vfir, Vector2f &vsec,
					  float theta, float t)
{
	float a = sinf((1.0f-t) * theta) / sinf(theta);
	float b = sinf(t * theta) / sinf(theta);

	vout.x = a * vfir.x + b * vsec.x;
	vout.y = a * vfir.y + b * vsec.y;
}

三)产生顶点缓冲:

void createGeoAndBuffer()
{
	Vector2f vers[SEGMENTS*2+2];
	Vector2f vfir(1.f, 0.f);
	Vector2f vsec(-1.f/sqrtf(2.0f), 1.f/sqrtf(2.0f));
	vers[1] = vfir, vers[3] = vsec;

	float theta = calVecTheta(vfir, vsec);
	for (int i = 4, d = 1; i < SEGMENTS*2+2; i += 2, d++)
	{
		interpolateTwoVectors(vers[i+1], vfir, vsec, theta,
			float(d) / (float)SEGMENTS);
	}

	glGenBuffers(1, &VBO);//注意是1, &VBO
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vers), vers, GL_STATIC_DRAW);
}

以上就是主要的算法代码了。

插值算法还可以实现很多有趣的效果,因为它乃是动画的最底层算法,如很多人玩的flash动画,flash会自动产生连贯的帧,实现动画效果,很神奇吧? 其实产生的动画效果就是使用了这个插值算法的。呵呵,在底层逻辑原理面前,能解开一切神秘面纱,Magic has been demistified。

有空会实现更多效果。

OpenGL 实现Interpolation插值算法,布布扣,bubuko.com

时间: 2024-11-05 20:27:06

OpenGL 实现Interpolation插值算法的相关文章

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ格式分析

[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ文件格式分析作者:yuezang - iTyran 在iOS的3D开发中常常需要导入通过3DS MAX之类的3D设计软件生成的模型.因为OpenGL ES是不能直接读取这些文件的,所以常常需要开发人员增加接口来导入.通常的做法是在建模软件中建立3D模型之后在OpenGL ES中导入并进行控制.    3DS MAX通常的保存格式有*.max(现在生成的版本的格式),*.3ds(低版本的3ds Max生成的格式)

Android OpenGL ES(七)----理解纹理与纹理过滤

1.理解纹理 OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据.每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最常用的方式是直接从一个图像文件加载数据. 每个二维纹理都有其自己的坐标空间,其范围是从一个拐角的(0,0)到另一个拐角的(1,1).按照惯例,一个维度叫做S,而另一个称为T.当我们想要把一个纹理应用于一个三角形或一组三角形的时候,我们要为每个顶点指定一组ST纹理坐标,以便OpenGL知道需要用那个纹理

CSharpGL(31)[译]OpenGL渲染管道那些事

+BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一个不错的突破口. 本文通过阅读.翻译和扩展(https://www.opengl.org/wiki/Rendering_Pipeline_Overview)的方式,来逐步回顾总结一下OpenGL渲染管道,从而串联起OpenGL的所有知识点,并期望能在更高的层次上有所领悟. 另外,(https://www.opengl.org/wiki/Rendering_

Chapter 1 : OpenGLES 3.0 简介 (2)—— OpenGL ES 3.0

管道 如前所属,本书讲解的API版本是OpenGL ES 3.0.本书的目标是,深入讲解OpenGL ES 3.0的技术细节,给出具体的例子来说明如何使用某个特性,并且讨论了各种性能优化技术.当您读完这本书,您应该可以对OpenGL ES 3.0API有一个很好的把握.您将可以轻松的写出让人新服的OpenGL ES 3.0的应用程序,并且您不必通过阅读多种OpenGL ES的规范来搞懂某个特性是如何工作的. OpenGL ES 3.0实现了可编程着色图形管道.OpenGL ES 3.0规范包含两

OpenGL渲染流程

一.什么是openGL OpenGL被定义为“图形硬件的一种软件接口”.从本质上说,它是一个3D图形和模型库,具有高度的可移植性,具有非常快的速度. 二.管线 管线这个术语描述了opengl渲染的整个过程.openGL采用cs模型:c是cpu,s是GPU,c给s的输入是vertex信息和Texture信息,s的输出是显示器上显示的图像.下面这2个图比较清楚的讲解了opengl的渲染管线. 相信没有opengl基础的应该看不懂,下面会简单的介绍这个流程,再看下文之前,建议先看GPU大百科全书系列文

OpenGL官方教程——着色器语言概述

OpenGL官方教程——着色器语言概述 OpenGL官方教程——着色器语言概述 可编程图形硬件管线(流水线) 可编程顶点处理器 可编程几何处理器 可编程片元处理器 语言 可编程图形硬件管线(流水线) 将 Pertransformed Vertices (每一个待转换顶点) 传人 Programmable Vertex Processor (可编程的顶点处理器) 得到 Transformed Vertices (转换的顶点) 将 Transformed Vertices (转换的顶点) 传入 Pr

三十分钟理解:线性插值,双线性插值Bilinear Interpolation算法

线性插值 先讲一下线性插值:已知数据 (x0, y0) 与 (x1, y1),要计算 [x0, x1] 区间内某一位置 x 在直线上的y值(反过来也是一样,略): y?y0x?x0=y1?y0x1?x0 y=x1?xx1?x0y0+x?x0x1?x0y1 上面比较好理解吧,仔细看就是用x和x0,x1的距离作为一个权重,用于y0和y1的加权.双线性插值本质上就是在两个方向上做线性插值. 双线性插值 在数学上,双线性插值是有两个变量的插值函数的线性插值扩展,其核心思想是在两个方向分别进行一次线性插值

图像处理之基础---图像缩放中的一些 灰度插值算法

在图像缩放,旋转等一些图像处理中,对图像进行插值是不可缺少的一个步骤,下面对一些常用的插值算法进行介绍: 1.最近邻插值 这种插值方法是最简单的一种插值算法,图像输出的像素值的大小直接设为与其最邻近的点的大小即可,这个算法最简单,不需要多说,可以表示为 f(x,y) = g(  round(x)  ,   round(y)  ) 原图                                                                                  

NeHe OpenGL lession 4

// lession4.c #include <OpenGL/OpenGL.h> #include <GLUT/GLUT.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* ASCII code for teh escape key. */ #define ESCAPE 27 /* The number of our GLUT window */ int window;