Android OpenGL ES(一)開發(fā)入門

早就聽過大名鼎鼎的 OpenGL神僵,卻遲遲沒有實(shí)踐學(xué)習(xí)蒸苇,有些慚愧明未。今天開始通過實(shí)踐+博文方式學(xué)習(xí)掌握 OpenGL钧唐。此文對(duì)于 OpenGL 的學(xué)習(xí)分為以下部分:

  • OpenGL 基礎(chǔ)概念
  • OpenGL 坐標(biāo)系理解
  • OpenGL 渲染管線
  • OpenGL 著色語言

OpenGL 基礎(chǔ)概念

OpenGL

OpenGL 即 Open Graphics Library,是一個(gè)功能強(qiáng)大寞酿、調(diào)用方便的底層圖形庫椿争,它定義了跨編程語言、跨平臺(tái)的專業(yè)圖形程序接口熟嫩,可用于二維或三維圖像的處理與渲染。

OpenGL 是跨平臺(tái)的褐捻,除了它純粹專注的渲染外掸茅,其他內(nèi)容在每個(gè)平臺(tái)上都要有它的具體實(shí)現(xiàn),比如上下文環(huán)境和窗口的管理就交由各個(gè)設(shè)備自己來完成柠逞。

OpenGL ES

OpenGL ES (OpenGL for Embedded Systems)是三維圖形 API OpenGL 的子集昧狮,針對(duì)手機(jī)、PDA 和游戲主機(jī)等嵌入式設(shè)備而設(shè)計(jì)板壮。

Android 對(duì)應(yīng) OpenGL ES 的版本支持如下:

  • Android 1.0 開始支持 OpenGL ES 1.0 及 1.1
  • Android 2.2 開始支持 OpenGL ES 2.0
  • Android 4.3 開始支持 OpenGL ES 3.0
  • Android 5.0 開始支持 OpenGL ES 3.1

其中 OpenGL ES 1.0 是以 OpenGL 1.3 規(guī)范為基礎(chǔ)的逗鸣,OpenGL ES 1.1 是以 OpenGL 1.5 規(guī)范為基礎(chǔ)的,而 OpenGL ES 2.0 基于 OpenGL 2.0 實(shí)現(xiàn)绰精。2.x 版本相比 1.x 版本有較大差異撒璧,1.x 版本為 fixed function pipeline,即固定管線硬件笨使,而 2.x 版本為 programmable pipeline卿樱,可編程管線硬件。

固定管線中原本由系統(tǒng)做的一部分工作硫椰,在可編程管線中必須需要自己寫程序?qū)崿F(xiàn)繁调,具體程序?yàn)?vertex shader(頂點(diǎn)著色器)和 fragment shader(片元著色器)萨蚕。

OpenGL 上下文

OpenGL 是一個(gè)僅僅關(guān)注圖像渲染的圖像接口庫,在渲染過程中它需要將頂點(diǎn)信息蹄胰、紋理信息岳遥、編譯好的著色器等渲染狀態(tài)信息存儲(chǔ)起來,而存儲(chǔ)這些信息的數(shù)據(jù)結(jié)構(gòu)就可以看作 OpenGL 的上下文裕寨。

調(diào)用任何 OpenGL 函數(shù)前浩蓉,必須已經(jīng)創(chuàng)建了 OpenGL Context,GL Context 存儲(chǔ)了OpenGL 的狀態(tài)變量以及其他渲染有關(guān)的信息帮坚。OpenGL 是個(gè)狀態(tài)機(jī)妻往,有很多狀態(tài)變量,是個(gè)標(biāo)準(zhǔn)的過程式操作過程试和,改變狀態(tài)會(huì)影響后續(xù)所有操作讯泣,這和面向?qū)ο蟮慕怦钤瓌t不符,畢竟渲染本身就是個(gè)復(fù)雜的過程阅悍。OpenGL 采用 Client-Server 模型來解釋 OpenGL 程序好渠,即 Server 存儲(chǔ) GL Context(可能不止一個(gè)),Client 提出渲染請(qǐng)求节视,Server 給予響應(yīng)拳锚,一般 Server 和 Client 都在我們的 PC 上,但 Server 和 Client 也可以是通過網(wǎng)絡(luò)連接寻行。

之后的渲染工作就要依賴這些渲染狀態(tài)信息來完成霍掺,當(dāng)一個(gè)上下文被銷毀時(shí),它所對(duì)應(yīng)的 OpenGL 渲染工作也將結(jié)束拌蜘。

EGL

在 OpenGL 的設(shè)計(jì)中杆烁,OpenGL 是不負(fù)責(zé)管理窗口的,窗口的管理交由各個(gè)設(shè)備自己來完成简卧,具體來講兔魂,IOS 平臺(tái)上使用 EAGL 提供本地平臺(tái)對(duì) OpenGL 的實(shí)現(xiàn),在 Android 平臺(tái)上使用 EGL 提供本地平臺(tái)對(duì) OpenGL 的實(shí)現(xiàn)举娩。EGL 是 OpenGL ES 和 Android 底層平臺(tái)視窗系統(tǒng)之間的接口析校,在 OpenGL 的輸出與設(shè)備屏幕之間架接起一個(gè)橋梁,承擔(dān)了為 OpenGL 提供上下文環(huán)境以及管理窗口的職責(zé)铜涉。

EGL 為雙緩沖工作模式智玻,即有一個(gè) Back Frame Buffer 和一個(gè) Front Frame Buffer,正常繪制的目標(biāo)都是 Back Frame Buffer骄噪,繪制完成后再調(diào)用 eglSwapBuffer API尚困,將繪制完畢的 FrameBuffer 交換到 Front Frame Buffer 并顯示出來。

從代碼層面來看链蕊,OpenGL ES 的 opengles 包下定義了平臺(tái)無關(guān)的繪圖指令事甜,EGL(javax.microedition.khronos.egl)
則定義了控制 displays谬泌,contexts 以及 surfaces 的統(tǒng)一的平臺(tái)接口。

  • Display(EGLDisplay) 是對(duì)實(shí)際顯示設(shè)備的抽象
  • Surface(EGLSurface)是對(duì)用來存儲(chǔ)圖像的內(nèi)存區(qū)域 FrameBuffer 的抽象逻谦,包括 Color Buffer掌实、Stencil Buffer、Depth Buffer
  • Context(EGLContext)存儲(chǔ) OpenGL ES 繪圖的一些狀態(tài)信息
image

使用 EGL 繪圖的一般步驟:

獲取 EGLDisplay 對(duì)象
初始化與 EGLDisplay 之間的連接
獲取 EGLConfig 對(duì)象
創(chuàng)建 EGLContext 實(shí)例
創(chuàng)建 EGLSurface 實(shí)例
連接 EGLContext 和 EGLSurface
使用 GL 指令繪制圖形
斷開并釋放與 EGLSurface 關(guān)聯(lián)的 EGLContext 對(duì)象
刪除 EGLSurface 對(duì)象
刪除 EGLContext 對(duì)象
終止與 EGLDisplay 之間的連接

一般來說在 Android 平臺(tái)上開發(fā) OpenGL ES 應(yīng)用邦马,無需按照上述步驟來繪制圖形贱鼻,可以直接使用 GLSurfaceView 控件,該控件提供了對(duì) Display滋将、Surface 以及 Context 的管理邻悬,大大簡化了開發(fā)流程。

OpenGL 紋理

紋理(Texture)是一個(gè) 2D 圖片(甚至也有 1D 和 3D 的紋理)随闽,它可以用來添加物體的細(xì)節(jié)父丰;你可以想象紋理是一張繪有磚塊的紙,無縫折疊貼合到你的 3D 的房子上掘宪,這樣你的房子看起來就像有磚墻外表了蛾扇。因?yàn)槲覀兛梢栽谝粡垐D片上插入非常多的細(xì)節(jié),這樣就可以讓物體非常精細(xì)而不用指定額外的頂點(diǎn)魏滚。

OpenGL 坐標(biāo)系理解

OpenGL 要求輸入的頂點(diǎn)坐標(biāo)都是標(biāo)準(zhǔn)化設(shè)備坐標(biāo)镀首,即每個(gè)頂點(diǎn)的 x、y鼠次、z 都在 -1 到 1 之間更哄,由標(biāo)準(zhǔn)化設(shè)備坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)的過程中會(huì)經(jīng)歷變換多個(gè)坐標(biāo)系統(tǒng),在這些特定的坐標(biāo)系中腥寇,一些操作和計(jì)算可以更加方便竖瘾。

image
  • 1. 局部坐標(biāo)
    頂點(diǎn)坐標(biāo)起始于局部空間(Local Space),在這里稱為局部坐標(biāo)花颗,是以物體某一點(diǎn)為原點(diǎn)而建立的,該坐標(biāo)系僅對(duì)該物體適用惠拭,用來簡化對(duì)物體各部分坐標(biāo)的描述扩劝。物體放到場景中時(shí),各部分經(jīng)歷的坐標(biāo)變換相同职辅,相對(duì)位置不變棒呛。
  • 2. 世界坐標(biāo)
    局部坐標(biāo)通過模型矩陣進(jìn)行位移、縮放域携、旋轉(zhuǎn)簇秒,將物體從局部變換到世界空間,并和其他物體一起相對(duì)于世界的原點(diǎn)擺放秀鞭。
  • 3. 觀察坐標(biāo)
    將世界空間坐標(biāo)轉(zhuǎn)化為用戶視野前方的坐標(biāo)趋观,通常是由一系列的位移和旋轉(zhuǎn)的組合(觀察矩陣)來完成扛禽。
  • 4. 裁剪坐標(biāo)
    坐標(biāo)到達(dá)觀察空間之后,通過投影矩陣會(huì)將指定范圍內(nèi)的坐標(biāo)變換為標(biāo)準(zhǔn)化設(shè)備坐標(biāo)的范圍(-1.0, 1.0)皱坛,所有在范圍外的坐標(biāo)會(huì)被裁剪掉编曼。
  • 5. 屏幕坐標(biāo)
    將裁剪坐標(biāo)位于(-1.0, 1.0)范圍的坐標(biāo)變換到由 glViewport 函數(shù)所定義的坐標(biāo)范圍內(nèi),最后變換出來的坐標(biāo)將會(huì)送到光柵器剩辟,將其轉(zhuǎn)化為片段掐场。

OpenGL 渲染管線

OpenGL 渲染管線流程為:頂點(diǎn)數(shù)據(jù) -> 頂點(diǎn)著色器 -> 圖元裝配 -> 幾何著色器 -> 光柵化 -> 片段著色器 -> 逐片段處理 -> 幀緩沖

image

OpenGL 渲染管線的流程其實(shí)就是 OpenGL 引擎渲染圖像的流程,也就是說 OpenGL 引擎一步一步的將圖片渲染到屏幕上的過程贩猎,渲染管線可以分為以下幾個(gè)階段:

  • 1. 指定幾何對(duì)象
    首先要了解幾何圖元的概念熊户,幾何圖元就是點(diǎn)、直線吭服、三角線等幾何對(duì)象嚷堡,在提供了頂點(diǎn)坐標(biāo)后,還要確定具體要畫的是點(diǎn)噪馏、線段還是三角形麦到,這就要確定具體執(zhí)行的繪制指令。比如 OpenGL 提供給開發(fā)者的繪制方法 glDrawArrays欠肾,這個(gè)方法的第一個(gè)參數(shù)就是指定繪制方式瓶颠,可選值有:
    GL_POINTS:以點(diǎn)的形式進(jìn)行繪制,通常用在繪制粒子效果的場景刺桃。
    GL_LINES:以線的形式進(jìn)行繪制粹淋,通常用于繪制直線的場景。
    GL_TRIANGLE_STRIP:以三角形的形式進(jìn)行繪制瑟慈,所有二維圖像的渲染都會(huì)使用這種方式桃移。
    具體選用哪一種繪制方式?jīng)Q定了 OpenGL 渲染管線的第一階段應(yīng)如何去繪制幾何圖元,這就是第一階段指定幾何對(duì)象葛碧。

  • 2. 頂點(diǎn)處理
    不論上面的幾何圖元是如何指定的借杰,所有的幾何數(shù)據(jù)都將會(huì)通過這個(gè)階段。這個(gè)階段的操作內(nèi)容有:根據(jù)模型視圖(即根據(jù)幾何圖元?jiǎng)?chuàng)建的物體)和投影矩陣進(jìn)行變換來改變頂點(diǎn)的位置进泼,根據(jù)紋理坐標(biāo)與紋理矩陣來改變紋理坐標(biāo)的位置蔗衡,如果設(shè)計(jì)三維的渲染,還要處理光照計(jì)算和法線變換乳绕。
    關(guān)鍵的操作就是頂點(diǎn)坐標(biāo)變換及光照處理绞惦,每個(gè)頂點(diǎn)是分別單獨(dú)處理的。這個(gè)階段所接受的數(shù)據(jù)是每個(gè)頂點(diǎn)的屬性特征洋措,輸出的則是變換后的頂點(diǎn)數(shù)據(jù)济蝉。

  • 3. 圖元組裝
    在頂點(diǎn)處理之后,頂點(diǎn)的全部屬性都已經(jīng)被確定。在這個(gè)階段頂點(diǎn)將會(huì)根據(jù)應(yīng)用程序設(shè)定的圖元規(guī)則如 GL_POINTS 王滤、GL_TRIANGLES(三角形) 等被組裝成圖元贺嫂。

  • 4. 珊格化操作
    在圖元組裝后會(huì)傳遞過來圖元數(shù)據(jù),到目前為止淑仆,這些圖元信息還只是頂點(diǎn)而已:頂點(diǎn)處都還沒有“像素點(diǎn)”涝婉、直線段端點(diǎn)之間是空的、多邊形的邊和內(nèi)部也是空的蔗怠,光柵化的任務(wù)就是構(gòu)造這些墩弯。
    這個(gè)階段會(huì)將圖元數(shù)據(jù)分解成更小的單元并對(duì)應(yīng)于幀緩沖區(qū)的各個(gè)像素,這些單元稱為片元寞射,一個(gè)片元可能包含窗口顏色渔工、紋理坐標(biāo)等屬性。片元的屬性則是圖元上的頂點(diǎn)數(shù)據(jù)等經(jīng)過插值而確定的桥温,這就是珊格化操作引矩,也就是確定好每一個(gè)片元是什么。

  • 5. 片元處理
    珊格化操作構(gòu)造了像素點(diǎn)侵浸,這個(gè)階段就是處理這些像素點(diǎn)旺韭,根據(jù)自己的業(yè)務(wù)處理(比如提亮、飽和度調(diào)節(jié)掏觉、對(duì)比度調(diào)節(jié)区端、高斯模糊等)來變換這個(gè)片元的顏色。

  • 6. 逐片段處理
    進(jìn)行剪切澳腹、Alpha 測試织盼、 模版測試、深度測試酱塔、混合等處理沥邻,這些操作將會(huì)最后影響其在幀緩沖區(qū)的顏色值。

  • 7. 幀緩沖操作
    此階段主要執(zhí)行幀緩沖的寫入操作羊娃,也是渲染管線的最后一步唐全,負(fù)責(zé)將最終的像素點(diǎn)寫到幀緩沖區(qū)。

上面提到 OpenGL ES 2.0 版本相比之前版本蕊玷,提供了可編程的著色器來代替 1.x 版本渲染管線的某些階段芦瘾,具體為:

  • Vertex Shader(頂點(diǎn)著色器)用于替換頂點(diǎn)處理階段
  • Fragment Shader(片元著色器)用于替換片元處理階段

OpenGL 著色語言

OpenGL 著色語言 GLSL 全稱為 OpenGL Shading Language,是為了實(shí)現(xiàn)著色器的功能而向開發(fā)人員提供的一種開發(fā)語言集畅,語法與 C 語言類似,下面分為以下幾點(diǎn)來學(xué)習(xí) GLSL:

  • 1. 基本數(shù)據(jù)類型

void:空類型缅糟,即不返回任何值
bool:布爾類型挺智,true/false
int:帶符號(hào)的整數(shù),signed integer
float:帶符號(hào)的浮點(diǎn)數(shù),signed scalar
vec2赦颇、vec3二鳄、vec4:n-維浮點(diǎn)數(shù)向量
bvec2、bvec3媒怯、bvec4:n-維布爾向量
ivec2订讼、ivec3、ivec4:n-維整數(shù)向量
mat2扇苞、mat3欺殿、mat4:2x2、3x3鳖敷、4x4 浮點(diǎn)數(shù)矩陣
sampler2D:2D 紋理
samplerCube:盒紋理

其中 float 可指定精度:

high:32bit脖苏,一般用于頂點(diǎn)坐標(biāo)(vertex Coordinate)
medium:16bit,一般用于紋理坐標(biāo)(texture Coordinate)

low:8bit定踱,一般用于顏色表示(color)

  • 2. 變量修飾符

none:(默認(rèn)的可省略)本地變量棍潘,可讀可寫,函數(shù)的輸入?yún)?shù)既是這種類型
const:聲明變量或函數(shù)的參數(shù)為只讀類型
attribute:用于保存頂點(diǎn)或法線數(shù)據(jù),它可以在數(shù)據(jù)緩沖區(qū)中讀取數(shù)據(jù)崖媚,僅能用于頂點(diǎn)著色器
uniform:在運(yùn)行時(shí) shader 無法改變 uniform 變量亦歉,一般用來放置程序傳遞給 shader 的變換矩陣,材質(zhì)畅哑,光照參數(shù)等等肴楷,可用于頂點(diǎn)著色器和片元著色器
varying:用于修飾從頂點(diǎn)著色器向片元著色器傳遞的變量

要注意全局變量限制符只能為 const、attribute敢课、uniform 和 varying 中的某一個(gè)阶祭,不可復(fù)合。

  • 3. 內(nèi)置變量

GLSL 程序使用一些特殊的內(nèi)置變量與硬件進(jìn)行溝通直秆,他們大致分成兩種濒募,一種是 input 類型,他負(fù)責(zé)向硬件(渲染管線)發(fā)送數(shù)據(jù);另一種是 output 類型圾结,負(fù)責(zé)向程序回傳數(shù)據(jù)瑰剃,以便編程時(shí)需要。
頂點(diǎn)著色器中 output 類型的內(nèi)置變量如下:

highp vec4 gl_Position:放置頂點(diǎn)坐標(biāo)信息
mediump float gl_PointSize:需要繪制點(diǎn)的大小,(只在gl.POINTS模式下有效)

片元著色器中 input 類型的內(nèi)置變量如下:

mediump vec4 gl_FragCoord;:片元在 framebuffer 畫面的相對(duì)位置
bool gl_FrontFacing:標(biāo)志當(dāng)前圖元是不是正面圖元的一部分
mediump vec2 gl_PointCoord:經(jīng)過插值計(jì)算后的紋理坐標(biāo),點(diǎn)的范圍是0.0到1.0

片元著色器中 output 類型的內(nèi)置變量如下:

mediump vec4 gl_FragColor:設(shè)置當(dāng)前片點(diǎn)的顏色
mediump vec4 gl_FragData[n]:設(shè)置當(dāng)前片點(diǎn)的顏色,使用glDrawBuffers數(shù)據(jù)數(shù)組

  • 4. 內(nèi)置常量

GLSL 提供了一些內(nèi)置的常量筝野,用來說明當(dāng)前系統(tǒng)的一些特性晌姚。有時(shí)我們需要針對(duì)這些特性,對(duì) shader 程序進(jìn)行優(yōu)化歇竟,讓程序兼容度更好挥唠。

頂點(diǎn)著色器中的內(nèi)置常量如下:

const mediump int gl_MaxVertexAttribs >= 8:頂點(diǎn)著色器中可用的最大 attributes 數(shù)
const mediump int gl_MaxVertexUniformVectors >= 128:頂點(diǎn)著色器中可用的最大 uniform vectors 數(shù)
const mediump int gl_MaxVaryingVectors >= 8:頂點(diǎn)著色器中可用的最大 varying vectors 數(shù)
const mediump int gl_MaxVertexTextureImageUnits >= 0:頂點(diǎn)著色器中可用的最大紋理單元數(shù)
const mediump int gl_MaxCombinedTextureImageUnits >= 8:表示最多支持多少個(gè)紋理單元

片元著色器中的內(nèi)置常量如下:

const mediump int gl_MaxTextureImageUnits >= 8:片元著色器中能訪問的最大紋理單元數(shù)
const mediump int gl_MaxFragmentUniformVectors >= 16:片元著色器中可用的最大 uniform vectors 數(shù)
const mediump int gl_MaxDrawBuffers = 1:表示可用的 drawBuffers 數(shù),在 OpenGL ES 2.0 中這個(gè)值為 1, 在將來的版本可能會(huì)有所變化

上面這些值的大小取決于 OpenGL ES 在某設(shè)備上的具體實(shí)現(xiàn)。

  • 5. 內(nèi)置函數(shù)

通用函數(shù):abs焕议、floor宝磨、min、max 等,參數(shù)可傳入 float/vec2/vec3/vec4 類型
角度函數(shù):sin唤锉、cos 等世囊,參數(shù)可傳入 float/vec2/vec3/vec4 類型
指數(shù)函數(shù):pow、log 等窿祥,參數(shù)可傳入 float/vec2/vec3/vec4 類型
幾何函數(shù):distance株憾、dot 等,參數(shù)可傳入 float/vec2/vec3/vec4 類型
矩陣函數(shù):matrixCompMult晒衩,參數(shù)傳入 mat 類型
向量函數(shù):lessThan嗤瞎、equal 等,參數(shù)可傳入 vec2/vec3/vec4 類型
紋理函數(shù):texture2D浸遗、texture2DProj 等

更詳細(xì)的內(nèi)置函數(shù)介紹可去官方文檔查看猫胁,在此只簡單列一下大致種類。

參考文章:

《音視頻開發(fā)進(jìn)階指南 - 基于Android與IOS平臺(tái)的實(shí)踐》
OpenGL 百度百科
OpenGL Context(渲染上下文)
OpenGL ES 百度百科
在Android中使用OpenGL ES進(jìn)行開發(fā)第(一)節(jié):概念先行
Android OpenGL ES(四):關(guān)于EGL
初學(xué)OpenGL(4):紋理
OpenGL各坐標(biāo)系及模型矩陣跛锌、投影矩陣等的深入理解
OpenGL管線(用經(jīng)典管線代說著色器內(nèi)部)
OpenGL shader GLSL 中文手冊(cè)
坐標(biāo)系統(tǒng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弃秆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子髓帽,更是在濱河造成了極大的恐慌菠赚,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郑藏,死亡現(xiàn)場離奇詭異衡查,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)必盖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門拌牲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人歌粥,你說我怎么就攤上這事塌忽。” “怎么了失驶?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵土居,是天一觀的道長。 經(jīng)常有香客問我嬉探,道長擦耀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任涩堤,我火速辦了婚禮眷蜓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胎围。我一直安慰自己吁系,他們只是感情好芹敌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垮抗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碧聪。 梳的紋絲不亂的頭發(fā)上冒版,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音逞姿,去河邊找鬼辞嗡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛滞造,可吹牛的內(nèi)容都是我干的续室。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谒养,長吁一口氣:“原來是場噩夢啊……” “哼挺狰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起买窟,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤丰泊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后始绍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞳购,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年亏推,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了学赛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吞杭,死狀恐怖盏浇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情篇亭,我是刑警寧澤缠捌,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站译蒂,受9級(jí)特大地震影響曼月,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柔昼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一哑芹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捕透,春花似錦聪姿、人聲如沸碴萧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽破喻。三九已至,卻和暖如春盟榴,著一層夾襖步出監(jiān)牢的瞬間曹质,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工擎场, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羽德,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓迅办,卻偏偏與公主長得像宅静,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子站欺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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