日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

使用OpenGL Shader实现放大镜效果

發(fā)布時(shí)間:2025/7/25 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用OpenGL Shader实现放大镜效果 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用OpenGL Shader實(shí)現(xiàn)放大鏡效果

2014年3月16日renjihe發(fā)表評(píng)論閱讀評(píng)論

周末閑來無事,想玩玩OpenGL Shader,想想就實(shí)現(xiàn)一個(gè)放大鏡效果的Shader吧。
著色器可以指定放大鏡位置、半徑、及放大部數(shù),我實(shí)現(xiàn)是在片段著色中使用向后映射的雙線性插值的方式對(duì)當(dāng)前片段顏色進(jìn)行插值,而頂點(diǎn)著色器什么都不做。
先來看一下頂點(diǎn)著色器。

1 uniform?float?texture_id;//當(dāng)前使用的紋理的ID
2 ?
3 void?main()
4 {
5 ????gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;//輸出默認(rèn)頂點(diǎn)位置
6 ????gl_FrontColor = gl_Color;
7 ????gl_TexCoord[texture_id] = gl_TextureMatrix[texture_id] * gl_MultiTexCoord0;//輸出當(dāng)前頂點(diǎn)對(duì)應(yīng)的紋理坐標(biāo)。
8 }

再來看一下片段著色器。

01 uniform vec2? in_circle_pos;//從客戶端傳入的放大鏡圓心位置
02 uniform?float?in_circle_radius;//從客戶端傳入的放大鏡圓半徑
03 uniform?float?in_zoom_times;//從客戶端傳入的放大鏡放大倍數(shù)
04 ?
05 uniform?float?imageWidth;//從客戶端傳入的圖片寬數(shù)據(jù)
06 uniform?float?imageHeight;//從客戶端傳入的圖片高數(shù)據(jù)
07 ?
08 uniform?float?texture_id;//從客戶端傳入的紋理ID數(shù)據(jù)
09 ?
10 uniform sampler2D textureSampler;//從客戶端傳入的采樣器ID
11 ?
12 vec2 transForTexPosition(vec2 pos)
13 {
14 ????return?vec2((float)pos.x/imageWidth, (float)pos.y/imageHeight);
15 }
16 ?
17 float?getDistance(vec2 pos_src, vec2 pos_dist)
18 {
19 ????float?quadratic_sum =?pow((pos_src.x - pos_dist.x), 2) +?pow((pos_src.y - pos_dist.y), 2);
20 ????return?sqrt(quadratic_sum);
21 }
22 ?
23 vec2 getZoomPosition()
24 {
25 ????float?zoom_x = (float)(gl_FragCoord.x - in_circle_pos.x) / in_zoom_times;
26 ????float?zoom_y = (float)(gl_FragCoord.y - in_circle_pos.y) / in_zoom_times;
27 ????return?vec2((float)in_circle_pos.x + zoom_x, (float)in_circle_pos.y - zoom_y);
28 }
29 ?
30 vec4 getColor()//雙線性插值采樣
31 {
32 ????vec2 pos = getZoomPosition();
33 ?
34 ????float?_x =?floor(pos.x);
35 ????float?_y =?floor(pos.y);
36 ?
37 ????float?u = pos.x - _x;
38 ????float?v = pos.y - _y;
39 ?
40 ????vec4 data_00 = texture2D(textureSampler, transForTexPosition(vec2(_x, _y)));
41 ????vec4 data_01 = texture2D(textureSampler, transForTexPosition(vec2(_x, _y + 1)));
42 ????vec4 data_10 = texture2D(textureSampler, transForTexPosition(vec2(_x + 1, _y)));
43 ????vec4 data_11 = texture2D(textureSampler, transForTexPosition(vec2(_x + 1, _y + 1)));
44 ?
45 ????return?(1 - u) * (1 - v) * data_00 + (1 - u) * v * data_01 + u * (1 - v) * data_10 + u * v * data_11;
46 }
47 ?
48 void?main()
49 {
50 ????vec2 frag_pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
51 ????//若當(dāng)前片段位置距放大鏡圓心距離大于圓半徑時(shí),直接從紋理中采樣輸出片段顏色
52 ????if?(getDistance(in_circle_pos, frag_pos) > in_circle_radius)
53 ????????gl_FragColor = texture2D(textureSampler, gl_TexCoord[texture_id].st);
54 ????else//距離小于半徑的片段,二次線性插值獲得顔色。
55 ????????gl_FragColor = getColor();
56 }

再來看看一看客戶端主要操作。
從編譯的Shader程序中獲取變量,用于后續(xù)操作。

1 m_circle_pos = glGetUniformLocation(m_program,?"in_circle_pos");
2 m_circle_radius = glGetUniformLocation(m_program,?"in_circle_radius");
3 m_zoom_times = glGetUniformLocation(m_program,?"in_zoom_times");
4 ?
5 m_image_width = glGetUniformLocation(m_program,?"imageWidth");
6 m_image_height = glGetUniformLocation(m_program,?"imageHeight");
7 m_texture_sampler = glGetUniformLocation(m_program,?"textureSampler");
8 m_texture_id? = glGetUniformLocation(m_program,?"texture_id");

對(duì)上面獲取的變量賦值。

1 glUniform2f(m_circle_pos, circle_pos.x(), circle_pos.y());
2 glUniform1f(m_circle_radius, (float)100.0);
3 glUniform1f(m_zoom_times, (float)2.0);
4 ?
5 glUniform1f(m_image_width, (float)this->width);
6 glUniform1f(m_image_height, (float)this->height);
7 ?
8 glUniform1i(m_texture_sampler, kTexture);
9 glUniform1i(m_texture_id, kTexture);

畫圖。

1 glBindTexture(GL_TEXTURE_2D, m_textures[kTexture]);
2 ?
3 glBegin(GL_QUADS);
4 ????glTexCoord2f(0.0, 0.0);glVertex3f(-this->width/2,?this->height/2, 0.0);
5 ????glTexCoord2f(0.0, 1.0);glVertex3f(-this->width/2, -this->height/2, 0.0);
6 ????glTexCoord2f(1.0, 1.0);glVertex3f(this->width/2, -this->height/2, 0.0);
7 ????glTexCoord2f(1.0, 0.0);glVertex3f(this->width/2,?this->height/2, 0.0);
8 glEnd();

最終效果如下:

作者:renjihe 出處:http://www.renjihe.com
本站所有文章均是原創(chuàng),版權(quán)歸本站所有。歡迎轉(zhuǎn)載,但未經(jīng)同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利.

總結(jié)

以上是生活随笔為你收集整理的使用OpenGL Shader实现放大镜效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。