From 908c47579dbe2f44df550971372e8581f34033c3 Mon Sep 17 00:00:00 2001 From: cbaakman Date: Fri, 21 Aug 2015 21:12:58 +0200 Subject: [PATCH 1/4] simpler water code This rendering code for the water is actually simpler to read. It also leaves room for extra objects to be rendered in the reflection. --- bin/test3d.zip | Bin 2923099 -> 2923104 bytes src/test3d/water.cpp | 207 ++++++++++++++++++++++++------------------- src/test3d/water.h | 5 +- 3 files changed, 119 insertions(+), 93 deletions(-) diff --git a/bin/test3d.zip b/bin/test3d.zip index 6ccebb2435a11850bfe025e27c1b36e2e31a16ba..1afd28dbe2aaa565aa02818e1d0695b4a887418a 100644 GIT binary patch delta 901 zcmcb;WfS8AAZ}=3Y+-6)ZeeL*ZDDI+Z{cX+Y~gC*ZsBR+ZQ*O-ZxLt_Y!PY^ZV_n_ zZ4qk`Z;@z`Y>{e_Zjot`ZINq{Z&7GbY*A`aZc%Ab-J-VCUbwkb)P0*l@smI%28LT~ z3=Dz{GSeMq=!n#FGBAtDUJnJ~(h6<{MwS=M3=CjmZHRaNZ37;=+xwf`t-bHsR7Ezw z+myIH_rQhQ1`?}$)tOQ>Cr^ET;lG_%kx+KoWziY@br)3j_se_cs;r-~Zeilrs0H(C znVNscB&%*Pcq~yB{yTc}>ixMTagT1Ti97jlu2|uo)L-=no(gS?IO8a!swNiuSoX~f z$GO~h7M-}h>S3F>VkhHXd)AX^C=i~c@PnuJnI(elke2jQ3aBGnZi(PYASAOW#1(8Pt*J~VU zt5-04|I$l0P0{0T{e|mA5!tIkr6RcUx@LrSXenmfq~zC@ao1Pk?3m2@};Njrkc5X0F}G z7~1%_@V>89N==5j`b__hfJ@nbd+XOe*qr7a?o_rUm0Q<(yUDu>j#&a1-Yjn6trGUC zHo7zSiT0F$Sqg3JnH4Qeylhg2eT&~|?B#jL_wk?}J5$d(liI?#J@21wd17dX`)&OEnAl3q6?d^U}IwwQb@ zPfwh#BQw2hhK?Mg`ShtXbix?_PJc5)$A@v}bjz7QN_TqOOdV6kr0IKR>X{e_Zjot`ZINq{Z&7GbY*A`aZc%Ab-J-VCzW(_xVfU#&7M}89Vqmz! z#=s!RAj43ck(iQNRIFc~Sdv<#msXq+8p6rIoV@NzC$IlFq$4i(%ZnY{eQLSDB@qoAb~th|qnJRjQ^K5^VsHlf~2(!=Ju!IEt{f)o80 zXdnH)EAQfy!Xw#D5kHt${`3gXvh;Sm%3r&-t#w(<(#Dw&md#0)c2`m4x*Ib|c>a>} z`c<9EBDz)i;nSlGir093FM9l0qUF-sBK||V`;L8(butn@YX1G}RLQgEA`8UtrPe8Z zl+e1J!>JH(?u^VNy9s9&*XO)>vb%HPCY!T@T1Qy3B2IO^Tc_!4kdi-T+5A1GUbiiG z^nXA5a>vPM?%gk>^%NJ*H1_T_d2sS&Pf%yK`W+jsrK{&Jj*rZ~~T8neuJsuDuoQ{~rJPg*>TQ%c z^d@F9f#OuwHmD|B~Oy7i?U>_46#u+QD&d~(k_p#?$A*I9#J>c~v5 zo}nYhXf%D+44p8>AJae1(D7m1GTm+_kkXjmJyXY&F?RaFnL6f-4by+l)Ujo>o^C!% MN14rXnhwx-0OV(f{Qv*} diff --git a/src/test3d/water.cpp b/src/test3d/water.cpp index d87902e..33e62ce 100644 --- a/src/test3d/water.cpp +++ b/src/test3d/water.cpp @@ -37,6 +37,8 @@ #define FAR_VIEW 1000.0f #define CUBESIZE 2.0f +#define GLSL(src) #src + WaterScene::WaterScene (App *pApp) : Scene(pApp), fbReflection(0), texReflection(0), texReflecDepth(0), @@ -64,6 +66,15 @@ WaterScene::WaterScene (App *pApp) : Scene(pApp), } } } + +const std::string + + // In this shader, given vertices are simply interpreted as if in clip space. + srcClipVertex = "void main () {gl_Position = gl_Vertex;}", + + // This shader sets depth to 1.0 everywhere. + srcDepth1Fragment = "uniform vec4 color; void main () {gl_FragColor = color; gl_FragDepth = 1.0;}"; + bool WaterScene::Init() { int w, h; @@ -193,11 +204,19 @@ bool WaterScene::Init() return false; } + shaderProgramDepth = CreateShaderProgram (srcClipVertex, srcDepth1Fragment); + if (!shaderProgramDepth) + { + SetError ("error creating depth shader program: %s", GetError ()); + return false; + } + return true; } WaterScene::~WaterScene() { glDeleteProgram(shaderProgramWater); + glDeleteProgram(shaderProgramDepth); glDeleteTextures(1, &texReflection); glDeleteTextures(1, &texRefraction); @@ -569,6 +588,7 @@ const GLfloat colorCube [] = {0.0f, 1.0f, 0.0f, 1.0f}, colorCubeReflect [] = {0.0f, 0.8f, 0.1f, 1.0f}, bgcolorReflect [] ={0.1f, 0.2f, 1.0f, 1.0f}, bgcolorRefract [] = {0.1f, 0.1f, 0.2f, 1.0f}, + bgcolorRed [] = {1.0f, 0.0f, 0.0f, 1.0f}, posLight [] = { 0.0f, @@ -581,11 +601,12 @@ const GLfloat colorCube [] = {0.0f, 1.0f, 0.0f, 1.0f}, // const GLdouble planeWater [] = {0, -1.0, 0, 0}; // at origin, pointing down -#define CUBE_STENCIL_MASK 0xFFFFFFFFL +#define WATER_STENCIL_MASK 0xFFFFFFFFL +#define WATER_LINE_MARGE 0.1f // moves water line slightly up to prevent artifacts void WaterScene::Render() { - GLint texLoc; + GLint texLoc, colLoc; int w, h; SDL_GL_GetDrawableSize (pApp->GetMainWindow (), &w, &h); @@ -616,134 +637,138 @@ void WaterScene::Render() glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); + /* - The pixel shader uses the depth values, assuming that the background depth is 1.0. - Thus the water shouldn't be rendered in the frame buffers, or with depthmask set to false! + Refraction: make sure anything above the water isn't drawn. + Set background depth to 1.0 for the pixel shader. */ - - // Render the refraction in its buffer - glBindFramebuffer(GL_FRAMEBUFFER, fbRefraction); - glViewport(0, 0, w, h); + // Switch to refraction frame buffer + glBindFramebuffer (GL_FRAMEBUFFER, fbRefraction); + glViewport (0, 0, w, h); glEnable (GL_CULL_FACE); glEnable (GL_STENCIL_TEST); - glCullFace(GL_FRONT); + glEnable (GL_DEPTH_TEST); // Position the light in normal space - glLightfv(GL_LIGHT0, GL_POSITION, posLight); + glLightfv (GL_LIGHT0, GL_POSITION, posLight); + // Clear the refraction buffer with water color, maximum depth and stencil 1 glClearDepth (1.0f); - glClearStencil (0); - glClearColor(bgcolorRefract[0], bgcolorRefract[1], bgcolorRefract[2], bgcolorRefract[3]); + glClearStencil (1); + glClearColor (bgcolorRefract[0], bgcolorRefract[1], bgcolorRefract[2], bgcolorRefract[3]); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - /* - Refraction first Pass, make sure anything above the water isn't drawn. - Set stencil values to 1 where the cube is drawn. - */ + // Render cube refraction, set stencil to 0 there + glStencilFunc (GL_ALWAYS, 0, WATER_STENCIL_MASK); + glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); + glCullFace (GL_FRONT); + glDepthFunc (GL_LEQUAL); + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorCubeReflect); + glTranslatef (posCube.x, posCube.y, posCube.z); + RenderCube (); + glTranslatef (-posCube.x, -posCube.y, -posCube.z); - glDepthFunc(GL_LEQUAL); + // Set stencil to 1 for everything above the water level. + glStencilFunc (GL_ALWAYS, 1, WATER_STENCIL_MASK); + glCullFace (GL_FRONT); + glDepthFunc (GL_GEQUAL); + glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); + glDepthMask (GL_FALSE); glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glStencilFunc (GL_ALWAYS, 1, CUBE_STENCIL_MASK); - - glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); - + glTranslatef (0, WATER_LINE_MARGE, 0); RenderWater (); + glTranslatef (0, -WATER_LINE_MARGE, 0); - glDepthFunc(GL_GEQUAL); - glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); + // Set the depth value 1.0 and water color for all pixels with stencil 1. + glDepthMask (GL_TRUE); + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthFunc (GL_ALWAYS); + glStencilFunc (GL_EQUAL, 1, WATER_STENCIL_MASK); + glUseProgram (shaderProgramDepth); + colLoc = glGetUniformLocation (shaderProgramDepth, "color"); + glUniform4fv (colLoc, 1, bgcolorRefract); + glBegin (GL_QUADS); + glVertex4f (-1.0f, 1.0f, 0.5f, 1.0f); + glVertex4f ( 1.0f, 1.0f, 0.5f, 1.0f); + glVertex4f ( 1.0f,-1.0f, 0.5f, 1.0f); + glVertex4f (-1.0f,-1.0f, 0.5f, 1.0f); + glEnd (); + glUseProgram (0); - glTranslatef(posCube.x, posCube.y, posCube.z); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorCubeReflect); - RenderCube(); - glTranslatef(-posCube.x, -posCube.y, -posCube.z); /* - Refraction second pass, set background depth to 1.0 and render the cube - wherever stencil was set to 1. + Reflection: make sure anything below the water isn't drawn and + everything above the water is drawn in mirror image. + Set background depth to 1.0 for the pixel shader. */ - glClearDepth (1.0f); - glDepthFunc(GL_LEQUAL); - glStencilFunc (GL_EQUAL, 1, CUBE_STENCIL_MASK); - glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - glClear (GL_DEPTH_BUFFER_BIT); - - glTranslatef(posCube.x, posCube.y, posCube.z); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorCubeReflect); - RenderCube(); - glTranslatef(-posCube.x, -posCube.y, -posCube.z); - - - // Render the reflection in its buffer - glBindFramebuffer(GL_FRAMEBUFFER, fbReflection); - glViewport(0, 0, w, h); + // Switch to reflection frame buffer + glBindFramebuffer (GL_FRAMEBUFFER, fbReflection); + glViewport (0, 0, w, h); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); + glEnable (GL_CULL_FACE); glEnable (GL_STENCIL_TEST); + glEnable (GL_DEPTH_TEST); - // Clear the reflection buffer with water color and maximum depth + // Clear the reflection buffer with water color, maximum depth and stencil 1 glClearDepth (1.0f); - glClearStencil (0); + glClearStencil (1); glClearColor (bgcolorReflect[0], bgcolorReflect[1], bgcolorReflect[2], bgcolorReflect[3]); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - /* - Reflection first Pass, make sure anything above the water isn't drawn. - Set stencil values to 1 where the cube is drawn. - */ - + // Render cube reflection, set stencil to 0 there + glStencilFunc (GL_ALWAYS, 0, WATER_STENCIL_MASK); + glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); + glCullFace (GL_BACK); glDepthFunc (GL_LEQUAL); - glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - glStencilFunc (GL_ALWAYS, 1, CUBE_STENCIL_MASK); - - glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); - - RenderWater (); + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glPushMatrix (); + // move light and cube to their mirror position + glScalef (1, -1, 1); + glLightfv (GL_LIGHT0, GL_POSITION, posLight); + glTranslatef (posCube.x, posCube.y, posCube.z); + glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorCubeReflect); + RenderCube (); + glPopMatrix (); + // Set stencil to 1 for everything above the water level. + glStencilFunc (GL_ALWAYS, 1, WATER_STENCIL_MASK); + glCullFace (GL_FRONT); glDepthFunc (GL_GEQUAL); glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); - glCullFace (GL_BACK); - - glPushMatrix(); - // move cube to mirror position - glScalef(1, -1, 1); - glTranslatef(posCube.x, posCube.y, posCube.z); - RenderCube(); - glPopMatrix(); - - /* - Reflection second pass, set background depth to 1.0 and render the cube - wherever stencil was set to 1. - */ + glDepthMask (GL_FALSE); + glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glTranslatef (0, WATER_LINE_MARGE, 0); + RenderWater (); + glTranslatef (0, -WATER_LINE_MARGE, 0); + // Set the depth value 1.0 and water color for all pixels with stencil 1. + glDepthMask (GL_TRUE); glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glStencilFunc (GL_EQUAL, 1, CUBE_STENCIL_MASK); - glClearDepth (1.0f); - glDepthFunc (GL_LEQUAL); - - glClear (GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - // move light and cube to their mirror position - glScalef(1, -1, 1); - glLightfv(GL_LIGHT0, GL_POSITION, posLight); - glTranslatef(posCube.x, posCube.y, posCube.z); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colorCubeReflect); - RenderCube(); - glPopMatrix(); + glDepthFunc (GL_ALWAYS); + glStencilFunc (GL_EQUAL, 1, WATER_STENCIL_MASK); + glUseProgram (shaderProgramDepth); + colLoc = glGetUniformLocation (shaderProgramDepth, "color"); + glUniform4fv (colLoc, 1, bgcolorReflect); + glBegin (GL_QUADS); + glVertex4f (-1.0f, 1.0f, 0.5f, 1.0f); + glVertex4f ( 1.0f, 1.0f, 0.5f, 1.0f); + glVertex4f ( 1.0f,-1.0f, 0.5f, 1.0f); + glVertex4f (-1.0f,-1.0f, 0.5f, 1.0f); + glEnd (); + glUseProgram (0); // Direct rendering to the screen - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, w, h); + glBindFramebuffer (GL_FRAMEBUFFER, 0); + glViewport (0, 0, w, h); - glDepthFunc(GL_LEQUAL); + glDepthFunc (GL_LEQUAL); - glEnable(GL_TEXTURE_2D); + glEnable (GL_TEXTURE_2D); // Bind reflection to texture 0 and refraction to texture 1 glActiveTexture (GL_TEXTURE0); diff --git a/src/test3d/water.h b/src/test3d/water.h index 7bd3c05..a116547 100644 --- a/src/test3d/water.h +++ b/src/test3d/water.h @@ -55,8 +55,9 @@ class WaterScene : public App::Scene fbReflection, texReflection, texReflecDepth, fbRefraction, texRefraction, texRefracDepth, - // handle to shader program - shaderProgramWater; + // handle to shader programs + shaderProgramWater, + shaderProgramDepth; // Moves water grid points in time: void UpdateWater (const float dt); From bcc2e2c23da24c83e4a573722d89b6daa5280cdd Mon Sep 17 00:00:00 2001 From: cbaakman Date: Fri, 21 Aug 2015 22:30:39 +0200 Subject: [PATCH 2/4] shaders embedded in source The shader sources are no longer in a zip archive. They are now part of the source and embedded in the executable. This makes it easier to apply changes to them. --- bin/test3d.zip | Bin 2923104 -> 2921499 bytes src/shader.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++- src/shader.h | 5 ++ src/test3d/toon.cpp | 34 ++---------- src/test3d/water.cpp | 42 ++------------- 5 files changed, 131 insertions(+), 72 deletions(-) diff --git a/bin/test3d.zip b/bin/test3d.zip index 1afd28dbe2aaa565aa02818e1d0695b4a887418a..f1d9bd75beb442c171f939e281ff614abc1f5d5d 100644 GIT binary patch delta 206 zcmaE`WfSA<6`L3vS{PfHT9{i{T3B1yTG(4SS~y#{TDV(yT6kOdTKHQ8S_E5!T7+9f zT0~pKTEtrD*zQ-ak!;V>(cw5T67C3@mA!Z9o0f3>|N#aKGvHGlBH!%IQ5b nbxc$k7Hcz<sr3ZMkvVrt)0pTMi1_tGcIzS!({5w0{ delta 1758 zcmZvdc{o&i7{|{Xnu%e|j3vq5U@#b2x|YY*Vwn^klPyBl6j_=?jA?$kBB7Br5^+OP zN^V(;x|NZkMW~xCU9PfLm%=@i>ZzXde9w7)f4tw{`~Kd~d4IVVs!)B`s!(wN1z^Aj z_`xcG1{km!2mnEV1wud=;D89g0|FodQ6L7yfdp6sB*9uB1=ay+AOmE99FPYJKoP75 zB%pLnx!9D+J}7Q^ofMO`u64*O!Z%FQFFb(mC;;(E$aK+{ zbTASNq4@vdgP`SCg(EGbmnvk^+j!K{i1xxb%7y*5%ByC76R(#lS!SyO`>1kGzveBP z*n|;-7>~rWL}GcQ#uPd0{iMqDOU!d#?_3M=V_^2jU3-)+QwJrZoIbi;EpOZ(;W5y2 z(c^x9o;&o@PIZ;Vj!hKL?EXzC(`@Ha8S6P3&x;5+AspLs7y)M_0=a$WE z9c9kG4e_P*9d1#$3&0y~j19~4o1TS(Ls+50TMtvciz5Z}1~*s_z6>2=`!HWw*!ap% zIuGJ|3ODncuy-bg(4Q2zv=A!EE%8iw{qYeS4L=2|d0tnTb5I#w%2_ZtQCvTCvsfXo zP26C5%iLVy>)$Lo3O+DyIv&kVQhU>yT)9Wgp@tiSmz@}wjNNRNp}08O&_FGk%_l~5 z);@?9(<-f+XTkgrie1b*g_)#jQm)}#u(wslU*Z(ZJK6e->A*sf!_80Hv)OveZ8N+f+_ovVs@t`f zTS*vHvHN+3)>MH)cU)vD_svpeK24y`2??W9U3pW_TRlmf_Fd!eYv-f%EbFnfG*+ z&a*-S`m!q;P;}N{=u2BEpCbVqRkC*^*mVZYCs*`c^`kjiFwXm8HH>O>-$t&^!Slw7 zfN+$kP4tH6c|+>yb~*C#n7~K?3!|m9PZqr;*9-OICU0qC;1id0V?sUZ#)qch3cxr?Suf;aQ%#(;+>}=?vPj;GBSClR&z#b;W^) z?OHa+^%I_`qt&!|I&_}J(-Nn11u3_+oOtNcs=GXoqx5Jc%{SG%px<*%l@X~RA|p~o zq=rbnCfAgbXwO`!Q4+wGCNij#$w+;Di13J3e!_^5kYLTF5+7a>yiLW&_1|FCH7A#r z2M-KA?|V$Q$jxBuV!H6<1GUj5ij2C&skBFGMh$zU6+Q-wyuVPR5Ymh?6l@_XiN2>A zoG5uZT1r3Ne@#&*K4?=tQ$%CVZICz!8>K#r+8$eqt-NTQ(!#<1H*x3LhIw}N5%XEs z)S2n=M4J+9TUKh}SbU4-LpF8VzH;NY{^S(FmT_hndmfUrG3pn&BlE*O#Wo1m#>cl0 zJ8`uGyL|6RfG3>3KxPNqGL7h6h4axNUQKeHduiKQ>=~X#l^fR?pTP;w;!Y^7HGAjf zFLbd$ZH?X@_ROIO4I$SyFSo|wX4(QOkupnCG&Wc12))(NO={OCj0{KxPM$j))F`#D z-D^j^)0~}5E7o0G{>Bu8*(8Q07;tveu8$WwyL7w9oh4708sa7@$OVK6**CEg+K#KZ z57d%6pdFpBA~~Ma20~W(!ApCipDgweIOL9zyRD48?X<#Ajm6nH^Osd>)~8YaMs1Si z`wZ#NQ&bW;4hTZd13J$_Ao$wO?`G<%<(Zo4nMRQ|`kC?-19`+^qs5N~%giGN2=mJZ znF1V&EIe 0.9999) // clamp reflectOffset to prevent glitches + { + reflectOffset = vec2(0.0, 0.0); + } + else + { + vec3 flat_normal = normal - nfac * mirror_normal; + + vec3 eye_normal = normalize (gl_NormalMatrix * flat_normal); + + reflectOffset = eye_normal.xy * length (flat_normal) * 0.1; + } + + // The deeper under water, the more distortion: + + float reflection_depth = min (texture2D (tex_reflect_depth, gl_TexCoord[0].st).r, + texture2D (tex_reflect_depth, gl_TexCoord[0].st + reflectOffset.xy).r), + refraction_depth = min (texture2D (tex_refract_depth, gl_TexCoord[0].st).r, + texture2D (tex_refract_depth, gl_TexCoord[0].st - refrac * reflectOffset.xy).r), + + // diff_reflect and diff_refract will be linear representations of depth: + + diff_reflect = clamp (30 * (reflection_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0), + diff_refract = clamp (30 * (refraction_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0); + + vec4 reflectcolor = texture2D (tex_reflect, gl_TexCoord[0].st + diff_reflect * reflectOffset.xy), + refractcolor = texture2D (tex_refract, gl_TexCoord[0].st - diff_refract * refrac * reflectOffset.xy); + + float Rfraq = normalize (gl_NormalMatrix * normal).z; + Rfraq = Rfraq * Rfraq; + + gl_FragColor = reflectcolor * (1.0 - Rfraq) + refractcolor * Rfraq; + } + +)shader", + +toon_vsh [] = R"shader( + + varying vec3 N; + varying vec3 v; + varying vec4 color; + + void main() + { + v = vec3 (gl_ModelViewMatrix * gl_Vertex); + + N = normalize (gl_NormalMatrix * gl_Normal); + + color = gl_Color; + + gl_Position = ftransform(); + } + +)shader", + +toon_fsh [] = R"shader( + + uniform float cutOff = 0.8; + + varying vec3 N; + varying vec3 v; + varying vec4 color; + + void main() + { + vec3 L = normalize(gl_LightSource[0].position.xyz - v); + + float lum = clamp (dot(normalize (N), L) + 0.5, 0.0, 1.0); + + if (lum < cutOff) + lum = cutOff; + else + lum = 1.0; + + gl_FragColor = color * lum; + } + +)shader"; + /** * Compile either the source of a vertex or fragment shader. * :param type: either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER @@ -71,8 +186,11 @@ GLuint CreateShader(const std::string& source, int type) return shader; } - -GLuint CreateShaderProgram(const std::string& sourceVertex, const std::string& sourceFragment) +GLuint CreateShaderProgram (const char *sourceVertex, const char *sourceFragment) +{ + return CreateShaderProgram (std::string (sourceVertex), std::string (sourceFragment)); +} +GLuint CreateShaderProgram (const std::string& sourceVertex, const std::string& sourceFragment) { GLint result = GL_FALSE; int logLength; diff --git a/src/shader.h b/src/shader.h index f65ef13..0f146d6 100644 --- a/src/shader.h +++ b/src/shader.h @@ -26,6 +26,10 @@ #include +extern const char + water_vsh [], water_fsh [], + toon_vsh [], toon_fsh []; + /** * Creates a shader program from source. * :param sourceVertex: source of the vertex shader @@ -33,5 +37,6 @@ * :returns: OpenGL handle to the shader program, or 0 on error */ GLuint CreateShaderProgram (const std::string& sourceVertex, const std::string& sourceFragment); +GLuint CreateShaderProgram (const char *sourceVertex, const char *sourceFragment); #endif // SHADER_H diff --git a/src/test3d/toon.cpp b/src/test3d/toon.cpp index 7367bdb..2ce6320 100644 --- a/src/test3d/toon.cpp +++ b/src/test3d/toon.cpp @@ -42,8 +42,7 @@ ToonScene::~ToonScene () } bool ToonScene::Init () { - std::string resPath = std::string(SDL_GetBasePath()) + "test3d.zip", - sourceV = "", sourceF = "";; + std::string resPath = std::string(SDL_GetBasePath()) + "test3d.zip"; SDL_RWops *f; bool success; @@ -85,38 +84,11 @@ bool ToonScene::Init () return false; } - // Load the vertex shader source: - f = SDL_RWFromZipArchive (resPath.c_str(), "shaders/toon.vsh"); - if (!f) - return false; - - success = ReadAll (f, sourceV); - f->close(f); - - if (!success) - { - SetError ("error parsing toon.vsh: %s", GetError ()); - return false; - } - - // Load the fragment shader source: - f = SDL_RWFromZipArchive (resPath.c_str(), "shaders/toon.fsh"); - if (!f) - return false; - success = ReadAll (f, sourceF); - f->close(f); - - if (!success) - { - SetError ("error parsing toon.fsh: %s", GetError ()); - return false; - } - // Create shader from sources: - shaderProgram = CreateShaderProgram (sourceV, sourceF); + shaderProgram = CreateShaderProgram (toon_vsh, toon_fsh); if (!shaderProgram) { - SetError ("error creating shader program from toon.vsh and toon.fsh: %s", GetError ()); + SetError ("error creating toon shader program: %s", GetError ()); return false; } diff --git a/src/test3d/water.cpp b/src/test3d/water.cpp index 33e62ce..e39a2dc 100644 --- a/src/test3d/water.cpp +++ b/src/test3d/water.cpp @@ -67,6 +67,7 @@ WaterScene::WaterScene (App *pApp) : Scene(pApp), } } +// very simple one-line shaders: const std::string // In this shader, given vertices are simply interpreted as if in clip space. @@ -83,12 +84,6 @@ bool WaterScene::Init() GLenum status; char errBuf [100]; - std::string resourceZip = std::string(SDL_GetBasePath()) + "test3d.zip", - shaderDir = "shaders/", - pathVSH = shaderDir + "water.vsh", - pathFSH = shaderDir + "water.fsh", - sourceV = "", sourceF = ""; - /* Build two framebuffers for reflection and refraction. Each framebuffer gets a color and depth-stencil texture. @@ -165,42 +160,11 @@ bool WaterScene::Init() return false; } - SDL_RWops *f; - bool success; - - // Read vertex shader source from archive: - f = SDL_RWFromZipArchive (resourceZip.c_str(), pathVSH.c_str()); - if (!f) - return false; // file or archive missing - - success = ReadAll (f, sourceV); - f->close(f); - - if (!success) - { - SetError ("error parsing %s: %s", pathVSH.c_str(), GetError ()); - return false; - } - - // Read fragment shader source from archive: - f = SDL_RWFromZipArchive (resourceZip.c_str(), pathFSH.c_str()); - if (!f) - return false; - - success = ReadAll (f, sourceF); - f->close(f); - - if (!success) - { - SetError ("error parsing %s: %s", pathFSH.c_str(), GetError ()); - return false; - } - // Create shader program: - shaderProgramWater = CreateShaderProgram (sourceV, sourceF); + shaderProgramWater = CreateShaderProgram (water_vsh, water_fsh); if (!shaderProgramWater) { - SetError ("error creating shader program from %s and %s: %s", pathVSH.c_str(), pathFSH.c_str(), GetError ()); + SetError ("error creating water shader program : %s", GetError ()); return false; } From 57b38f961957a53fd53651c6b5da661184a72969 Mon Sep 17 00:00:00 2001 From: cbaakman Date: Sat, 22 Aug 2015 00:40:46 +0200 Subject: [PATCH 3/4] shader sources moved Moved the shader sources to the files where they are used. --- src/shader.cpp | 115 ------------------------------------------- src/shader.h | 4 -- src/test3d/toon.cpp | 47 ++++++++++++++++++ src/test3d/water.cpp | 80 ++++++++++++++++++++++++++++-- 4 files changed, 123 insertions(+), 123 deletions(-) diff --git a/src/shader.cpp b/src/shader.cpp index b308419..4335661 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -24,121 +24,6 @@ #include "err.h" #include "shader.h" -const char - water_vsh [] = R"shader( - -varying vec3 normal; - - void main() - { - normal=gl_Normal; - - gl_Position = ftransform(); - - gl_TexCoord[0].s = 0.5 * gl_Position.x / gl_Position.w + 0.5; - gl_TexCoord[0].t = 0.5 * gl_Position.y / gl_Position.w + 0.5; - } - -)shader", - -water_fsh [] = R"shader( - - uniform sampler2D tex_reflect, - tex_refract, - tex_reflect_depth, - tex_refract_depth; - - varying vec3 normal; - varying vec4 water_level_position; - - const vec3 mirror_normal = vec3(0.0, 1.0, 0.0); - - const float refrac = 1.33; // air to water - - void main() - { - float nfac = dot (normal, mirror_normal); - - vec2 reflectOffset; - if (nfac > 0.9999) // clamp reflectOffset to prevent glitches - { - reflectOffset = vec2(0.0, 0.0); - } - else - { - vec3 flat_normal = normal - nfac * mirror_normal; - - vec3 eye_normal = normalize (gl_NormalMatrix * flat_normal); - - reflectOffset = eye_normal.xy * length (flat_normal) * 0.1; - } - - // The deeper under water, the more distortion: - - float reflection_depth = min (texture2D (tex_reflect_depth, gl_TexCoord[0].st).r, - texture2D (tex_reflect_depth, gl_TexCoord[0].st + reflectOffset.xy).r), - refraction_depth = min (texture2D (tex_refract_depth, gl_TexCoord[0].st).r, - texture2D (tex_refract_depth, gl_TexCoord[0].st - refrac * reflectOffset.xy).r), - - // diff_reflect and diff_refract will be linear representations of depth: - - diff_reflect = clamp (30 * (reflection_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0), - diff_refract = clamp (30 * (refraction_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0); - - vec4 reflectcolor = texture2D (tex_reflect, gl_TexCoord[0].st + diff_reflect * reflectOffset.xy), - refractcolor = texture2D (tex_refract, gl_TexCoord[0].st - diff_refract * refrac * reflectOffset.xy); - - float Rfraq = normalize (gl_NormalMatrix * normal).z; - Rfraq = Rfraq * Rfraq; - - gl_FragColor = reflectcolor * (1.0 - Rfraq) + refractcolor * Rfraq; - } - -)shader", - -toon_vsh [] = R"shader( - - varying vec3 N; - varying vec3 v; - varying vec4 color; - - void main() - { - v = vec3 (gl_ModelViewMatrix * gl_Vertex); - - N = normalize (gl_NormalMatrix * gl_Normal); - - color = gl_Color; - - gl_Position = ftransform(); - } - -)shader", - -toon_fsh [] = R"shader( - - uniform float cutOff = 0.8; - - varying vec3 N; - varying vec3 v; - varying vec4 color; - - void main() - { - vec3 L = normalize(gl_LightSource[0].position.xyz - v); - - float lum = clamp (dot(normalize (N), L) + 0.5, 0.0, 1.0); - - if (lum < cutOff) - lum = cutOff; - else - lum = 1.0; - - gl_FragColor = color * lum; - } - -)shader"; - /** * Compile either the source of a vertex or fragment shader. * :param type: either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER diff --git a/src/shader.h b/src/shader.h index 0f146d6..cfce466 100644 --- a/src/shader.h +++ b/src/shader.h @@ -26,10 +26,6 @@ #include -extern const char - water_vsh [], water_fsh [], - toon_vsh [], toon_fsh []; - /** * Creates a shader program from source. * :param sourceVertex: source of the vertex shader diff --git a/src/test3d/toon.cpp b/src/test3d/toon.cpp index 2ce6320..d8abdf3 100644 --- a/src/test3d/toon.cpp +++ b/src/test3d/toon.cpp @@ -40,6 +40,53 @@ ToonScene::~ToonScene () glDeleteTextures (1, &texBG.tex); glDeleteProgram (shaderProgram); } + +const char + +// Toon vector shader: +toon_vsh [] = R"shader( + + varying vec3 N; + varying vec3 v; + varying vec4 color; + + void main() + { + v = vec3 (gl_ModelViewMatrix * gl_Vertex); + + N = normalize (gl_NormalMatrix * gl_Normal); + + color = gl_Color; + + gl_Position = ftransform(); + } + +)shader", + +// Toon fragment shader: +toon_fsh [] = R"shader( + + uniform float cutOff = 0.8; + + varying vec3 N; + varying vec3 v; + varying vec4 color; + + void main() + { + vec3 L = normalize(gl_LightSource[0].position.xyz - v); + + float lum = clamp (dot(normalize (N), L) + 0.5, 0.0, 1.0); + + if (lum < cutOff) + lum = cutOff; + else + lum = 1.0; + + gl_FragColor = color * lum; + } + +)shader"; bool ToonScene::Init () { std::string resPath = std::string(SDL_GetBasePath()) + "test3d.zip"; diff --git a/src/test3d/water.cpp b/src/test3d/water.cpp index e39a2dc..dba9e3a 100644 --- a/src/test3d/water.cpp +++ b/src/test3d/water.cpp @@ -67,14 +67,86 @@ WaterScene::WaterScene (App *pApp) : Scene(pApp), } } -// very simple one-line shaders: -const std::string +const char // In this shader, given vertices are simply interpreted as if in clip space. - srcClipVertex = "void main () {gl_Position = gl_Vertex;}", + srcClipVertex [] = "void main () {gl_Position = gl_Vertex;}", // This shader sets depth to 1.0 everywhere. - srcDepth1Fragment = "uniform vec4 color; void main () {gl_FragColor = color; gl_FragDepth = 1.0;}"; + srcDepth1Fragment [] = "uniform vec4 color; void main () {gl_FragColor = color; gl_FragDepth = 1.0;}", + +// Vector shader for the water's surface: +water_vsh [] = R"shader( + + varying vec3 normal; + + void main() + { + normal=gl_Normal; + + gl_Position = ftransform(); + + gl_TexCoord[0].s = 0.5 * gl_Position.x / gl_Position.w + 0.5; + gl_TexCoord[0].t = 0.5 * gl_Position.y / gl_Position.w + 0.5; + } + +)shader", + +// Fragment shader for the water's surface: +water_fsh [] = R"shader( + + uniform sampler2D tex_reflect, + tex_refract, + tex_reflect_depth, + tex_refract_depth; + + varying vec3 normal; + varying vec4 water_level_position; + + const vec3 mirror_normal = vec3(0.0, 1.0, 0.0); + + const float refrac = 1.33; // air to water + + void main() + { + float nfac = dot (normal, mirror_normal); + + vec2 reflectOffset; + if (nfac > 0.9999) // clamp reflectOffset to prevent glitches + { + reflectOffset = vec2(0.0, 0.0); + } + else + { + vec3 flat_normal = normal - nfac * mirror_normal; + + vec3 eye_normal = normalize (gl_NormalMatrix * flat_normal); + + reflectOffset = eye_normal.xy * length (flat_normal) * 0.1; + } + + // The deeper under water, the more distortion: + + float reflection_depth = min (texture2D (tex_reflect_depth, gl_TexCoord[0].st).r, + texture2D (tex_reflect_depth, gl_TexCoord[0].st + reflectOffset.xy).r), + refraction_depth = min (texture2D (tex_refract_depth, gl_TexCoord[0].st).r, + texture2D (tex_refract_depth, gl_TexCoord[0].st - refrac * reflectOffset.xy).r), + + // diff_reflect and diff_refract will be linear representations of depth: + + diff_reflect = clamp (30 * (reflection_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0), + diff_refract = clamp (30 * (refraction_depth - gl_FragCoord.z) / gl_FragCoord.w, 0.0, 1.0); + + vec4 reflectcolor = texture2D (tex_reflect, gl_TexCoord[0].st + diff_reflect * reflectOffset.xy), + refractcolor = texture2D (tex_refract, gl_TexCoord[0].st - diff_refract * refrac * reflectOffset.xy); + + float Rfraq = normalize (gl_NormalMatrix * normal).z; + Rfraq = Rfraq * Rfraq; + + gl_FragColor = reflectcolor * (1.0 - Rfraq) + refractcolor * Rfraq; + } + +)shader"; bool WaterScene::Init() { From 4b5e5801ad8e2e80853004d96e65b6969472725c Mon Sep 17 00:00:00 2001 From: cbaakman Date: Sat, 22 Aug 2015 10:17:39 +0200 Subject: [PATCH 4/4] Bumped version number to 1.3.1 --- notes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notes.txt b/notes.txt index b5ad905..5888bee 100644 --- a/notes.txt +++ b/notes.txt @@ -1,4 +1,4 @@ -Game templates version 1.3.0 +Game templates version 1.3.1 [test3d]