從0開始的OpenGL學(xué)習(xí)(五)-紋理

本文主要解決一個(gè)問題:

在OpenGL中如何使用紋理兔毙?

一、什么是紋理骆撇?

紋理瞒御,英文是texture,中文可以翻譯成紋理神郊、紋理圖肴裙、紋理映射等等一堆東西。不過不管翻譯成啥涌乳,講的都是一個(gè)東西蜻懦。我們通常說的紋理,指的是一張二維的圖片夕晓,把它像貼紙一樣貼在什么東西上面宛乃,讓那個(gè)東西看起來像我們貼紙所要表現(xiàn)的東西那樣。

舉例來說,假如我們想繪制一面磚墻征炼,我們該怎么辦析既?根據(jù)我們已經(jīng)掌握的知識(shí)來看,我們需要用成千上萬的點(diǎn)來模擬它的顏色谆奥,我的天眼坏,這要搞到猴年馬月才能搞出來?顯然不現(xiàn)實(shí)酸些!于是聰明的程序員們想出了一個(gè)好方法宰译,就是用一張圖“貼”到物體的表面上,讓它看起來像是一面磚墻的樣子魄懂,省時(shí)省力省心沿侈。

用一句話來總結(jié),紋理就是一張貼到物體上的2維圖像市栗。

二缀拭、映射方式

既然是要把圖貼到物體上,自然就要想怎么貼才行肃廓。我們可以橫貼智厌、豎貼、斜貼怎么貼都行盲赊,但是怎樣貼才能達(dá)到我們想要的效果呢铣鹏?總要有個(gè)規(guī)章制度來規(guī)定一下怎么貼才行吧。這個(gè)貼法哀蘑,就稱為映射诚卸。

規(guī)則是:以左下角為原點(diǎn),向右伸展到1.0的位置绘迁,向上伸展到1.0的位置合溺,表示一整張的紋理圖像。

紋理圖坐標(biāo)(看著美女圖是不是比磚塊圖有激情多了缀台?)

使用紋理圖的時(shí)候棠赛,我們需要在頂點(diǎn)數(shù)據(jù)中添加一個(gè)紋理坐標(biāo)的數(shù)據(jù),標(biāo)明我們是如何將紋理上的元素映射到頂點(diǎn)上的膛腐,這個(gè)我們在后面的實(shí)現(xiàn)環(huán)節(jié)再詳細(xì)說明睛约。

三、紋理環(huán)繞方式(Texture Wrapping)

通常哲身,紋理坐標(biāo)的范圍在(0,0)到(1,1)之間辩涝,但是如果我們制定的坐標(biāo)在這之外呢?OpenGL會(huì)如何做出反應(yīng)勘天?默認(rèn)情況下怔揩,OpenGL會(huì)重復(fù)繪制紋理圖捉邢,不過,OpenGL也提供了更多的選擇方案:

  • GL_REPEAT: 默認(rèn)方案商膊,重復(fù)紋理圖片伏伐。
  • GL_MIRRORED_REPEAT:類似于默認(rèn)方案,不過每次重復(fù)的時(shí)候進(jìn)行鏡像重復(fù)翘狱。
  • GL_CLAMP_TP_EDGE:將坐標(biāo)限制在0到1之間秘案。超出的坐標(biāo)會(huì)重復(fù)繪制邊緣的像素,變成一種擴(kuò)展邊緣的圖案潦匈。(通常很難看)
  • GL_CLAMP_TO_BORDER:超出的坐標(biāo)將會(huì)被繪制成用戶指定的邊界顏色。

每種方案的顯示效果截然不同赚导,不必?fù)?dān)心你會(huì)搞混了茬缩,看看效果就知道了。

四種紋理環(huán)繞方式的效果對比

怎么樣吼旧,只要視力在1000度之內(nèi)凰锡,都能看出明顯的區(qū)別吧。

設(shè)置紋理環(huán)繞方式的方法是調(diào)用glTexParameteri函數(shù)圈暗,具體方式如下:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    //橫坐標(biāo)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    //縱坐標(biāo)

至于當(dāng)你設(shè)定了GL_CLAMP_TO_BORDER的環(huán)繞方式掂为,想要指定邊界顏色,就需要使用glTexParameterfv函數(shù)了员串,像這樣:

float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };  //指定成黃色
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); 

記得在設(shè)置了環(huán)繞方式之后用勇哗!

四、紋理過濾(Texture Filtering)

紋理坐標(biāo)采用了浮點(diǎn)數(shù)的形式寸齐,表明了它和分辨率無關(guān)欲诺。OpenGL需要非常精確的計(jì)算出紋理像素(通常被稱為紋素)和紋理坐標(biāo)之間的對應(yīng)關(guān)系。當(dāng)你有一張低分辨率的紋理圖渺鹦,但是需要用到一個(gè)非常大的物體上時(shí)扰法,這種操作的重要性就更加明顯了。聰明的你可能已經(jīng)猜到了毅厚,沒錯(cuò)塞颁,OpenGL提供了幾種不同的方案來解決這個(gè)問題,我們只討論最重要的兩種:GL_NEAREST和GL_LINEAR吸耿。

  • GL_NEAREST
    最近點(diǎn)過濾祠锣。指的是紋理坐標(biāo)最靠近哪個(gè)紋素,就用哪個(gè)紋素珍语。這是OpenGL默認(rèn)的過濾方式锤岸,速度最快,但是效果最差板乙。
  • GL_LINEAR
    (雙)線性過濾是偷。指的是紋理坐標(biāo)位置附近的幾個(gè)紋素值進(jìn)行某種插值計(jì)算之后的結(jié)果拳氢。這是應(yīng)用最廣泛的一種方式,效果一般蛋铆,速度較快馋评。

不過,你一定有個(gè)疑問刺啦,這些方法使用后留特,顯示上有啥區(qū)別?別急玛瘸,我們來看兩張圖就知道了蜕青。

最近點(diǎn)過濾和線性過濾的區(qū)別(圖片資源來自:www.learningopengl.com)

什么,你問我那張美女圖呢糊渊?這個(gè)右核,不是我不想用,是那張圖實(shí)在是太不明顯了渺绒,怕你看不出來贺喝。我們還是來看這張圖,效果杠杠的宗兼。

很明顯躏鱼,最近點(diǎn)過濾的像素痕跡非常明顯,看著就跟“屎大棒”似的殷绍。而線性過濾的方式效果就好上很多了染苛,雖然感覺很模糊,但我們完全能理解一張小圖放大之后會(huì)模糊這件事篡帕。

設(shè)置過濾方式還是使用glTexParameteri殖侵,像這樣:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  //縮小時(shí)的過濾方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  //放大時(shí)的過濾方式

五、Mipmaps

多級(jí)漸進(jìn)紋理镰烧。雖然有這樣的翻譯拢军,但是這種翻譯太小眾了,還是決定使用英文來表示怔鳖。(筆者對自己的英文能力還是有信心的茉唉,不然也不會(huì)去看英文資料,嘿嘿~)

言歸正傳结执!想象這樣一個(gè)場景度陆,有非常多的同種物體,距離觀察者的遠(yuǎn)近各不相同献幔,我們可以對這種物體使用同一張紋理貼圖懂傀,但是問題來了,對于那些離觀察者比較遠(yuǎn)的物體蜡感,真的有必要用原始的紋理貼圖去映射嗎蹬蚁?答案當(dāng)然是否定的恃泪。太遠(yuǎn)的物體我們看不清楚,顯示的非常精細(xì)沒有意義犀斋,而且使用原始貼圖計(jì)算映射起來太麻煩贝乎,所以,我們使用一種mipmaps的方式來進(jìn)行處理叽粹。

所謂的mipmaps览效,就是一系列的紋理圖片,每一張紋理圖的大小都是前一張的1/4虫几,直到剩最后一個(gè)像素為止锤灿。看起來就像是這一個(gè)樣子:

mipmaps示例(圖片資源來自:www.learningopengl.com)

當(dāng)物體越離越遠(yuǎn)的時(shí)候持钉,就可以選用較小紋理去映射衡招,這樣不僅效果好,而且速度也快每强。

你可能會(huì)有疑問,這個(gè)圖片是程序弄的還是美術(shù)弄的呢州刽?對于這個(gè)問題空执,我的回答是:美術(shù)弄不弄我不知道,但是程序肯定可以弄穗椅,而且弄起來還非常方便辨绊。我們只要調(diào)用一個(gè)函數(shù)就行了,那就是glGenerateMipmaps匹表。

那我們開始用吧门坷!哦偶,還不行袍镀,還有一個(gè)問題沒解決默蚌。

疑問:
看上去很好,可是我物體的大小剛好在兩張mipmaps之間怎么辦呢苇羡?

對于剛好在兩張圖片之間的物體绸吸,我們可以參考前面兩種過濾方式,最近點(diǎn)(采用最接近的圖)或者線性(采用兩張圖的加權(quán)平均)设江。這樣锦茁,我們就有了四種不同的過濾方案。

  • GL_NEAREST_MIPMAP_NEAREST:采用最近的mipmap圖叉存,在紋理采樣的時(shí)候使用最近點(diǎn)過濾采樣码俩。
  • GL_LINEAR_MIPMAP_NEAREST:采用最近的mipmap圖,紋理采樣的時(shí)候使用線性過濾采樣歼捏。
  • GL_NEAREST_MIPMAP_LINEAR:采用兩張mipmap圖的線性插值紋理圖稿存,紋理采樣的時(shí)候采用最近點(diǎn)過濾采樣笨篷。
  • GL_LINEAR_MIPMAP_LINEAR:采用兩張mipmap圖的線性插值紋理圖,紋理采樣的時(shí)候采用線性過濾采樣挠铲。

好了冕屯,這次是真的可以用了。使用的函數(shù)還是一樣拂苹,glTexParameteri安聘。像這樣:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);  //都是線性過濾
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

這里要注意一點(diǎn),mipmaps是用來處理物體變小時(shí)候如何進(jìn)行貼圖的問題的,所以不需要設(shè)置GL_TEXTURE_MAG_FILTER成mipmap方式。如果強(qiáng)行使用了脓杉,會(huì)報(bào)錯(cuò)赂韵。(不信的話去試試!)

六谤草、使用

準(zhǔn)備

我們要做的第一件事就是將紋理圖加載到我們的應(yīng)用之中,但是,圖片的格式不計(jì)其數(shù)榴芳,難道我們要對每一種格式都寫一個(gè)加載的模塊嗎?這顯然不是我們想要的跺撼。最好能有一個(gè)庫來加載所有的圖片格式窟感,讓我們可以直接用,這樣我們就可以專注在映射上了歉井。

幸運(yùn)的是柿祈,確實(shí)有這樣一個(gè)庫我們可以直接用(鏈接)。打包下載之后哩至,將其中的stb_image.h文件包含到我們的項(xiàng)目中去躏嚎,我們要使用這個(gè)文件。

使用方式

我們使用stbi_load函數(shù)來加載圖片菩貌,并且將圖片格式信息保存起來卢佣。像這樣:

int width, height, nrChannels;
unsigned char *data = stbi_load("beauty.jpg", &width, &height, &nrChannels, 0); 

width,height和nrChannels變量中分別會(huì)保存圖片的寬度菜谣、高度和顏色通道數(shù)量的信息珠漂,這些都是在之后有用的數(shù)據(jù)。

頂點(diǎn)數(shù)據(jù)

到這里尾膊,我們的頂點(diǎn)已經(jīng)有許多相關(guān)聯(lián)的數(shù)據(jù)了媳危,比如顏色,比如紋理坐標(biāo)冈敛,是時(shí)候該給我們的頂點(diǎn)數(shù)組升升級(jí)了待笑。

我們的頂點(diǎn)數(shù)組中需要三樣?xùn)|西:位置、顏色抓谴、紋理坐標(biāo)暮蹂。每個(gè)頂點(diǎn)都需要這三組數(shù)據(jù)寞缝,在數(shù)組中依次排下去。于是仰泻,頂點(diǎn)數(shù)組就成了現(xiàn)在這個(gè)樣子:

float vertices[] = {
    //位置                  // 顏色                 //紋理坐標(biāo)
    0.5f,   0.5f,   0.0f,   1.0f,   0.0f,   0.0f,   1.0f,   1.0f,   //右上角
    0.5f,   -0.5f,  0.0f,   0.0f,   1.0f,   0.0f,   1.0f,   0.0f,   //右下角
    -0.5f,  -0.5f,  0.0f,   0.0f,   0.0f,   1.0f,   0.0f,   0.0f,   //左下角
    -0.5f,  0.5f,   0.0f,   1.0f,   1.0f,   0.0f,   0.0f,   1.0f    //左上角

};
頂點(diǎn)數(shù)組的結(jié)構(gòu)

可以看到荆陆,我們的跨度變成了32,也就是8sizeof(float)集侯,顏色的起始偏移值為3sizeof(float)被啼,紋理的起始偏移值為6*sizeof(float)。這樣棠枉,我們指定頂點(diǎn)屬性的時(shí)候自然需要指定相應(yīng)的位置和偏移浓体。

顏色屬性:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);

紋理屬性:

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);

頂點(diǎn)著色器中,我們需要采用輸入的顏色和紋理坐標(biāo)進(jìn)行操作辈讶,所以命浴,在著色器中添加兩個(gè)輸入是非常好的選擇。

layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

然后贱除,我們的頂點(diǎn)著色器代碼就成了這個(gè)樣子:

//頂點(diǎn)著色器代碼
#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}

代碼都是自解釋的生闲,非常容易理解,就不再浪費(fèi)口舌了月幌。相應(yīng)的跪腹,我們的片元著色器也就成了這個(gè)樣子:

//片元著色器代碼
#version 330 core

out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord);  //對紋理指定位置進(jìn)行采樣
}

創(chuàng)建紋理

想OpenGL里的其他東西那樣,紋理也需要一個(gè)唯一ID飞醉,我們來創(chuàng)建一個(gè):

unsigned int texture;
glGenTextures(1, &texture);

glGenTextures的第一個(gè)參數(shù)是要?jiǎng)?chuàng)建的紋理數(shù)量,后面的參數(shù)就是保存這么多數(shù)量的整型數(shù)數(shù)組屯阀。當(dāng)然缅帘,創(chuàng)建完了之后我們也需要綁定到OpenGL的環(huán)境里才能操作。

glBindTexture(GL_TEXTURE_2D, texture);

綁定完成后难衰,我們就可以把之前加載的圖片數(shù)據(jù)放到紋理中去了钦无。

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);

又是一個(gè)擁有很多參數(shù)的龐大函數(shù)。我們一點(diǎn)點(diǎn)啃死它盖袭!

  • 參數(shù)一:指定目標(biāo)紋理失暂。GL_TEXTURE_2D就表示當(dāng)前的操作會(huì)對綁定的2D紋理產(chǎn)生作用(GL_TEXTURE_1D和GL_TEXTURE_3D里的東西就不會(huì)受影響)
  • 參數(shù)二:mipmap層級(jí)。我們之后會(huì)調(diào)用glGenerateMipmap來創(chuàng)建鳄虱,這里只需要?jiǎng)?chuàng)建原始圖就行了弟塞。(或者你也可以手動(dòng)的一次次調(diào)用這個(gè)函數(shù)來創(chuàng)建,(壞笑~))
  • 參數(shù)三:我們需要保存的紋理格式拙已。我們的圖片只有RGB信息决记,所以用GL_RGB格式。
  • 參數(shù)四和參數(shù)五:紋理圖片的寬高倍踪。之前保存的那個(gè)系宫。
  • 參數(shù)六:一定要設(shè)置成0(有一些遺留的工作)
  • 參數(shù)七和參數(shù)八:源圖片的格式和數(shù)據(jù)類型索昂。我們加載的圖片中有RGB值,并且以字節(jié)的方式保存扩借。所以我們傳遞了這兩個(gè)參數(shù)椒惨。
  • 參數(shù)九:加載的圖片數(shù)據(jù)。

調(diào)用glTexImage2D之后潮罪,當(dāng)前的紋理對象就和我們的紋理圖綁定起來了康谆。然后,我們再調(diào)用glGenerateMipmap函數(shù)創(chuàng)建mipmaps错洁,非常流暢~

操作完成之后秉宿,最好要把圖片釋放掉,因?yàn)閿?shù)據(jù)已經(jīng)都保存到紋理對象中了屯碴,這樣干:

stbi_image_free(data);

整個(gè)代碼塊就是這個(gè)樣子:

//紋理
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//設(shè)置紋理包裝和過濾的方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
//stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load("beauty.jpg", &width, &height, &nrChannels, 0);
if (data) {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
    std::cout << "無法加載問題描睦,請檢查代碼或資源是否有誤。" << std::endl;
stbi_image_free(data);

七导而、運(yùn)行

好忱叭,咱就運(yùn)行起來。

運(yùn)行效果

嗯今艺?不對啊韵丑,怎么是倒的?

這是因?yàn)镺penGL期待原點(diǎn)(0,0)位于左下角虚缎,而通常一張圖片的原點(diǎn)位于左上角撵彻。不過,這不是問題实牡,stb庫早就已經(jīng)為我們準(zhǔn)備了解決方案陌僵。在加載圖片之前調(diào)用stbi_set_flip_vertically_on_load(true);

哈哈,是不是注意到了我之前注釋掉的那行代碼创坞,沒錯(cuò)碗短,就是為了顯示出倒圖而故意注掉的。

好题涨,再次編譯運(yùn)行偎谁,這次的效果才對!

正確的效果

八纲堵、結(jié)語

呼~ 好長的一篇巡雨,不過總算是弄了點(diǎn)東西,辛苦沒有白費(fèi)~

下一篇
目錄
上一篇

參考資料:
www.learningopengl.com(非常好的網(wǎng)站婉支,建議也去學(xué)習(xí))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸯隅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蝌以,老刑警劉巖炕舵,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異跟畅,居然都是意外死亡咽筋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進(jìn)店門徊件,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奸攻,“玉大人,你說我怎么就攤上這事虱痕《媚停” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵部翘,是天一觀的道長硝训。 經(jīng)常有香客問我,道長新思,這世上最難降的妖魔是什么窖梁? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮夹囚,結(jié)果婚禮上纵刘,老公的妹妹穿的比我還像新娘。我一直安慰自己荸哟,他們只是感情好假哎,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鞍历,像睡著了一般位谋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堰燎,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機(jī)與錄音笋轨,去河邊找鬼秆剪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛爵政,可吹牛的內(nèi)容都是我干的仅讽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼钾挟,長吁一口氣:“原來是場噩夢啊……” “哼洁灵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤徽千,失蹤者是張志新(化名)和其女友劉穎苫费,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體双抽,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡百框,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牍汹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铐维。...
    茶點(diǎn)故事閱讀 40,444評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖慎菲,靈堂內(nèi)的尸體忽然破棺而出嫁蛇,到底是詐尸還是另有隱情,我是刑警寧澤露该,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布睬棚,位于F島的核電站,受9級(jí)特大地震影響有决,放射性物質(zhì)發(fā)生泄漏闸拿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一书幕、第九天 我趴在偏房一處隱蔽的房頂上張望新荤。 院中可真熱鬧,春花似錦台汇、人聲如沸苛骨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痒芝。三九已至,卻和暖如春牵素,著一層夾襖步出監(jiān)牢的瞬間严衬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工笆呆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留请琳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓赠幕,卻偏偏與公主長得像俄精,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子榕堰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評論 2 359

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