0010--OpenGL ES初探:GLKit 案例實現(xiàn)-加載圖片和立方體旋轉(zhuǎn)

圖片渲染

  • 新建一個ViewController繼承自GLKViewController
  • 把這個控制器設(shè)置為根視圖,view改成基礎(chǔ)GLKView
  • 導(dǎo)入相應(yīng)頭文件

#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>

setUpConfig

初始化上下文&設(shè)置當(dāng)前上下文

  1. 使用OpenGL做任何事前,你都需要先創(chuàng)建一個EAGLContext返十。
  2. iOS使用OpenGL進行繪制時需要一些信息奋刽,這些信息都由EAGLContext管理旱函。這和你使用一個Core Graphics上下文差不多应结。
  3. 當(dāng)你創(chuàng)建一個上下文時图毕,你需要定義要使用的API版本推励。

EAGLContext 是蘋果iOS平臺下實現(xiàn)OpenGLES 渲染層.

1. `kEAGLRenderingAPIOpenGLES1` = 1, 固定管線
2. `kEAGLRenderingAPIOpenGLES2` = 2,
3. `kEAGLRenderingAPIOpenGLES3` = 3,
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

設(shè)置當(dāng)前上下文

[EAGLContext setCurrentContext:context];

獲取GLKView & 設(shè)置context

  • 這創(chuàng)建了一個新的GLKView的實例曲梗,并使它和整個window一樣大。
  • 當(dāng)你創(chuàng)建一個GLKView的時候弄跌,你需要告訴它要使用的OpenGL上下文甲喝,所以配置成我們剛剛創(chuàng)建的context
GLKView *view = (GLKView *)self.view; view.context = context;

配置視圖創(chuàng)建的渲染緩存區(qū)

  • drawableColorFormat: 顏色緩存區(qū)格式
  1. 簡介:OpenGL ES 有一個緩存區(qū)铛只,它用以存儲將在屏幕中顯示的顏色埠胖。你可以使用其屬性來設(shè)置緩沖區(qū)中的每個像素的顏色格式。
  2. GLKViewDrawableColorFormatRGBA8888:此值為默認值淳玩,緩存區(qū)的每個像素的最小組成部分(RGBA)使用8個bit直撤,(所以每個像素4個字節(jié),4*8個bit)蜕着。
  3. GLKViewDrawableColorFormatRGB565:如果你的APP允許更小范圍的顏色谋竖,即可設(shè)置這個红柱。會讓你的APP消耗更小的資源(內(nèi)存和處理時間)
  • drawableDepthFormat(深度緩存區(qū)格式):如果你要使用這個屬性(一般用于3D游戲),你應(yīng)該選擇GLKViewDrawableDepthFormat16GLKViewDrawableDepthFormat24蓖乘。這里的差別是使用GLKViewDrawableDepthFormat16將消耗更少的資源锤悄。
  1. GLKViewDrawableDepthFormatNone = 0:意味著完全沒有深度緩沖區(qū)
  2. GLKViewDrawableDepthFormat16
  3. GLKViewDrawableDepthFormat24
 view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat16;

設(shè)置背景顏色

定義用來清理屏幕的RGB顏色alpha(透明度)值。這里我們設(shè)置紅色嘉抒。

 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

setUpVertexData

準(zhǔn)備數(shù)據(jù)

四邊形是有兩個三角形組成.


 GLfloat vertexData[] = {
        
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        0.5, 0.5,  0.0f,    1.0f, 1.0f, //右上
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        
        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, //左下
    };

綁定數(shù)據(jù)

創(chuàng)建頂點緩存區(qū)標(biāo)識符ID

函數(shù)原型:void glGenBuffers(GLsizei n,GLuint * buffers);
第一個參數(shù):要生成的緩沖對象的數(shù)量
第二個參數(shù):要輸入用來存儲緩沖對象名稱的數(shù)組

如果使用數(shù)組保存

GLuint bufferID[3];
glGenBuffers(3,bufferID);

  • 單個GLuint數(shù)據(jù)

GLuint bufferID;
glGenTextures(1, &bufferID);

綁定頂點緩存區(qū)(明確作用)

函數(shù)原型:void glBindBuffer(GLenum target,GLuint buffer);
第一個參數(shù):緩沖對象的類型
第二個參數(shù):要綁定的緩沖對象的名稱

  • 使用該函數(shù)將緩沖對象綁定到OpenGL上下文環(huán)境中以便使用零聚。
  • 如果把target綁定到一個已經(jīng)創(chuàng)建好的緩沖對象,那么這個緩沖對象將為當(dāng)前target的激活對象些侍。
  • 但是如果綁定的buffer值為0隶症,那么OpenGL將不再對當(dāng)前target使用任何緩存對象。

  glBindTexture(GL_ARRAY_BUFFER, bufferID);

OpenGL允許我們同時綁定多個緩沖類型岗宣,只要這些緩沖類型是不同的蚂会,換句話說,同一時間耗式,不能綁定兩個相同類型的緩沖對象颂龙。也可以理解為對于一個類型來說,同一時間只能“激活”一個類型纽什,否則就會發(fā)生“矛盾”措嵌。

第二個參數(shù)雖然是GLuint類型的,但是你萬萬不能直接指定個常量比如說0芦缰,否則會出現(xiàn)GL_INVALID_VALUE的錯誤企巢,具體如下:
GL_INVALID_VALUE is generated if buffer is not a name previously returned form a call to glGenBuffers

將頂點數(shù)組的數(shù)據(jù)copy到頂點緩存區(qū)中(GPU顯存中)


 glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

插槽重識(打開讀取通道)

GLKit目標(biāo)就是簡化, 里面有很多對OpenGLES的封裝, 我們也可以不用進行shader的編輯, 不用在寫glsl就能完成shader的繪制

GLKVertexAttribPosition就是position位置插槽,
GLKVertexAttribColor就是color位置插槽,
GLKVertexAttribTexCoord0就是texcoord0位置插槽,

  • glEnableVertexAttribArray:在iOS中, 默認情況下,出于性能考慮让蕾,所有頂點著色器的屬性(Attribute)變量都是關(guān)閉的浪规。

意味著,頂點數(shù)據(jù)在著色器端(服務(wù)端)是不可用的。即使你已經(jīng)使用glBufferData方法探孝,將頂點數(shù)據(jù)從內(nèi)存拷貝到頂點緩存區(qū)中(GPU顯存中)笋婿。

所以, 必須由glEnableVertexAttribArray方法打開通道。指定訪問屬性顿颅,才能讓頂點著色器能夠訪問到從CPU復(fù)制到GPU的數(shù)據(jù)缸濒。

注意: 數(shù)據(jù)在GPU端是否可見,即粱腻,著色器能否讀取到數(shù)據(jù)庇配,由是否啟用了對應(yīng)的屬性決定,這就是glEnableVertexAttribArray的功能绍些,允許頂點著色器讀取GPU(服務(wù)器端)數(shù)據(jù)捞慌。

  • glVertexAttribPointer

函數(shù)原型:


glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)

功能:上傳頂點數(shù)據(jù)到顯存的方法(設(shè)置合適的方式從buffer里面讀取數(shù)據(jù))

參數(shù)列表:

  1. index:指定要修改的頂點屬性的索引值
  2. size:每次讀取數(shù)量。(如position是由3個(x,y,z)組成柬批,而顏色是4個(r,g,b,a),紋理則是2個.)
  3. type:指定數(shù)組中每個組件的數(shù)據(jù)類型啸澡⌒涠可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和GL_FLOAT,初始值為GL_FLOAT嗅虏。
    4.normalized:指定當(dāng)被訪問時著角,固定點數(shù)據(jù)值是否應(yīng)該被歸一化(GL_TRUE)或者直接轉(zhuǎn)換為固定點值(GL_FALSE
  4. stride:指定連續(xù)頂點屬性之間的偏移量。如果為0旋恼,那么頂點屬性會被理解為:它們是緊密排列在一起的。初始值為0
  5. ptr:指定一個指針奄容,指向數(shù)組中第一個頂點屬性的第一個組件冰更。初始值為0

glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
    
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
      glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);

  • (GLfloat *)NULL null值包裝為0
  • (GLfloat *)NULL + 3 起始位置
  • 乘以5直接間隔

setUpTexture

紋理矩陣

  • 獲取紋理圖片路徑

NSString *filePath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"jpg"];

  • 設(shè)置紋理參數(shù)

由于紋理坐標(biāo)系是跟手機顯示的Quartz 2D坐標(biāo)系的y軸正好相反,紋理坐標(biāo)系使用左下角為原點昂勒,往上為y軸的正值蜀细,往右是x軸的正值,所以需要設(shè)置一下GLKTextureLoaderOriginBottomLeft戈盈。


 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];

  • 使用蘋果GLKit 提供GLKBaseEffect 完成著色器工作(頂點/片元)

eEffect = [[GLKBaseEffect alloc] init];
eEffect.texture2d0.enabled = GL_TRUE;
eEffect.texture2d0.name = textureInfo.name;

  • 繪制

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    
    glClear(GL_COLOR_BUFFER_BIT);
    
    [eEffect prepareToDraw];
    
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

效果圖

image.png

下來做一個立方體的貼圖,并旋轉(zhuǎn).

準(zhǔn)備工作

立方體和單個四邊形區(qū)別,多了5個面,定點數(shù)也有原來的6個變成36個.

  • 首先創(chuàng)建需要的類已經(jīng)一個OPVertex來存放頂點和紋理頂點.


ypedef struct OPVertex{
    GLKVector3 positionCoord;//頂點坐標(biāo)
    GLKMatrix2 texturecoord; //紋理
}OPVertex;

//總共頂點數(shù)
static int const kCoordCount = 36;



EAGLContext *context; //上下文
GLKBaseEffect *cEffect;// 著色器
NSInteger angle; //記錄旋轉(zhuǎn)的角度
GLKView *glkView; //glkView

@property(nonatomic, assign) OPVertex *vertices;


繪制

  • 初始化上下文&設(shè)置當(dāng)前上下文,設(shè)置渲染區(qū)和背景顏色

這一步和之前繪制沒有變化


-(void)setUpConfig
{
   
    context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
    //判斷context是否創(chuàng)建成功
    if (!context) {
        NSLog(@"Create ES context Failed");
    }
    //設(shè)置當(dāng)前上下文
    [EAGLContext setCurrentContext:context];
    
    //2.獲取GLKView & 設(shè)置context
    GLKView *view =(GLKView *) self.view;
    view.context = context;
   
    //3.配置視圖創(chuàng)建的渲染緩存區(qū).
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    glkView = view;
    
    //4.設(shè)置背景顏色
    glClearColor(1, 0, 0, 1.0);
}

  • 加載頂點/紋理坐標(biāo)數(shù)據(jù)
  1. 使用malloc分配內(nèi)存

 self.vertices = malloc(sizeof(OPVertex) * kCoordCount);

  1. 6個面對應(yīng)的頂點和紋理坐標(biāo)

// 前面
    self.vertices[0] = (OPVertex){{-0.5, 0.5, 0.5},  {0, 1}};
    self.vertices[1] = (OPVertex){{-0.5, -0.5, 0.5}, {0, 0}};
    self.vertices[2] = (OPVertex){{0.5, 0.5, 0.5},   {1, 1}};
    
    self.vertices[3] = (OPVertex){{-0.5, -0.5, 0.5}, {0, 0}};
    self.vertices[4] = (OPVertex){{0.5, 0.5, 0.5},   {1, 1}};
    self.vertices[5] = (OPVertex){{0.5, -0.5, 0.5},  {1, 0}};
    
    // 上面
    self.vertices[6] = (OPVertex){{0.5, 0.5, 0.5},    {1, 1}};
    self.vertices[7] = (OPVertex){{-0.5, 0.5, 0.5},   {0, 1}};
    self.vertices[8] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
    self.vertices[9] = (OPVertex){{-0.5, 0.5, 0.5},   {0, 1}};
    self.vertices[10] = (OPVertex){{0.5, 0.5, -0.5},  {1, 0}};
    self.vertices[11] = (OPVertex){{-0.5, 0.5, -0.5}, {0, 0}};
    
    // 下面
    self.vertices[12] = (OPVertex){{0.5, -0.5, 0.5},    {1, 1}};
    self.vertices[13] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[14] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};
    self.vertices[15] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[16] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};
    self.vertices[17] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
    
    // 左面
    self.vertices[18] = (OPVertex){{-0.5, 0.5, 0.5},    {1, 1}};
    self.vertices[19] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[20] = (OPVertex){{-0.5, 0.5, -0.5},   {1, 0}};
    self.vertices[21] = (OPVertex){{-0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[22] = (OPVertex){{-0.5, 0.5, -0.5},   {1, 0}};
    self.vertices[23] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
    
    // 右面
    self.vertices[24] = (OPVertex){{0.5, 0.5, 0.5},    {1, 1}};
    self.vertices[25] = (OPVertex){{0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[26] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
    self.vertices[27] = (OPVertex){{0.5, -0.5, 0.5},   {0, 1}};
    self.vertices[28] = (OPVertex){{0.5, 0.5, -0.5},   {1, 0}};
    self.vertices[29] = (OPVertex){{0.5, -0.5, -0.5},  {0, 0}};
    
    // 后面
    self.vertices[30] = (OPVertex){{-0.5, 0.5, -0.5},   {0, 1}};
    self.vertices[31] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
    self.vertices[32] = (OPVertex){{0.5, 0.5, -0.5},    {1, 1}};
    self.vertices[33] = (OPVertex){{-0.5, -0.5, -0.5},  {0, 0}};
    self.vertices[34] = (OPVertex){{0.5, 0.5, -0.5},    {1, 1}};
    self.vertices[35] = (OPVertex){{0.5, -0.5, -0.5},   {1, 0}};

  1. 開辟頂點緩存區(qū)

GLuint bufferID;
    glGenBuffers(1, &bufferID);
    //(2).綁定頂點緩存區(qū).(明確作用)
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    //(3).將頂點數(shù)組的數(shù)據(jù)copy到頂點緩存區(qū)中(GPU顯存中)
    glBufferData(GL_ARRAY_BUFFER, sizeof(OPVertex) * kCoordCount, self.vertices, GL_STATIC_DRAW);
    
    // 頂點坐標(biāo)數(shù)據(jù)
  glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(OPVertex) , offsetof(OPVertex, positionCoord) + NULL);   
    
    
    //紋理坐標(biāo)數(shù)據(jù)
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(OPVertex), offsetof(OPVertex, texturecoord) + NULL);

sizeof(OPVertex) * kCoordCount傳入內(nèi)容的大小
offsetof(OPVertex, positionCoord) + NULL,對應(yīng)頂點或者紋理起始點的內(nèi)存偏移值

  • 加載紋理數(shù)據(jù)


{
    //1.獲取紋理圖片路徑
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"jpg"];
    
    //2.設(shè)置紋理參數(shù)
    //紋理坐標(biāo)原點是左下角,但是圖片顯示原點應(yīng)該是左上角.
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
    
    GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    
    //3.使用蘋果GLKit 提供GLKBaseEffect 完成著色器工作(頂點/片元)
    cEffect = [[GLKBaseEffect alloc]init];
    cEffect.texture2d0.enabled = GL_TRUE;
    cEffect.texture2d0.name = textureInfo.name;
    cEffect.texture2d0.target = textureInfo.target;
    
     [self setTimer];
}

cEffect.texture2d0.target = textureInfo.target;將目標(biāo)對象交給cEffect;
[self setTimer]; 開啟一個定時器

  • 開始定時器

- (void)setTimer{
    
    NSTimer* timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
        
        [self transforms];
    }];
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}
- (void)transforms{
    angle = (angle + 10) % 360;
    //使用模型矩陣
    cEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(angle), 0.3, 1, -1.7);
   
   //重新繪制
    [glkView display];
}

  • 繪制

#pragma mark -- GLKViewDelegate

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    //1.清屏
    glClear(GL_COLOR_BUFFER_BIT);
    
    //2.準(zhǔn)備繪制
    [cEffect prepareToDraw];
    
    //3.開始繪制
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    
}

這里36繪制的定點數(shù).

效果圖:

image.png

總結(jié)

  1. OpenGL ES 相關(guān)初始化

    • 初始化上下文&設(shè)置當(dāng)前上下文
    • 獲取GLKView & 設(shè)置context
    • 配置視圖創(chuàng)建的渲染緩存區(qū)
    • 設(shè)置背景顏色
  2. 加載頂點/紋理坐標(biāo)數(shù)據(jù)

    • 設(shè)置頂點數(shù)組(頂點坐標(biāo),紋理坐標(biāo))
    • 開辟頂點緩存區(qū)
      1. 創(chuàng)建頂點緩存區(qū)標(biāo)識符ID
      2. 綁定頂點緩存區(qū).(明確作用)
      3. 將頂點數(shù)組的數(shù)據(jù)copy到頂點緩存區(qū)中(GPU顯存中)
    • 打開讀取通道.
      1. 上傳頂點數(shù)據(jù)到顯存的方法
  3. 加載紋理數(shù)據(jù)(使用GLBaseEffect)

    • 獲取紋理圖片路徑
    • 設(shè)置紋理參數(shù)
    • 使用蘋果GLKit 提供GLKBaseEffect 完成著色器工作(頂點/片元)
  4. 繪制視圖的內(nèi)容(GLKViewDelegate)

    • 清屏
    • 準(zhǔn)備繪制
    • 開始繪制

demo

GLKBaseEffect使用小結(jié):

  • 創(chuàng)建一個GLKBaseEffect奠衔。通常當(dāng)你創(chuàng)建OpenGL上下文的時候,你都會創(chuàng)建一個塘娶。對于不同的幾何圖形归斤,你可以(或者說應(yīng)該)重用相同的GLKBaseEffect,只是要重新設(shè)置其屬性刁岸。在后臺脏里,GLKBaseEffect只會向它的著色器傳播剛剛變化的屬性。
  • 設(shè)置GLKBaseEffect的屬性虹曙。這里你可以配置光迫横,轉(zhuǎn)化,和其他GLKBaseEffect的著色器用來渲染幾何圖形的屬性酝碳。
  • 調(diào)用GLKBaseEffectprepareToDraw方法矾踱。任何時候如果你改變了GLKBaseEffect的一個屬性,你都要先調(diào)用prepareToDraw方法讓著色器得到正確的配置疏哗。這也讓GLKBaseEffect的著色器作為“當(dāng)前”的著色器程序(就是讓GLKBaseEffect的著色器起作用)呛讲。
  • 使能預(yù)定義屬性。通常當(dāng)你使用自定義著色器時返奉,他們會使用稱為屬性的參數(shù)圣蝎,你要寫代碼獲得它們的ID。對于GLKBaseEffect的內(nèi)建著色器衡瓶,這些屬性已經(jīng)用常量值預(yù)先定義好了徘公,比如GLKVertexAttribPosition或者GLKVertexAttribColor。所以你要使能所有需要傳給著色器的參數(shù)哮针,并保證他們指向了數(shù)據(jù)关面。
  • 繪制你的幾何圖形坦袍。一旦你東西要配置,你都可以使用普通的OpenGL繪圖指令等太,比如glDrawArrays或者glDrawElements捂齐,它會使用你剛剛配置好的效果進行渲染!

GLKBaseEffect的好處是如果你使用它們缩抡,你根本就不需要去寫任何的著色器,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奠宜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞻想,更是在濱河造成了極大的恐慌压真,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蘑险,死亡現(xiàn)場離奇詭異滴肿,居然都是意外死亡,警方通過查閱死者的電腦和手機佃迄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門泼差,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呵俏,你說我怎么就攤上這事堆缘。” “怎么了普碎?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵套啤,是天一觀的道長。 經(jīng)常有香客問我随常,道長潜沦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任绪氛,我火速辦了婚禮唆鸡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘枣察。我一直安慰自己争占,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布序目。 她就那樣靜靜地躺著臂痕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猿涨。 梳的紋絲不亂的頭發(fā)上握童,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機與錄音叛赚,去河邊找鬼澡绩。 笑死稽揭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肥卡。 我是一名探鬼主播溪掀,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼步鉴!你這毒婦竟也來了揪胃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤氛琢,失蹤者是張志新(化名)和其女友劉穎喊递,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艺沼,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年蕴掏,在試婚紗的時候發(fā)現(xiàn)自己被綠了障般。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡盛杰,死狀恐怖挽荡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情即供,我是刑警寧澤定拟,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站逗嫡,受9級特大地震影響青自,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驱证,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一延窜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抹锄,春花似錦逆瑞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吻育,卻和暖如春念秧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背布疼。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工出爹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庄吼,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓严就,卻偏偏與公主長得像总寻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子梢为,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348