OpenGL ES:新手村中的HelloWorld


前言


對于OpenGL ES,本人現(xiàn)在還是一個(gè)小白,所以我將用小白視角對OpenGL ES進(jìn)行小白式的講解.希望能通過如此幫助更多的人.同時(shí)我要感謝一個(gè)人,那就是落影l(fā)oyinglin,落影大神關(guān)于OpenGL ES方面的知識寫的非常的詳細(xì),大家可以去參考.好了,開始戰(zhàn)斗吧.


OpenGL ES簡介


OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三維圖形 API 的子集廉嚼,針對手機(jī)、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)。該API由Khronos集團(tuán)定義推廣,Khronos是一個(gè)圖形軟硬件行業(yè)協(xié)會狈定,該協(xié)會主要關(guān)注圖形和多媒體方面的開放標(biāo)準(zhǔn)。

OpenGL ES 是從 OpenGL 裁剪的定制而來的巷挥,去除了glBegin/glEnd烹卒,四邊形(GL_QUADS)、多邊形(GL_POLYGONS)等復(fù)雜圖元等許多非絕對必要的特性倦西。經(jīng)過多年發(fā)展能真,現(xiàn)在主要有兩個(gè)版本,OpenGL ES 1.x 針對固定管線硬件的扰柠,OpenGL ES 2.x 針對可編程管線硬件粉铐。OpenGL ES 1.0 是以 OpenGL 1.3 規(guī)范為基礎(chǔ)的,OpenGL ES 1.1 是以 OpenGL 1.5 規(guī)范為基礎(chǔ)的卤档,它們分別又支持 common 和 common lite兩種profile蝙泼。lite profile只支持定點(diǎn)實(shí)數(shù),而common profile既支持定點(diǎn)數(shù)又支持浮點(diǎn)數(shù)劝枣。 OpenGL ES 2.0 則是參照 OpenGL 2.0 規(guī)范定義的汤踏,common profile發(fā)布于2005-8,引入了對可編程管線的支持舔腾。

那么上面說了這么一些到底是什么意思呢.其實(shí)就是說OpenGL ES是移動(dòng)端處理圖像的一個(gè)C語言庫.


OpenGL ES的顯示圖像


在iOS中,我們平常要加載一張圖片會怎么做呢?一個(gè)是使用UIKit框架的UIImage,一個(gè)是使用Core Graphics框架直接繪制.那么OpenGL ES是如何展現(xiàn)圖像的呢?今天我們就先用OpenGL ES中的GLKBaseEffect來展現(xiàn)圖像.實(shí)現(xiàn)效果如下所示.



HelloWorld的實(shí)現(xiàn)過程


一溪胶、 準(zhǔn)備工作

</b>
為了簡便省時(shí),我決定直接在ViewController中修改代碼,首先我們先導(dǎo)入GLKit.h頭文件,緊接著那個(gè)將ViewController的類型修改為GLKViewController.

然后在Main.storyboard修改ViewController中view的類型為GLKView.如圖所示.

上面的準(zhǔn)備工作已經(jīng)是做完了,那么接下來,就是正題部分了,我們現(xiàn)在ViewController.m中聲明兩個(gè)屬性.一個(gè)是OpenGL ES 上下文屬性的EAGLContext對象,一個(gè)是矩陣相關(guān)的GLKBaseEffect對象.

@interface ViewController ()

@property(nonatomic,strong)EAGLContext *mContext;

@property(nonatomic,strong)GLKBaseEffect *mEffect;

@end

通過官方的API文檔,我們知道,EAGLContext對象管理一個(gè)OpenGL ES渲染環(huán)境狀態(tài)信息,命令,以及使用OpenGL ES的所需要資源。OpenGL ES執(zhí)行任何命令之前,都需要通過EAGLContext對象來實(shí)現(xiàn)稳诚。同時(shí)官方文檔也提到,繪制一個(gè)上下文之前,你必須完成framebuffer對象綁定到上下文哗脖。

GLKBaseEffect這個(gè)類實(shí)現(xiàn)了OpenGL ES 1.0公共(common)的shading行為,簡化(從1.0)到OpenGL ES 2.0的轉(zhuǎn)化。它們也提供了讓光和紋理(lighting and texturing)工作的簡單方法才避。GLKBaseEffect對象提供了著色器這一功能.其實(shí)著色器應(yīng)該算的上是OpenGL ES的一大特色,但是GLKBaseEffect已經(jīng)包含了這一功能,相當(dāng)于封裝了著色器.現(xiàn)在只是知道有著色器就行.

</b>
接下來,我們了解兩個(gè)方法,他們的刷新頻率和屏幕的刷新頻率是一致的.我們需要在- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect這個(gè)方法中進(jìn)行渲染操作.

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;

-(void)update;

</b>

二丘损、ViewDidLoad的配置工作

</b>
我們接下來在ViewDidLoad中需要做以下幾個(gè)工作.

1、配置OpenGL ES 上下文信息
    self.mContext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
    GLKView *view = (GLKView *)self.view;
    
    view.context = self.mContext;
    
    //顏色緩沖區(qū)格式
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    
    [EAGLContext setCurrentContext:self.mContext];

代碼講解:第一行代碼是對控制器自身的EAGLContext對象使用- (instancetype) initWithAPI:(EAGLRenderingAPI) api;進(jìn)行初始化.EAGLRenderingAPI是一個(gè)枚舉類型.包含了三個(gè)值,分別代表著1.0工扎、2.0和3.0的OpenGL ES,我們現(xiàn)在使用的OpenGL ES2.0,所以選擇的是kEAGLRenderingAPIOpenGLES2;

typedef NS_ENUM(NSUInteger, EAGLRenderingAPI)
{
    kEAGLRenderingAPIOpenGLES1 = 1,
    kEAGLRenderingAPIOpenGLES2 = 2,
    kEAGLRenderingAPIOpenGLES3 = 3,
};

第二行和第三行代碼則是把當(dāng)前控制器的View的context設(shè)置為self.mContext.

第四行代碼則是設(shè)置頁面的顏色緩沖區(qū)格式,默認(rèn)的也是GLKViewDrawableColorFormatRGBA8888,所以不做設(shè)置也可以.

第五行代碼則是將此“EAGLContext”實(shí)例設(shè)置為OpenGL的“當(dāng)前激活”的“Context”徘钥。這樣,以后所有“GL”的指令均作用在這個(gè)“Context”上肢娘。

2呈础、配置繪制矩陣數(shù)組信息

OpenGL ES的坐標(biāo)系是和iOS常用的Quartz 2D坐標(biāo)系是不一樣的.OpenGL ES是左手坐標(biāo)系(待議~),Quartz 2D坐標(biāo)系則是右手坐標(biāo)系.OpenGL ES的坐標(biāo)系是以中心為原點(diǎn),原點(diǎn)到屏幕的邊緣為單位1(不管屏幕尺寸如何變化,都是單位1).OpenGL ES的坐標(biāo)系如下所示.

OpenGL ES的坐標(biāo)系

接下來,我們創(chuàng)建頂點(diǎn)數(shù)組,數(shù)組中的元素類型為GLfloat類型.數(shù)組中包含了兩個(gè)坐標(biāo)一個(gè)是頂點(diǎn)坐標(biāo)(x,y,z軸信息),一個(gè)是紋理坐標(biāo)(x,y信息),注意,頂點(diǎn)要與紋理的點(diǎn)一一對應(yīng).關(guān)于紋理相關(guān)只是可以參考我在SpriteKit的文集中的SpriteKit框架之SKTextureAtlas第一部分內(nèi)容.代碼如下所示.

(PS:問什么要這么創(chuàng)建數(shù)組呢?難道是系統(tǒng)規(guī)定的?回答:并不是,數(shù)組的形式規(guī)則定好之后,我們可以按照一定的規(guī)律取出對應(yīng)的數(shù)據(jù)元素.然后進(jìn)行操作.)

        //頂點(diǎn)數(shù)據(jù),前三個(gè)是頂點(diǎn)坐標(biāo)橱健,后面兩個(gè)是紋理坐標(biāo)
    GLfloat squareVertexData[] =
    {
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
        0.5, 0.5, -0.0f,    1.0f, 1.0f, //右上
    };

上面的頂點(diǎn)坐標(biāo)組成看似是一個(gè)正方形,但是實(shí)際上真的如此嗎?NONONO,事實(shí)上,由于屏幕的寬高不相同的原因.所選擇區(qū)域會是下面的這個(gè)樣子的.

</b>
對于初學(xué)者還有個(gè)容易忽視的技術(shù)點(diǎn),那就是 在OpenGL ES只能繪制三角形,不能繪制多邊形,但是在OpenGL中確實(shí)可以直接繪制多邊形.
那么我們改如何繪制一個(gè)矩形呢?我們可以認(rèn)為一個(gè)矩形是兩個(gè)三角形拼接而成的.這時(shí)候,我們就需要整出另外一個(gè)東西:那就是頂點(diǎn)索引數(shù)組.有了它就可以規(guī)定繪制的順序.如下所示.

  //頂點(diǎn)索引
    GLuint indices[] ={ 
      0, 1, 2,
      1, 3, 0
     };

繪制過程如圖所示.先是做下三角形,再是右上三角形.


繪制順序圖示


3.將頂點(diǎn)數(shù)據(jù)和頂點(diǎn)索引數(shù)據(jù)寫入通用的頂點(diǎn)屬性存儲區(qū) (重點(diǎn)核心部分??????)

其實(shí)我一直沒有理解"通用"這個(gè)詞(寫這篇博客寫到最后竟然理解了,因?yàn)轫旤c(diǎn)屬性集中包含五種屬性:位置而钞、法線、顏色拘荡、紋理0臼节,紋理1,所以只能用"通用"這個(gè)詞了).那么把頂點(diǎn)數(shù)據(jù)和頂點(diǎn)索引數(shù)據(jù)寫入通用的頂點(diǎn)屬性存儲區(qū),是怎么樣的過程呢?首先將頂點(diǎn)數(shù)據(jù)和頂點(diǎn)索引數(shù)據(jù)保存進(jìn)GUP的一個(gè)緩沖區(qū)中,然后再按一定規(guī)則珊皿,將數(shù)據(jù)取出网缝,復(fù)制到各個(gè)通用頂點(diǎn)屬性中.

那么接下來,我們先將頂點(diǎn)數(shù)組保存進(jìn)GPU緩沖區(qū)中.代碼如下所示.

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);

然后就是把頂點(diǎn)索引數(shù)組寫進(jìn)GPU緩沖區(qū)中.

    GLuint index;
    glGenBuffers(1, &index);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
函數(shù)說明:

  • glGenBuffers(GLsizei n,GLuint *buffers):任何非零的無符合整數(shù)都可以作為緩沖區(qū)對象的標(biāo)識符使用。這個(gè)函數(shù)的作用就是向系統(tǒng)申請n個(gè)緩沖區(qū)蟋定,系統(tǒng)把這n個(gè)緩沖區(qū)的標(biāo)識符都放進(jìn)buffers數(shù)組中粉臊。還可以調(diào)用glIsBuffer()函數(shù)判斷一個(gè)標(biāo)識符是否正被使用。
    例如,glGenBuffers(1, &index);這是是向系統(tǒng)申請1個(gè)緩沖區(qū),標(biāo)識符為index.

  • glBindBuffer(GLenum target, GLuint buffer) :把這個(gè)緩沖區(qū)綁定給頂點(diǎn)還是索引.通俗點(diǎn),也就是定義了這個(gè)緩沖區(qū)存儲的是什么.target用于決定綁定的是頂點(diǎn)數(shù)據(jù)(GL_ARRAY_BUFFER)還是索引數(shù)據(jù)(GL_ELEMENT_ARRAY_BUFFER).

  • glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage):把CPU中的內(nèi)存中的數(shù)組復(fù)制到GPU的內(nèi)存中.target用于決定綁定的是頂點(diǎn)數(shù)據(jù)(GL_ARRAY_BUFFER)還是索引數(shù)據(jù)(GL_ELEMENT_ARRAY_BUFFER).size決定數(shù)據(jù)的存儲長度.data則是數(shù)據(jù)信息.usage表示數(shù)據(jù)的讀寫方式,是一個(gè)枚舉類型,這里使用的是GL_STATIC_DRAW,它表示此緩沖區(qū)內(nèi)容只能被修改一次驶兜,但可以無限次讀取扼仲。


</b>
然后,將GPU緩沖區(qū)的頂點(diǎn)數(shù)據(jù)復(fù)制進(jìn)通用頂點(diǎn)屬性中.注意:索引數(shù)據(jù)不需要復(fù)制到通用頂點(diǎn)屬性中.具體代碼如下.

    //頂點(diǎn)數(shù)據(jù)
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *) NULL +0);
    
    //紋理數(shù)據(jù)
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL +3);
函數(shù)說明:

  • glEnableVertexAttribArray (GLuint index) : 激活頂點(diǎn)屬性(默認(rèn)它的關(guān)閉的).在剛開始,我們就說到頂點(diǎn)屬性集中包含五種屬性:位置、法線抄淑、顏色屠凶、紋理0,紋理1.頂點(diǎn)屬性集是一個(gè)枚舉值.這里我們只用到了位置和紋理這兩個(gè)屬性.
typedef NS_ENUM(GLint, GLKVertexAttrib)
{
    GLKVertexAttribPosition,
    GLKVertexAttribNormal,
    GLKVertexAttribColor,
    GLKVertexAttribTexCoord0,
    GLKVertexAttribTexCoord1
} NS_ENUM_AVAILABLE(10_8, 5_0);

</b>

  • glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) : 往對應(yīng)的頂點(diǎn)屬性中添加數(shù)據(jù).indx為頂點(diǎn)屬性類型.size為每個(gè)數(shù)據(jù)中的數(shù)據(jù)長度.type為元素?cái)?shù)據(jù)類型,normalized填充時(shí)需不需要單位化.stride需要填寫的是在數(shù)據(jù)數(shù)組中每行的跨度,最后一個(gè)ptr指針是說的是每一個(gè)數(shù)據(jù)的起始位置將從內(nèi)存數(shù)據(jù)塊的什么地方開始肆资。例如頂點(diǎn)屬性的數(shù)據(jù)填充示意圖如下所示.


4.將圖片紋理賦值給GLKBaseEffect對象

本文的前面我就提到了圖片紋理和紋理集,紋理集最好的好處就是節(jié)省內(nèi)存,具體看我以前寫的博客,上面有提到,這里就不啰嗦了.在OpenGL ES也是有紋理(GLKTextureInfo)這一概念,應(yīng)該說Sprite Kit框架就是封裝的OpenGL ES??.下面我們先把圖片加載到紋理對象中.

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
    
    GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil ];

然后創(chuàng)建GLKBaseEffect對象并且開啟它的可編輯狀態(tài),然后把紋理賦值給GLKBaseEffect對象.

    self.mEffect = [[GLKBaseEffect alloc]init];
    
    self.mEffect.texture2d0.enabled = GL_TRUE;

    self.mEffect.texture2d0.name = textureInfo.name;

</b>

三矗愧、渲染場景

</b>
可能沒接觸過Sprite Kit的童靴不太了解場景(Scene),你可以理解為是繪制圖層,當(dāng)然了,這個(gè)繪制的頻率是跟屏幕刷新頻率是一致的(默認(rèn)的).在GLKit框架中,GLKView對象是完全不需要做任何操作的,只要在控制器中執(zhí)行- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect-(void)update這兩個(gè)方法就可以在GLKView對象上顯示圖像了.一般我們把渲染代碼寫在- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect.如下所示.

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClearColor(0.3f, 0.6f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //啟動(dòng)著色器
    [self.mEffect prepareToDraw];
    glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0);
    
}

函數(shù)說明:

  • glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) : 渲染前的“清除”操作,指定在清除屏幕之后填充什么樣的顏色.四個(gè)參數(shù)就是RGB值.

  • glClear (GLbitfield mask) :指定需要清除的緩沖.mask指定緩沖的類型.可以使用 | 運(yùn)算符組合不同的緩沖標(biāo)志位迅耘,表明需要清除的緩沖.可以使用以下標(biāo)識符.

GL_COLOR_BUFFER_BIT: 當(dāng)前可寫的顏色緩沖

GL_DEPTH_BUFFER_BIT: 深度緩沖

GL_ACCUM_BUFFER_BIT: 累積緩沖

GL_STENCIL_BUFFER_BIT: 模板緩沖

[self.mEffect prepareToDraw];這個(gè)就是啟動(dòng)當(dāng)前GLKBaseEffect對象.

  • glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) : 通過頂點(diǎn)索引繪制圖像.mode指定的繪制的類型.類型展示如下,這里使用的是GL_TRIANGLES,count指定的頂點(diǎn)索引數(shù)組中元素的個(gè)數(shù),type 為索引數(shù)組(indices)中元素的類型贱枣,只能是下列值之一: GL_UNSIGNED_BYTE ,GL_UNSIGNED_SHORT,GL_UNSIGNED_INT. indices指向索引數(shù)組的指針。
GL_POINTS:  單獨(dú)的將頂點(diǎn)畫出來颤专。

GL_LINES:  單獨(dú)地將直線畫出來纽哥。

GL_LINE_STRIP:  連貫地將直線畫出來。

GL_LINE_LOOP:  連貫地將直線畫出來栖秕。行為和GL_LINE_STRIP類似春塌,但是會自動(dòng)將最后一個(gè)頂點(diǎn)和第一個(gè)頂點(diǎn)通過直線連接起來。

GL_TRIANGLES:這個(gè)參數(shù)意味著OpenGL使用三個(gè)頂點(diǎn)來組成圖形。所以只壳,在開始的三個(gè)頂點(diǎn)俏拱,將用頂點(diǎn)1,頂點(diǎn)2吼句,頂點(diǎn)3來組成一個(gè)三角形锅必。完成后,在用下一組的三個(gè)頂點(diǎn)(頂點(diǎn)4惕艳,5搞隐,6)來組成三角形,直到數(shù)組結(jié)束远搪。

GL_TRIANGLE_STRIP:  OpenGL的使用將最開始的兩個(gè)頂點(diǎn)出發(fā)劣纲,然后遍歷每個(gè)頂點(diǎn),這些頂點(diǎn)將使用前2個(gè)頂點(diǎn)一起組成一個(gè)三角形谁鳍。

GL_TRIANGLE_FAN:  在跳過開始的2個(gè)頂點(diǎn)癞季,然后遍歷每個(gè)頂點(diǎn),讓OpenGL將這些頂點(diǎn)于它們前一個(gè)倘潜,以及數(shù)組的第一個(gè)頂點(diǎn)一起組成一個(gè)三角形绷柒。


HelloWorld之路的結(jié)束


如果沒有太大的問題的話,那么我們就會出現(xiàn)一開始的模擬器效果了.想想一張圖片展示底層顯示代碼是這么的多,想哭有木有??.其實(shí)這只是OpenGL ES的冰山一角.接下來,我將對著色器相關(guān)的部分進(jìn)行研究講解,如果有任何疑問,可以在評論區(qū)回復(fù),共同討論進(jìn)步.最后附上HelloWorld的實(shí)現(xiàn)Demo.

OpenGLES相關(guān)學(xué)習(xí)Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窍荧,隨后出現(xiàn)的幾起案子辉巡,更是在濱河造成了極大的恐慌,老刑警劉巖蕊退,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異憔恳,居然都是意外死亡瓤荔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門钥组,熙熙樓的掌柜王于貴愁眉苦臉地迎上來输硝,“玉大人,你說我怎么就攤上這事程梦〉惆眩” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵屿附,是天一觀的道長郎逃。 經(jīng)常有香客問我,道長挺份,這世上最難降的妖魔是什么褒翰? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上优训,老公的妹妹穿的比我還像新娘朵你。我一直安慰自己,他們只是感情好揣非,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布抡医。 她就那樣靜靜地躺著,像睡著了一般早敬。 火紅的嫁衣襯著肌膚如雪魂拦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天搁嗓,我揣著相機(jī)與錄音芯勘,去河邊找鬼。 笑死腺逛,一個(gè)胖子當(dāng)著我的面吹牛荷愕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棍矛,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼安疗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了够委?” 一聲冷哼從身側(cè)響起荐类,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茁帽,沒想到半個(gè)月后玉罐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡潘拨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年吊输,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铁追。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡季蚂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出琅束,到底是詐尸還是另有隱情扭屁,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布涩禀,位于F島的核電站料滥,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏埋泵。R本人自食惡果不足惜幔欧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一罪治、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧礁蔗,春花似錦觉义、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至磺浙,卻和暖如春洪囤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撕氧。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工瘤缩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伦泥。 一個(gè)月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓剥啤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親不脯。 傳聞我的和親對象是個(gè)殘疾皇子府怯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

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