双三次插值算法的OpenGL实现

双三次插值算法的OpenGL实现

说明

最近写一个图像缩放的接口,考虑到自己有现成的OpenGL图像处理引擎,还是直接写shader用GPU实现方便。为了效果好一些,采用了双三次插值算法。
算法相关公式可参考这篇文章:
http://blog.csdn.net/lichengyu/article/details/8526629

代码

详细实现代码见:
https://github.com/jxt1234/Simple3D/blob/master/src/GL/GLBicubicWork.cpp
测试代码见:
https://github.com/jxt1234/Simple3D/blob/master/gltest/GLBitmapWorkTest.cpp

要集成到其他项目中,只需要 vertex shader 和 fragment shader 两部分的代码,毕竟不同的图像引擎在如何加载shader,如何传参数,如何上传纹理的逻辑都是不同的。

bicubic.vex

attribute vec4 pos;
attribute vec2 tex;
varying vec2 vTex;
void main(void)
{
    gl_Position = pos;
    vTex = tex;
}

生成的 fragment shader:
bicubic.fra

#ifdef GL_ES
precision mediump float;//用于手机上时需要添加此句
#endif
varying vec2 vTex;//纹理坐标,注意与 vertex shader 中的变量对应
uniform sampler2D buffer;
uniform float uUnit;//传入原图的宽
uniform float vUnit;//传入原图的高

float BiCubicPoly1(float x, float a)
{
    x = abs(x);
    float res = (a+float(2))*x*x*x - (a+float(3))*x*x + float(1);
    return res;
}
float BiCubicPoly2(float x, float a)
{
    x = abs(x);
    float res = a*x*x*x - float(5)*a*x*x + float(8)*a*x - float(4)*a;
    return res;
}
void main()
{
vec2 basic; 
vec2 det; 
basic = vTex*vec2(uUnit, vUnit) - vec2(0.5,0.5); 
det = fract(basic); 
gl_FragColor = vec4(0.0,0.0,0.0,0.0)
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(-1), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(-1), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(0), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(0), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly1(det.x-float(1), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(1), float(2)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly2(det.y-float(-1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(-1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly1(det.y-float(0), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(0)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly1(det.y-float(1), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(1)))/vec2(uUnit, vUnit))
+BiCubicPoly2(det.x-float(2), float(-0.5))*BiCubicPoly2(det.y-float(2), float(-0.5))*texture2D(buffer, vTex + ( - det + vec2(float(2), float(2)))/vec2(uUnit, vUnit))
;
}
课程解决的问题: 作为游戏行业或者图形学从业者,你是否面临以下问题: 到底openGL底层如何实现的? 到底矩阵操作变换是怎么做到的? 到底光栅化的算法以及原理是什么? 到底如何才能从3D世界投射到2D屏幕呢? 图形学有这么多的矩阵操作,到底如何推导如何应用呢? 学完这门课程,你应该就可以从底层了解一个初级的openGL图形接口如何实现,图形学最底层的封装到底面临哪些挑战;跟随我们一行一行写完代码,你就会得到一个迷你版本的openGL图形库,你可以深度体会图形从模型变换,观察矩阵变换,投影矩阵变换一直到光栅化纹理操作的全套模拟流程。 课程介绍: 本课程将带领学员不使用任何图形库,实现从0到1的图形学接口封装以及算法讲解,并且带领大家手敲代码,一行一行进行实现。 涵盖了(环境搭建,绘制点,Bresenham算法绘制完美直线,三角形拆分绘制算法,颜色插值算法,图片操作,图片二次插值放缩算法,纹理系统接口搭建及封装,矩阵操作理论以及实践,openGL类似接口封装,3D世界的图形学理论及接口封装等) 最终将带领大家通过C++实现一个3D世界的图形接口,方便所有人入门图形学,进行接下来的openGL接口以及GPU编程的学习   本课程为系列课程的第一步入门,且带领所有人进行实现,更加实用,可以让大家打牢图形学的基础知识及编程技能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值