實現Mac視窗最小化動畫效果

2021-10-11 03:03:06 字數 3006 閱讀 6727

在學習opengl的過程中,經一前輩的教導,做出了乙個比較有趣的東西:仿製mac中視窗最小化的動畫效果。因為是在我學習opengl的過程中製作的乙個東西,所以實現的**是使用是opengl來實現的,個人感覺思路也適用於其他的框架。實現的核心都在片元著色器中:對片元的uv座標進行修改,從而模擬實現乙個變形的整個過程。核心**只有幾句,剛做出來的時候自己也覺得太神奇了,所以希望把這個方法分享出來。

float vertices = ;
由效果圖可以看到,這整個動畫的變化過程實際上就是乙個矩形頂點在x方向上的變化和y方向上的變化, 大家看到這可能有不同的乙個想法,比如對頂點座標進行移動,但是這需要注意的是因為頂點著色器中拿到的只是上面的六個頂點座標,如果需要做出乙個曲線的伸縮效果,光對這些座標進行移動是不足夠的,因為光柵化過程中使用的是乙個線性插值,所以如果需要通過頂點著色器中對這些頂點的位置進行移動,就需要加入更多的頂點才可以,那整個過程就變得有點繁瑣了。

這裡選擇在片元著色器中進行變換,因為片元著色器可以獲得uv座標,通過改變uv的座標可以改變取樣的值(對眼睛來說就是顯示出來的發現了改變),同時在渲染管線中到片元著色器中的時候已經生成了乙個個的片元(類似畫素一樣),所以我們得到了更多的資料,這樣不需要人為的加入頂點資料便可以生成平滑曲線形狀。這裡變換的原理實際上就是對uv座標進行變換,拿u座標(水平方向)來說,把水平方向的取樣座標像兩邊拉伸,讓本來取樣座標應該為0和1的地方往中間去靠攏,然後取樣座標超出0~1的地方都讓他不取樣或者取樣為透明的顏色(這樣看起來就像是沒有了),這樣整體看起來就像是往中間收縮了。

因為uv座標取樣值範圍是0 ~ 1,為了方便計算這裡假設畫素點的x座標和y座標的取樣範圍也是0 ~ 1,因為無論縮放前還是縮放後都應該被完整的顯示出來的,所以變換前和變換後的畫素點座標都應該是成比例的,這樣就可以知道收縮後的座標(pos)的uv對應的是收縮前的哪個點(target)的uv,拿x座標來計算,即target.x:

因為uv座標的範圍是0 ~ 1,畫素點的座標xy的範圍也是0 ~ 1,而且是一 一對應的,所以算出來的target.x的值實際上也等於target點的u座標,所以我們就知道了目標點的 u 座標,然後根據該點當前的u座標和target點的 u 座標根據時間 t 進行線性插值,就可以得到x方向上的乙個變化效果:

到了這一步雖然看起來收縮了,但是只是豎直的去搜尋,這樣得出來的效果跟預期有點差距,我們想要搜尋邊緣呈現乙個曲線的效果,越往下搜尋的幅度越大,所以我們需要對時間 t 乘以 y 座標的乙個的二次函式,因為y座標和v座標是一一對應的,所以實際上等同於乘以v座標的乙個二次函式:

float targetx = (texcoord.x - left.x) / (right.x - left.x);

vec2 targetuv = vec2 (lerp(texcoord.x,targetx , pow(1 - texcoord.y,2) * time),texcoord.y);

這樣一來水平方向上就得到了我們想要的乙個收縮效果

接著只需要按相同思路去對y方向上進行搜尋就可以了,這裡就不在重複去講了,後面直接我會直接把著色器的**貼出來給大家,最後的效果圖:

float bordercolor = ; //指定邊緣顏色,設定成跟背景同樣的顏色就可以了

gltexparameterfv(gl_texture_2d, gl_texture_border_color, bordercolor);

gltexparameteri(gl_texture_2d, gl_texture_wrap_s, gl_clamp_to_border); //指定環繞方式為"超出的座標為使用者指定的邊緣顏色"

gltexparameteri(gl_texture_2d, gl_texture_wrap_t, gl_clamp_to_border);

頂點著色器(vertexshader)的**:

layout (location = 0) in vec3 apos;

layout (location = 1) in vec2 atexcoord;

out vec2 texcoord;

void main()

片元著色器(fragementshader)的**:

out vec4 fragcolor; 

in vec2 texcoord;

uniform sampler2d ourtexture;

uniform float time;

uniform vec2 left;

uniform vec2 right;

float lerp(float curentval,float targetval, float t)

vec2 caltexcoord(vec2 texcoord)

void main()

``

VC 實現 視窗最小化 MFC

所謂的 托盤 在windows系統介面中,指的就是下面任務條右側,有系統時間等等的標誌的那一部分。在程式最小化或掛起時,但有不希望佔據工作列的時候,就可以把程式放到托盤區。一 原理 二 實現 1 自定義訊息wm showtask define wm showtask wm user 1 為了防止使用...

Fedora視窗最大最小化

這是linux初用者普遍感到不習慣的地方 視窗沒有最大最小化按鍵,需要通過檢視右側活動視窗來處理不同視窗的顯示問題。較早的fedora版本貌似可以通過安裝 yum install gnome tweak tool yum install gconf editor 通過gconf editor改變 b...

視窗最小化到托盤

使用notifyicon控制項和contextmenustrip控制項實現 1.將notifyicon控制項和contextmenustrip控制項拖到form上 2.在form的formclosing事件 取消關閉窗體 e.cancel true 將窗體變為最小化 this.windowstate...