OpenGL ES 2.0 Shader相關(guān)介紹

因為近大半年都是在VR的項目,里面好多地方都用到opengl和shader之前因為沒接觸過這方面的東西,感覺走了不少彎路蜜徽,剛開始感覺這東西晦澀難懂蹋砚,一旦入門了就會好很多粉寞。

與OpenGL ES1.x渲染管線相比,OpenGL ES 2.0渲染管線中“頂點著色器”取代了OpenGL ES 1.x渲染管線中的“變換和光照”;“片元著色器”取代了OpenGL ES 1.x渲染管線中的“紋理環(huán)境和顏色求和”诈泼、“霧”以及“Alpha測試”懂拾。這使得開發(fā)人員在使用OpenGL ES 2.0API進(jìn)行開發(fā)時,可以通過編寫頂點及片元著色器程序铐达,來完成一些頂點變換和紋理顏色計算工作岖赋,實現(xiàn)更加靈活、精細(xì)化的計算與渲染瓮孙。
一唐断、著色(Shader)語言
著色語言是一種類C的編程語言,但不像C語言一樣支持雙精度浮點型(double)杭抠、字節(jié)型(byte)脸甘、短整型(short)、長整型(long)偏灿,并且取消了C中的聯(lián)合體(union)丹诀、枚舉類型(enum)、無符號數(shù)(unsigned)以及位運算等特性翁垂。著色語言中有許多內(nèi)建的原生數(shù)據(jù)類型以及構(gòu)建數(shù)據(jù)類型铆遭,如:浮點型(float)、布爾型(bool)沿猜、整型(int)枚荣、矩陣型(matrix)以及向量型(vec2、vec3等)等啼肩」髋總體來說,這些數(shù)據(jù)類型可以分為標(biāo)量疟游、向量、矩陣痕支、采樣器颁虐、結(jié)構(gòu)體以及數(shù)組等。shader支持下面數(shù)據(jù)類型:


float  bool  int    基本數(shù)據(jù)類型  
vec2                包含了2個浮點數(shù)的向量  
vec3                包含了3個浮點數(shù)的向量  
vec4                包含了4個浮點數(shù)的向量  
ivec2               包含了2個整數(shù)的向量  
ivec3               包含了3個整數(shù)的向量  
ivec4               包含了4個整數(shù)的向量  
bvec2               包含了2個布爾數(shù)的向量  
bvec3               包含了3個布爾數(shù)的向量  
bvec4               包含了4個布爾數(shù)的向量  
mat2                2*2維矩陣  
mat3                3*3維矩陣  
mat4                4*4維矩陣  
sampler1D           1D紋理采樣器  
sampler2D           2D紋理采樣器  
sampler3D           3D紋理采樣器  
  1. 頂點著色器
    1.1 頂點著色器示例代碼
uniform mat4 uMVPMatrix;                             // 應(yīng)用程序傳入頂點著色器的總變換矩陣  
attribute vec4 aPosition;                            // 應(yīng)用程序傳入頂點著色器的頂點位置  
attribute vec2 aTextureCoord;                        // 應(yīng)用程序傳入頂點著色器的頂點紋理坐標(biāo)  
attribute vec4 aColor                                // 應(yīng)用程序傳入頂點著色器的頂點顏色變量  
varying vec4 vColor                                  // 用于傳遞給片元著色器的頂點顏色數(shù)據(jù)  
varying vec2 vTextureCoord;                          // 用于傳遞給片元著色器的頂點紋理數(shù)據(jù)  
void main()  
{  
    gl_Position = uMVPMatrix * aPosition;            // 根據(jù)總變換矩陣計算此次繪制此頂點位置  
    vColor = aColor;                                 // 將頂點顏色數(shù)據(jù)傳入片元著色器  
    vTextureCoord = aTextureCoord;                   // 將接收的紋理坐標(biāo)傳遞給片元著色器  
}  

1.2 頂點著色器介紹
頂點著色器是一個可編程的處理單元卧须,執(zhí)行頂點變換另绩、紋理坐標(biāo)變換、光照花嘶、材質(zhì)等頂點的相關(guān)操作笋籽,每頂點執(zhí)行一次。替代了傳統(tǒng)渲染管線中頂點變換椭员、光照以及紋理坐標(biāo)的處理车海,開發(fā)人員可以根據(jù)自己的需求自行開發(fā),大大增加了程序的靈活性隘击。
頂點著色器主要是傳入相應(yīng)的Attribute變量侍芝、Uniforms變量研铆、采樣器以及臨時變量,經(jīng)過頂點著色器后生成Varying變量州叠。如下圖所示:

shader1.jpg

(1)attribute變量(屬性變量)只能用于頂點著色器中棵红,不能用于片元著色器。一般用該變量來表示一些頂點數(shù)據(jù)咧栗,如:頂點坐標(biāo)逆甜、紋理坐標(biāo)、顏色等致板。
(2)uniforms變量(一致變量)用來將數(shù)據(jù)值從應(yīng)用程其序傳遞到頂點著色器或者片元著色器交煞。該變量有點類似C語言中的常量(const),即該變量的值不能被shader程序修改可岂。一般用該變量表示變換矩陣错敢、光照參數(shù)、紋理采樣器等缕粹。
(3)varying變量(易變變量)是從頂點著色器傳遞到片元著色器的數(shù)據(jù)變量稚茅。頂點著色器可以使用易變變量來傳遞需要插值的顏色、法向量平斩、紋理坐標(biāo)等任意值亚享。在頂點與片元shader程序間傳遞數(shù)據(jù)是很容易的,一般在頂點shader中修改varying變量值绘面,然后片元shader中使用該值欺税,當(dāng)然,該變量在頂點及片元這兩段shader程序中聲明必須是一致的揭璃。例如:上面代碼中應(yīng)用程序中由頂點著色器傳入片元著色器中的vColor變量晚凿。
(4)gl_Position為內(nèi)建變量,表示變換后點的空間位置瘦馍。頂點著色器從應(yīng)用程序中獲得原始的頂點位置數(shù)據(jù)歼秽,這些原始的頂點數(shù)據(jù)在頂點著色器中經(jīng)過平移、旋轉(zhuǎn)情组、縮放等數(shù)學(xué)變換后燥筷,生成新的頂點位置。新的頂點位置通過在頂點著色器中寫入gl_Position傳遞到渲染管線的后繼階段繼續(xù)處理院崇。
2. 片元著色器
2.1 片元著色器示例代碼

precision mediump float;                           // 設(shè)置工作精度  
varying vec4 vColor;                               // 接收從頂點著色器過來的頂點顏色數(shù)據(jù)  
varying vec2 vTextureCoord;                        // 接收從頂點著色器過來的紋理坐標(biāo)  
uniform sampler2D sTexture;                        // 紋理采樣器肆氓,代表一幅紋理  
void main()  
{                                                                                     
    gl_FragColor = texture2D(sTexture, vTextureCoord) * vColor;// 進(jìn)行紋理采樣  
} 

此片元著色器的主要功能為根據(jù)接收的記錄片元紋理坐標(biāo)的易變變量中的紋理坐標(biāo),調(diào)用texture2D內(nèi)建函數(shù)從采樣器中進(jìn)行紋理采樣底瓣,得到此片元的顏色值谢揪。最后,將采樣到的顏色值傳給gl_FragColor內(nèi)建變量,完成片元的著色键耕。
2.2 片元著色器介紹
片元著色器是一個處理片元值及其相關(guān)聯(lián)數(shù)據(jù)的可編程單元寺滚,片元著色器可執(zhí)行紋理的訪問、顏色的匯總屈雄、霧化等操作村视,每片元執(zhí)行一次。片元著色器替代了紋理酒奶、顏色求和蚁孔、霧以及Alpha測試,這一部分是需要開發(fā)者自己開發(fā)的惋嚎。

shader2.jpg

(1)varying指的是從頂點著色器傳遞到片元著色器的數(shù)據(jù)變量
(2)gl_FragColor為內(nèi)置變量杠氢,用來保存片元著色器計算完成的片元顏色值,此顏色值將送入渲染管線的后繼階段進(jìn)行處理另伍。
二鼻百、加載著色器代碼示例

private int loadShader( int shaderType, String source)   
{  
    // 創(chuàng)建一個新shader  
    int shader = GLES20.glCreateShader(shaderType);  
    // 若創(chuàng)建成功則加載shader  
    if (shader != 0)   
    {  
        // 加載shader源代碼  
        GLES20.glShaderSource(shader, source);  
        // 編譯shader  
        GLES20.glCompileShader(shader);  
        // 存放編譯成功shader數(shù)量的數(shù)組  
        int[] compiled = new int[1];  
        // 獲取Shader的編譯情況  
        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);  
        if (compiled[0] == 0)  
        {  
            //若編譯失敗則顯示錯誤日志并刪除此shader  
            Log.e(TAG, "Could not compile shader " + shaderType + ":");  
            Log.e(TAG, GLES20.glGetShaderInfoLog(shader));  
            GLES20.glDeleteShader(shader);  
            shader = 0;  
        }  
    }  
  
    return shader;  
}  

上述示例代碼中主要用到了三個方法:

GLES20.glCreateShader(shaderType);  
GLES20.glShaderSource(shader, source);  
GLES20.glCompileShader(shader);  
   1. GLES20.glCreateShader(),創(chuàng)建一個容納shader的容器摆尝,稱為shader容器温艇。
函數(shù)原型:  
int glCreateShader (int type)  
方法參數(shù):  
GLES20.GL_VERTEX_SHADER          (頂點shader)  
GLES20.GL_FRAGMENT_SHADER        (片元shader)  

如果調(diào)用成功的話,函數(shù)將返回一個整形的正整數(shù)作為shader容器的id堕汞。如果對c++熟悉的話勺爱,該函數(shù)的返回值理解為指針或者句柄更合適。
2. GLES20.glShaderSource(shader, source)讯检,添加shader的源代碼琐鲁。源代碼應(yīng)該以字符串?dāng)?shù)組的形式表示。當(dāng)然人灼,也可以只用一個字符串來包含所有的源代碼围段。

函數(shù)原型:  
void glShaderSource (int shader, String string)  
參數(shù)含義:  
shader是代表shader容器的id(由glCreateShader返回的整形數(shù));  
string是包含源程序的字符串?dāng)?shù)組投放。  
  1. GLES20.glCompileShader(shader)奈泪,對shader容器中的源代碼進(jìn)行編譯。
函數(shù)原型:  
void glCompileShader (int shader)  
參數(shù)含義:  
shader是代表shader容器的id跪呈。  

  1. 調(diào)試
    調(diào)試一個shader是非常困難的。shader的世界里沒有printf取逾,無法在控制臺中打印調(diào)試信息耗绿,更沒有斷點,甚至很多編輯器對shader程序關(guān)鍵字砾隅、變量等連高亮顯示都不支持误阻。但是可以通過一些OpenGL提供的函數(shù)來獲取編譯和連接過程中的信息。
    在編譯階段使用glGetShaderiv獲取編譯情況,在連接階段使用glGetProgramiv獲取連接情況究反。當(dāng)錯誤產(chǎn)生的時候寻定,還可以從InfoLog中獲得更多的信息。InfoLog中存儲了關(guān)于上一個操作執(zhí)行時的相關(guān)信息精耐,比如編譯階段的警告和錯誤狼速,以及連接階段產(chǎn)生的問題。不幸的是對于錯誤信息沒有統(tǒng)一的標(biāo)準(zhǔn)卦停,所以不同的硬件或驅(qū)動程序?qū)⑻峁┎煌腻e誤信息向胡。
    4.1 編譯階段使用glGetShaderiv獲取編譯情況
函數(shù)原型:  
void glGetShaderiv (int shader, int pname, int[] params, int offset)  
參數(shù)含義:  
shader是一個shader的id;  
pname使用GL_COMPILE_STATUS惊完;  
params是返回值僵芹,如果一切正常返回GL_TRUE代,否則返回GL_FALSE小槐。  

4.2編譯階段使用glGetShaderInfoLog獲取編譯錯誤

函數(shù)原型:  
String glGetShaderInfoLog (int shader)  
參數(shù)含義:  
shader是一個頂點shader或者片元shader的id拇派。  

4.3 在連接階段使用glGetProgramiv獲取連接情況

函數(shù)原型:  
void glGetProgramiv (int program, int pname, int[] params, int offset)  
參數(shù)含義:  
program是一個著色器程序的id;  
pname是GL_LINK_STATUS凿跳;  
param是返回值件豌,如果一切正常返回GL_TRUE代,否則返回GL_FALSE拄显。

4.4 在連接階段使用glGetProgramInfoLog獲取連接錯誤

函數(shù)原型:  
String glGetProgramInfoLog (int program)  
參數(shù)含義:  
program是一個著色器程序的id苟径。  

4.5 清理shader的glDeleteShader方法
當(dāng)不再需要某個shader或某個程序的時候,需要對其進(jìn)行清理躬审,以釋放資源棘街。前面,提到過如何向一個程序中添加一個shader承边。這里可調(diào)用下面的函數(shù)來將一個shader從一個程序中清除掉遭殉。

函數(shù)原型:  
void glDeleteShader (int shader);  
參數(shù)含義:  
shader是要被排除的頂點shader或者片元shader的id博助。  

如果险污,一個shader被刪除之前沒有從相應(yīng)的程序中排除,那么這個shader不會被實際刪除富岳,而只是被標(biāo)記為被刪除蛔糯;當(dāng)shader被從程序中排除的時候,才會被真正地刪除窖式。
   三蚁飒、創(chuàng)建著色器程序代碼示例
private int createProgram(String vertexSource, String fragmentSource)   
{  
    // 加載頂點著色器  
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);  
    if (vertexShader == 0)   
    {  
        return 0;  
    }  
      
    // 加載片元著色器  
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);  
    if (pixelShader == 0)   
    {  
        return 0;  
    }  
  
    // 創(chuàng)建著色器程序  
    int program = GLES20.glCreateProgram();  
    // 若程序創(chuàng)建成功則向程序中加入頂點著色器與片元著色器  
    if (program != 0)   
    {  
        // 向程序中加入頂點著色器  
        GLES20.glAttachShader(program, vertexShader);  
        // 向程序中加入片元著色器  
        GLES20.glAttachShader(program, pixelShader);  
        // 鏈接程序  
        GLES20.glLinkProgram(program);  
        // 存放鏈接成功program數(shù)量的數(shù)組  
        int[] linkStatus = new int[1];  
        // 獲取program的鏈接情況  
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);  
        // 若鏈接失敗則報錯并刪除程序  
        if (linkStatus[0] != GLES20.GL_TRUE)   
        {  
            Log.e(TAG, "Could not link program: ");  
            Log.e(TAG, GLES20.glGetProgramInfoLog(program));  
            GLES20.glDeleteProgram(program);  
            program = 0;  
        }  
    }  
  
    // 釋放shader資源  
    GLES20.glDeleteShader(vertexShader );  
    GLES20.glDeleteShader(pixelShader);  
  
    return program;  
}  
  1. glCreateProgram,在連接shader之前萝喘,首先要創(chuàng)建一個容納程序的容器淮逻,稱為著色器程序容器琼懊。可以通過glCreateProgram函數(shù)來創(chuàng)建一個程序容器爬早。
函數(shù)原型:  
int glCreateProgram ()  
如果函數(shù)調(diào)用成功將返回一個正整數(shù)作為該著色器程序的id哼丈。 
  1. glAttachShader,接下來筛严,我們要將shader容器添加到程序中醉旦。這時的shader容器不一定需要被編譯,他們甚至不需要包含任何的代碼脑漫。我們要做的只是將shader容器添加到程序中髓抑。使用glAttachShader函數(shù)來為程序添加shader容器。
函數(shù)原型:  
void glAttachShader (int program, int shader)  
參數(shù)含義:  
program是著色器程序容器的id优幸;  
shader是要添加的頂點或者片元shader容器的id吨拍。  

如果你同時擁有了,頂點shader和片元shader网杆,需要分別將他們各自的兩個shader容器添加的程序容器中羹饰。
3. glLinkProgram,鏈接程序碳却。

函數(shù)原型:  
void glLinkProgram (int program)  
參數(shù)含義:  
program是著色器程序容器的id队秩。

在鏈接操作執(zhí)行以后,可以任意修改shader的源代碼昼浦,對shader重新編譯不會影響整個程序馍资,除非重新鏈接程序。
4. glUseProgram关噪,加載并使用鏈接好的程序鸟蟹。

函數(shù)原型:  
void glUseProgram (int program)  
參數(shù)含義:  
program是要使用的著色器程序的id。  

如果將program設(shè)置為0使兔,表示使用固定功能管線建钥。如果程序已經(jīng)在使用的時候,對程序進(jìn)行重新編譯虐沥,編譯后的應(yīng)用程序會自動替代以前的那個被調(diào)用熊经,這時你不需要再次調(diào)用這個函數(shù)。
四欲险、 向著色器程序中傳遞數(shù)據(jù)
1. 獲取著色器程序內(nèi)成員變量的id镐依,也可以理解為句柄、指針天试。
glGetAttribLocation方法:獲取著色器程序中槐壳,指定為attribute類型變量的id。
glGetUniformLocation方法:獲取著色器程序中秋秤,指定為uniform類型變量的id宏粤。
如:
// 獲取指向著色器中aPosition的index
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
// 獲取指向著色器中uMVPMatrix的index
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
2. 傳遞數(shù)據(jù)
使用上一節(jié)獲取的指向著色器相應(yīng)數(shù)據(jù)成員的各個id,就能將我們自己定義的頂點數(shù)據(jù)灼卢、顏色數(shù)據(jù)等等各種數(shù)據(jù)傳遞到著色器當(dāng)中了绍哎。

// 使用shader程序  
GLES20.glUseProgram(mProgram);  
// 將最終變換矩陣傳入shader程序  
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);  
// 設(shè)置緩沖區(qū)起始位置  
mRectBuffer.position(0);  
// 頂點位置數(shù)據(jù)傳入著色器  
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 20, mRectBuffer);  
// 頂點顏色數(shù)據(jù)傳入著色器中  
GLES20.glVertexAttribPointer(maColorHandle, 4, GLES20.GL_FLOAT, false, 4*4, mColorBuffer);  
// 頂點坐標(biāo)傳遞到頂點著色器  
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 20, mRectBuffer);  
// 允許使用頂點坐標(biāo)數(shù)組  
GLES20.glEnableVertexAttribArray(maPositionHandle);  
// 允許使用頂點顏色數(shù)組  
GLES20.glDisableVertexAttribArray(maColorHandle);  
// 允許使用定點紋理數(shù)組  
GLES20.glEnableVertexAttribArray(maTextureHandle);   
// 綁定紋理  
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);  
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);  
// 圖形繪制  
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4); 

2.1 glVertexAttribPointer,定義頂點屬性數(shù)組鞋真。

函數(shù)原型:  
void glVertexAttribPointer (int index, int size, int type, boolean normalized, int stride, Buffer ptr )  
參數(shù)含義:  
    index  指定要修改的頂點著色器中頂點變量id崇堰;  
    size   指定每個頂點屬性的組件數(shù)量。必須為1涩咖、2海诲、3或者4。如position是由3個(x,y,z)組成檩互,而顏色是4個(r,g,b,a))特幔;  
    type   指定數(shù)組中每個組件的數(shù)據(jù)類型≌⒆颍可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT蚯斯,初始值為GL_FLOAT;  
    normalized  指定當(dāng)被訪問時饵较,固定點數(shù)據(jù)值是否應(yīng)該被歸一化(GL_TRUE)或者直接轉(zhuǎn)換為固定點值(GL_FALSE)拍嵌;  
    stride      指定連續(xù)頂點屬性之間的偏移量。如果為0循诉,那么頂點屬性會被理解為:它們是緊密排列在一起的横辆。初始值為0。如果normalized被設(shè)置為GL_TRUE茄猫,意味著整數(shù)型的值會被映射至區(qū)間[-1,1](有符號整數(shù))狈蚤,或者區(qū)間[0,1](無符號整數(shù)),反之募疮,這些值會被直接轉(zhuǎn)換為浮點值而不進(jìn)行歸一化處理炫惩;  
    ptr  頂點的緩沖數(shù)據(jù)。  

2.2 啟用或者禁用頂點屬性數(shù)組阿浓。調(diào)用glEnableVertexAttribArray和glDisableVertexAttribArray傳入?yún)?shù)index他嚷。如果啟用,那么當(dāng)glDrawArrays或者glDrawElements被調(diào)用時芭毙,頂點屬性數(shù)組會被使用筋蓖。
2.3 glActiveTexture,選擇活動紋理單元退敦。

函數(shù)原型:  
void glActiveTexture (int texture)  
參數(shù)含義:  
texture指定哪一個紋理單元被置為活動狀態(tài)粘咖。texture必須是GL_TEXTUREi之一,其中0 <= i < GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS侈百,初始值為GL_TEXTURE0瓮下。  

glActiveTexture()確定了后續(xù)的紋理狀態(tài)改變影響哪個紋理翰铡,紋理單元的數(shù)量是依據(jù)該紋理單元所被支持的具體實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讽坏,一起剝皮案震驚了整個濱河市锭魔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌路呜,老刑警劉巖迷捧,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異胀葱,居然都是意外死亡漠秋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門抵屿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來庆锦,“玉大人,你說我怎么就攤上這事轧葛》世螅” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵朝群,是天一觀的道長燕耿。 經(jīng)常有香客問我,道長姜胖,這世上最難降的妖魔是什么誉帅? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮右莱,結(jié)果婚禮上蚜锨,老公的妹妹穿的比我還像新娘。我一直安慰自己慢蜓,他們只是感情好亚再,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晨抡,像睡著了一般氛悬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耘柱,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天如捅,我揣著相機(jī)與錄音,去河邊找鬼调煎。 笑死镜遣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的士袄。 我是一名探鬼主播悲关,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谎僻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寓辱?” 一聲冷哼從身側(cè)響起戈稿,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讶舰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體需了,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡跳昼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肋乍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹅颊。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖墓造,靈堂內(nèi)的尸體忽然破棺而出堪伍,到底是詐尸還是另有隱情,我是刑警寧澤觅闽,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布帝雇,位于F島的核電站,受9級特大地震影響蛉拙,放射性物質(zhì)發(fā)生泄漏尸闸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一孕锄、第九天 我趴在偏房一處隱蔽的房頂上張望吮廉。 院中可真熱鬧,春花似錦畸肆、人聲如沸宦芦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽调卑。三九已至,卻和暖如春大咱,著一層夾襖步出監(jiān)牢的瞬間令野,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工徽级, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留气破,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓餐抢,卻偏偏與公主長得像现使,于是被迫代替她去往敵國和親低匙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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