高級(jí)OpenGL-03.混合(Blending)

混合

在OpenGL中爬橡,物體透明技術(shù)通常被叫做混合(Blending)治唤。透明的物體(或物體的一部分)非純色而是混合色,這種顏色來自于不同濃度的自身顏色和它后面的物體顏色糙申。一個(gè)有色玻璃窗就是一種透明物體肝劲,玻璃有自身的顏色,但是最終的顏色包含了所有玻璃后面的顏色郭宝。這也正是混合這名稱的出處,因?yàn)槲覀儗⒍喾N(來自于不同物體)顏色混合為一個(gè)顏色掷漱,透明使得我們可以看穿物體粘室。

透明物體可以是完全透明(它使顏色完全穿透)或者半透明的(它使顏色穿透的同時(shí)也顯示自身顏色)。一個(gè)物體的透明度卜范,被定義為它的顏色的alpha值衔统。alpha顏色值是一個(gè)顏色向量的第四個(gè)元素,你可能已經(jīng)看到很多了海雪。在這個(gè)教程前锦爵,我們一直把這個(gè)元素設(shè)置為1.0,這樣物體的透明度就是0.0奥裸,同樣的险掀,當(dāng)alpha值是0.0時(shí)就表示物體是完全透明的,alpha值為0.5時(shí)表示物體的顏色由50%的自身的顏色和50%的后面的顏色組成湾宙。

我們之前所使用的紋理都是由3個(gè)顏色元素組成的:紅樟氢、綠冈绊、藍(lán),但是有些紋理同樣有一個(gè)內(nèi)嵌的aloha通道埠啃,它為每個(gè)紋理像素(Texel)包含著一個(gè)alpha值死宣。這個(gè)alpha值告訴我們紋理的哪個(gè)部分有透明度,以及這個(gè)透明度有多少碴开。例如毅该,下面的窗子紋理的玻璃部分的alpha值為0.25(它的顏色是完全紅色,但是由于它有75的透明度潦牛,它會(huì)很大程度上反映出網(wǎng)站的背景色眶掌,看起來就不那么紅了),角落部分alpha是0.0(表示完全透明)罢绽。

我們很快就會(huì)把這個(gè)窗子紋理加到場(chǎng)景中畏线,但是首先,我們將討論一點(diǎn)簡單的技術(shù)來實(shí)現(xiàn)紋理的半透明寝殴,也就是完全透明和完全不透明明垢。

忽略片段

有些圖像并不關(guān)心半透明度,但也想基于紋理的顏色值顯示一部分痊银。例如,創(chuàng)建像草這種物體你不需要花費(fèi)很大力氣贞绳,通常把一個(gè)草的紋理貼到2D四邊形上致稀,然后把這個(gè)四邊形放置到你的場(chǎng)景中《兜ィ可是萎攒,草并不是像2D四邊形這樣的形狀,而只需要顯示草紋理的一部分而忽略其他部分矛绘。

下面的紋理正是這樣的紋理耍休,它既有完全不透明的部分(alpha值為1.0)也有完全透明的部分(alpha值為0.0),而沒有半透明的部分货矮。你可以看到?jīng)]有草的部分羊精,圖片顯示了網(wǎng)站的背景色,而不是它自身的那部分顏色次屠。

所以园匹,當(dāng)向場(chǎng)景中添加像這樣的紋理時(shí)雳刺,我們不希望看到一個(gè)方塊圖像,而是只顯示實(shí)際的紋理像素裸违,剩下的部分可以被看穿掖桦。我們要忽略(丟棄)紋理透明部分的像素,不必將這些片段儲(chǔ)存到顏色緩沖中供汛。在此之前枪汪,我們還要學(xué)一下如何加載一個(gè)帶有透明像素的紋理。

加載帶有alpha值的紋理我們需要告訴SOIL怔昨,去加載RGBA元素圖像雀久,而不再是RGB元素的。SOIL能以RGBA的方式加載大多數(shù)沒有alpha值的紋理趁舀,它會(huì)將這些像素的alpha值設(shè)為了1.0(完全不透明)赖捌。

unsigned char * image = SOIL_load_image(path, &width, &height, 0, SOIL_LOAD_RGBA);

不要忘記還要改變OpenGL生成的紋理:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

保證你在片段著色器中獲取了紋理的所有4個(gè)顏色元素,而不僅僅是RGB元素:

void main ()
{
    // color = vec4(vec3(texture(texture1, TexCoords)), 1.0);
    color = texture (texture1, TexCoords);
}

現(xiàn)在我們知道了如何加載透明紋理矮烹,是時(shí)候試試在深度測(cè)試教程里那個(gè)場(chǎng)景中添加幾根草了越庇。

我們創(chuàng)建一個(gè)std::vector,并向里面添加幾個(gè)glm::vec3變量奉狈,來表示草的位置:

vector<glm::vec3> vegetation;
vegetation.push_back (glm::vec3 (-1.5f, 0.0f, -0.48f));
vegetation.push_back (glm::vec3 (1.5f, 0.0f, 0.51f));
vegetation.push_back (glm::vec3 (0.0f, 0.0f, 0.7f));
vegetation.push_back (glm::vec3 (-0.3f, 0.0f, -2.3f));
vegetation.push_back (glm::vec3 (0.5f, 0.0f, -0.6f));

一個(gè)單獨(dú)的四邊形被貼上草的紋理卤唉,這并不能完美的表現(xiàn)出真實(shí)的草,但是比起加載復(fù)雜的模型還是要高效很多仁期,利用一些小技巧,比如在同一個(gè)地方添加多個(gè)不同朝向的草熬的,還是能獲得比較好的效果的悦析。

由于草紋理被添加到四邊形物體上亭螟,我們需要再次創(chuàng)建另一個(gè)VAO预烙,向里面填充VBO翘县,以及設(shè)置合理的頂點(diǎn)屬性指針锈麸。在我們繪制完地面和兩個(gè)立方體后忘伞,我們就來繪制草葉:

glBindVertexArray (vegetationVAO);
glBindTexture (GL_TEXTURE_2D, grassTexture);
for (GLuint i = 0; i < vegetation.size (); i++)
{
    model = glm::mat4 ();
    model = glm::translate (model, vegetation[i]);
    glUniformMatrix4fv (modelLoc, 1, GL_FALSE, glm::value_ptr (model));
    glDrawArrays (GL_TRIANGLES, 0, 6);
}
glBindVertexArray (0);

運(yùn)行程序你將看到:

出現(xiàn)這種情況是因?yàn)镺penGL默認(rèn)是不知道如何處理alpha值的翘魄,不知道何時(shí)忽略(丟棄)它們暑竟。我們不得不手動(dòng)做這件事但荤。幸運(yùn)的是這很簡單,感謝著色器化借,GLSL為我們提供了discard命令铐炫,它保證了片段不會(huì)被進(jìn)一步處理倒信,這樣就不會(huì)進(jìn)入顏色緩沖鳖悠。有了這個(gè)命令我們就可以在片段著色器中檢查一個(gè)片段是否有在一定的閾限下的alpha值,如果有卡辰,那么丟棄這個(gè)片段九妈,就好像它不存在一樣

#version 330 core
in vec2 TexCoords;

out vec4 color;

uniform sampler2D texture1;

void main ()
{
    vec4 texColor = texture (texture1, TexCoords);
    if (texColor.a < 0.1)
        discard;
    color = texColor;
}

在這兒我們檢查被采樣紋理顏色包含著一個(gè)低于0.1這個(gè)閾限的alpha值宴树,如果有森渐,就丟棄這個(gè)片段。這個(gè)片段著色器能夠保證我們只渲染哪些不是完全透明的片段∧推耄現(xiàn)在我們來看看效果:

需要注意的是埠况,當(dāng)采樣紋理邊緣的時(shí)候,OpenGL在邊界值和下一個(gè)重復(fù)的紋理的值之間進(jìn)行插值(因?yàn)槲覀儼阉姆胖梅绞皆O(shè)置成了GL_REPEAT)喜命。這樣就行了壁榕,但是由于我們使用的是透明值牌里,紋理圖片的上部獲得了它的透明值是與底邊的純色值進(jìn)行插值的牡辽。結(jié)果就是一個(gè)有點(diǎn)半透明的邊催享,你可以從我們的紋理四邊形的四周看到。為了防止它的出現(xiàn)攀涵,當(dāng)你使用alpha紋理的時(shí)候要把紋理環(huán)繞方式設(shè)置為GL_CLAMP_TO_EDGE:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

你可以在這里得到源碼以故。
項(xiàng)目代碼在這怒详。

混合

上述丟棄片段的方式昆烁,不能使我們獲得渲染半透明圖像静尼,我們要么渲染出像素鼠渺,要么完全地丟棄它拦盹。為了渲染出不同的透明度級(jí)別,我們需要開啟混合(Blending)池磁。像大多數(shù)OpenGL的功能一樣华临,我們可以開啟GL_BLEND來啟用混合功能:

glEnable(GL_BLEND);

開啟混合后雅潭,我們還需要告訴OpenGL它該如何混合扶供。OpenGL以下面的方程進(jìn)行混合:

Cˉresult = Cˉsource ? Fsource + Cˉdestination ? Fdestination

  • Cˉsource:源顏色向量椿浓。這是來自紋理的本來的顏色向量提岔。
  • Cˉdestination:目標(biāo)顏色向量碱蒙。這是儲(chǔ)存在顏色緩沖中當(dāng)前位置的顏色向量。
  • Fsource:源因子喷兼。設(shè)置了對(duì)源顏色的alpha值影響褒搔。
  • Fdestination:目標(biāo)因子星瘾。設(shè)置了對(duì)目標(biāo)顏色的alpha影響琳状。

片段著色器運(yùn)行完成并且所有的測(cè)試都通過以后念逞,混合方程才能自由執(zhí)行片段的顏色輸出翎承,當(dāng)前它在顏色緩沖中(前面片段的顏色在當(dāng)前片段之前儲(chǔ)存)叨咖。源和目標(biāo)顏色會(huì)自動(dòng)被OpenGL設(shè)置甸各,而源和目標(biāo)因子可以讓我們自由設(shè)置。我們來看一個(gè)簡單的例子:

我們有兩個(gè)方塊儒恋,我們希望在紅色方塊上繪制綠色方塊涂邀。紅色方塊會(huì)成為目標(biāo)顏色(它會(huì)先進(jìn)入顏色緩沖),我們將在紅色方塊上繪制綠色方塊驹止。

那么問題來了:我們?cè)鯓觼碓O(shè)置因子呢?我們起碼要把綠色方塊乘以它的alpha值墓捻,所以我們打算把Fsource設(shè)置為源顏色向量的alpha值:0.6撤卢。接著,讓目標(biāo)方塊的濃度等于剩下的alpha值渡紫。如果最終的顏色中綠色方塊的濃度為60%惕澎,我們就把紅色的濃度設(shè)為40%(1.0 – 0.6)唧喉。所以我們把Fdestination設(shè)置為1減去源顏色向量的alpha值。方程將變成:

最終方塊結(jié)合部分包含了60%的綠色和40%的紅色梯找,得到一種臟兮兮的顏色:

最后的顏色被儲(chǔ)存到顏色緩沖中唆阿,取代先前的顏色。

這個(gè)方案不錯(cuò)锈锤,但我們?cè)鯓痈嬖VOpenGL來使用這樣的因子呢驯鳖?恰好有一個(gè)叫做glBlendFunc的函數(shù)闲询。

void glBlendFunc(GLenum sfactor, GLenum dfactor)接收兩個(gè)參數(shù),來設(shè)置源(source)和目標(biāo)(destination)因子浅辙。OpenGL為我們定義了很多選項(xiàng)扭弧,我們把最常用的列在下面。注意记舆,顏色常數(shù)向量Cˉconstant可以用glBlendColor函數(shù)分開來設(shè)置御蒲。

為從兩個(gè)方塊獲得混合結(jié)果,我們打算把源顏色的alpha給源因子严望,1-alpha給目標(biāo)因子拨匆。調(diào)整到glBlendFunc之后就像這樣:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

也可以為RGB和alpha通道各自設(shè)置不同的選項(xiàng)宏赘,使用glBlendFuncSeperate:

glBlendFuncSeperate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_ZERO);

這個(gè)方程就像我們之前設(shè)置的那樣脐往,設(shè)置了RGB元素,但是只讓最終的alpha元素被源顏色的alpha值影響到(GL_ONE)誊辉。

OpenGL給了我們更多的自由蛙紫,我們可以改變方程源和目標(biāo)部分的操作符⊙涠荆現(xiàn)在抄肖,源和目標(biāo)元素已經(jīng)相加了幌甘。如果我們?cè)敢獾脑捒裕覀冞€可以把它們相減十酣。

void glBlendEquation(GLenum mode)允許我們?cè)O(shè)置這個(gè)操作搓彻,有3種可行的選項(xiàng):

  • GL_FUNC_ADD:默認(rèn)的,彼此元素相加:Cˉresult = Src + Dst.
  • GL_FUNC_SUBTRACT:彼此元素相減: Cˉresult = Src – Dst.
  • GL_FUNC_REVERSE_SUBTRACT:彼此元素相減,但順序相反:Cˉresult = Dst – Src.

通常我們可以簡單地省略glBlendEquation因?yàn)镚L_FUNC_ADD在大多數(shù)時(shí)候就是我們想要的是己,但是如果你如果你真想嘗試努力打破主流常規(guī),其他的方程或許符合你的要求牢贸。

渲染半透明紋理

現(xiàn)在我們知道OpenGL如何處理混合,是時(shí)候把我們的知識(shí)運(yùn)用起來了,我們來添加幾個(gè)半透明窗子耳峦。我們會(huì)使用本教程開始時(shí)用的那個(gè)場(chǎng)景冠句,但是不再渲染草紋理聚唐,取而代之的是來自教程開始處半透明窗子紋理臀蛛。

首先舔琅,初始化時(shí)我們需要開啟混合虚循,設(shè)置合適和混合方程:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

由于我們開啟了混合奢入,就不需要丟棄片段了筝闹,所以我們把片段著色器設(shè)置為原來的那個(gè)版本:

#version 330 core

in vec2 TexCoords;

out vec4 color;

uniform sampler2D texture1;

void main()
{    
    color = texture(texture1, TexCoords);
}

這一次(無論OpenGL什么時(shí)候去渲染一個(gè)片段),它都根據(jù)alpha值腥光,把當(dāng)前片段的顏色和顏色緩沖中的顏色進(jìn)行混合关顷。因?yàn)榇白拥牟AР糠值募y理是半透明的,我們應(yīng)該可以透過玻璃看到整個(gè)場(chǎng)景武福。

如果你仔細(xì)看看议双,就會(huì)注意到有些不對(duì)勁。前面的窗子透明部分阻塞了后面的捉片。為什么會(huì)這樣平痰?

原因是深度測(cè)試在與混合的一同工作時(shí)出現(xiàn)了點(diǎn)狀況。當(dāng)寫入深度緩沖的時(shí)候界睁,深度測(cè)試不關(guān)心片段是否有透明度,所以透明部分被寫入深度緩沖兵拢,就和其他值沒什么區(qū)別翻斟。結(jié)果是整個(gè)四邊形的窗子被檢查時(shí)都忽視了透明度。即便透明部分應(yīng)該顯示出后面的窗子说铃,深度緩沖還是丟棄了它們访惜。

所以我們不能簡簡單單地去渲染窗子,我們期待著深度緩沖為我們解決這所有問題腻扇;這也正是混合之處代碼不怎么好看的原因债热。為保證前面窗子顯示了它后面的窗子,我們必須首先繪制后面的窗子幼苛。這意味著我們必須手工調(diào)整窗子的順序窒篱,從遠(yuǎn)到近地逐個(gè)渲染。

對(duì)于全透明物體,比如草葉墙杯,我們選擇簡單的丟棄透明像素而不是混合配并,這樣就減少了令我們頭疼的問題(沒有深度測(cè)試問題)。

別打亂順序

要讓混合在多物體上有效高镐,我們必須先繪制最遠(yuǎn)的物體溉旋,最后繪制最近的物體。普通的無混合物體仍然可以使用深度緩沖正常繪制嫉髓,所以不必給它們排序观腊。我們一定要保證它們?cè)谕该魑矬w前繪制好。當(dāng)無透明度物體和透明物體一起繪制的時(shí)候算行,通常要遵循以下原則:
先繪制所有不透明物體梧油。 為所有透明物體排序。 按順序繪制透明物體纱意。

** 一種排序透明物體的方式是婶溯,獲取一個(gè)物體到觀察者透視圖的距離。**這可以通過獲取攝像機(jī)的位置向量和物體的位置向量來得到偷霉。接著我們就可以把它和相應(yīng)的位置向量一起儲(chǔ)存到一個(gè)map數(shù)據(jù)結(jié)構(gòu)(STL庫)中迄委。map會(huì)自動(dòng)基于它的鍵排序它的值,所以當(dāng)我們把它們的距離作為鍵添加到所有位置中后类少,它們就自動(dòng)按照距離值排序了:

map<float, glm::vec3> sorted;       // 距離叙身,位置向量
for (auto pos : windows)
{
    GLfloat distance = glm::length (camera.Position - pos);     // 攝像機(jī)位置與窗口的距離,map會(huì)按照距離從小到大排序硫狞。
    sorted[distance] = pos;
}

最后產(chǎn)生了一個(gè)容器對(duì)象信轿,基于距離從低到高儲(chǔ)存了每個(gè)窗子的位置。
隨后當(dāng)渲染的時(shí)候残吩,我們逆序獲取到每個(gè)map的值(從遠(yuǎn)到近)财忽,然后以正確的繪制相應(yīng)的窗子:

for (map<float, glm::vec3>::reverse_iterator it = sorted.rbegin (); it != sorted.rend (); ++it) // 逆序獲取每個(gè)map的值(從遠(yuǎn)到近)
{
    model = glm::mat4 ();
    model = glm::translate (model, it->second);
    glUniformMatrix4fv (glGetUniformLocation (windowShader.Program, "model"), 1, GL_FALSE, glm::value_ptr (model));
    glDrawArrays (GL_TRIANGLES, 0, 6);
}

我們從map得來一個(gè)逆序的迭代器,迭代出每個(gè)逆序的條目泣侮,然后把每個(gè)窗子的四邊形平移到相應(yīng)的位置即彪。這個(gè)相對(duì)簡單的方法對(duì)透明物體進(jìn)行了排序,修正了前面的問題活尊,現(xiàn)在場(chǎng)景看起來像這樣:

你可以從這里得到完整的帶有排序的源碼隶校。
完整項(xiàng)目代碼在[這里[(https://www.jianguoyun.com/p/DScoVDMQ-5L3BRicqxY)。

雖然這個(gè)按照它們的距離對(duì)物體進(jìn)行排序的方法在這個(gè)特定的場(chǎng)景中能夠良好工作蛹锰,但它不能進(jìn)行旋轉(zhuǎn)深胳、縮放或者進(jìn)行其他的變換,奇怪形狀的物體需要一種不同的方式铜犬,而不能簡單的使用位置向量舞终。

在場(chǎng)景中排序物體是個(gè)有難度的技術(shù)轻庆,它很大程度上取決于你場(chǎng)景的類型,更不必說會(huì)耗費(fèi)額外的處理能力了权埠。完美地渲染帶有透明和不透明的物體的場(chǎng)景并不那么容易榨了。有更高級(jí)的技術(shù)例如次序無關(guān)透明度(order independent transparency),但是這超出了本教程的范圍∪帘危現(xiàn)在你不得不采用普通的混合你的物體龙屉,但是如果你小心謹(jǐn)慎,并知道這個(gè)局限满俗,你仍可以得到頗為合適的混合實(shí)現(xiàn)转捕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市唆垃,隨后出現(xiàn)的幾起案子五芝,更是在濱河造成了極大的恐慌,老刑警劉巖辕万,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢步,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡渐尿,警方通過查閱死者的電腦和手機(jī)醉途,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來砖茸,“玉大人隘擎,你說我怎么就攤上這事×购唬” “怎么了货葬?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長劲够。 經(jīng)常有香客問我震桶,道長,這世上最難降的妖魔是什么征绎? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任蹲姐,我火速辦了婚禮,結(jié)果婚禮上炒瘸,老公的妹妹穿的比我還像新娘淤堵。我一直安慰自己寝衫,他們只是感情好顷扩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著慰毅,像睡著了一般隘截。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天婶芭,我揣著相機(jī)與錄音东臀,去河邊找鬼。 笑死犀农,一個(gè)胖子當(dāng)著我的面吹牛惰赋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播呵哨,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赁濒,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了孟害?” 一聲冷哼從身側(cè)響起拒炎,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挨务,沒想到半個(gè)月后击你,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谎柄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年丁侄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谷誓。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绒障,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捍歪,到底是詐尸還是另有隱情户辱,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布糙臼,位于F島的核電站庐镐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏变逃。R本人自食惡果不足惜必逆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揽乱。 院中可真熱鬧名眉,春花似錦、人聲如沸凰棉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撒犀。三九已至福压,卻和暖如春掏秩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荆姆。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工蒙幻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胆筒。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓邮破,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仆救。 傳聞我的和親對(duì)象是個(gè)殘疾皇子决乎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容