OpenGL 2.1 - GLSL normal mapping - 3D C/C++ tutorials

文章推薦指數: 80 %
投票人數:10人

The normal map used in this tutorial is a Direct3D normal map and before it can be mapped on triangles, it must be converted from Direc3D space to OpenGL ... 3DC/C++tutorials-OpenGL2.1-GLSLnormalmapping 3DC/C++tutorials->OpenGL2.1->GLSLnormalmapping Useforpersonaloreducationalpurposesonly.Commercialandotherprofitusesstrictlyprohibited.Exploitationofcontentonawebsiteorinapublicationprohibited. Tocompileandrunthesetutorialssomeoralloftheselibrariesarerequired:FreeImage3.16.0,GLEW1.11.0,GLUT3.7.6/GLUTforDev-C++,GLM0.9.5.4 GettingstartedinVisualStudioExpress2013 GLSLnormalmapping WelcometotheGLSLnormalmappingtutorial. Beforeweshowyouourimplementationofthenormalmappingalgorithm,wewouldliketoinformyouaboutanessentialdifferencebetweenaDirect3DandanOpenGLnormalmap. Texture Direct3Dnormalmap OpenGLnormalmap Noticethegreenishpixelsinbothnormalmaps.ThenormalmapusedinthistutorialisaDirect3Dnormalmapandbeforeitcanbemappedontriangles,itmustbeconvertedfromDirec3DspacetoOpenGLspace. Inaforwardrendererwehavetwooptionshowtocalculatelighting.Eitherwetransformthelightdirectionvectorfromworld(orview)spacetotangentspace,orwetransformnormalfromnormalmapfromtangentspacetoworld(orview)space. Inadeferredrendererwehavenochoicebuttoconvertnormalfromnormalmapfromtangentspacetoworld(orview)space. Wedecidedtotransformnormalfromnormalmapbecauseit'seasiertoimplementandtounderstand.Andalsobecauseit'susableinadeferredrenderer. Thefirststepistocalculatethetangentandbitangentvectorspertriangle. for(intt=0;t<12;t++) { intia=t*3,ib=ia+1,ic=ib+1; vec3vdab=VertexArray[ib].Vertex-VertexArray[ia].Vertex; vec3vdac=VertexArray[ic].Vertex-VertexArray[ia].Vertex; vec2tcdab=VertexArray[ib].TexCoord-VertexArray[ia].TexCoord; vec2tcdac=VertexArray[ic].TexCoord-VertexArray[ia].TexCoord; floatr=1.0f/(tcdab.x*tcdac.y-tcdab.y*tcdac.x); ... vec3Tangent=normalize((vdab*tcdac.y-vdac*tcdab.y)*r); vec3Bitangent=normalize((vdac*tcdab.x-vdab*tcdac.x)*r); ... } Atthispointwehave2vectorsofunitlengthperpendiculartoeachother.Wedidn'texplicitlydefinenormals,soweneedtocalculatenormalspertriangletoo. for(intt=0;t<12;t++) { ... vec3Normal=normalize(cross(vdab,vdac)); ... } Nowwehave3vectorsofunitlengthperpendiculartoeachother.Thecommonpracticeistoprovidethisdatapervertex.Inthistutorialwerenderasimplerectangularprismobject,sothetangent,bitangentandnormalvectorsareidenticalforall3verticesofatriangle. for(intt=0;t<12;t++) { ... VertexArray[ia].Normal=Normal; VertexArray[ia].Tangent=Tangent; VertexArray[ia].Bitangent=Bitangent; VertexArray[ib].Normal=Normal; VertexArray[ib].Tangent=Tangent; VertexArray[ib].Bitangent=Bitangent; VertexArray[ic].Normal=Normal; VertexArray[ic].Tangent=Tangent; VertexArray[ic].Bitangent=Bitangent; } Withthis3vectorswecanconstructtheTBNmatrixinthefragmentshader. mat3x3TBN=mat3x3(Tangent,Bitangent,Normal); TheTBNmatrixisinit'ssubstanceanarbitraryaxisrotationmatrixanditdefinesthetransformationfromtangentspacetoobjectspace. Ifwewantedtorenderanobject(forexampleloadedfromafileandthatobjectwas)madeofcurvedsurfaces,itwouldprobablyincludepervertexnormals.Inthatcasethepervertexnormalsofatrianglewouldn'tnecessarilyhavetobeidenticalandtheywouldn'tnecessarilyhavetobeperpendiculartothepertriangletangentandbitangentvectors.Aftercalculatingthepertriangletangentandbitangentvectors,wewouldhavetocalculatethepervertextangentvectorperpendiculartothepervertexnormalvectorusingthe(firststepofthe)Gram-Schmidtorthogonalisationprocessandthenwewouldhavetocalculatethepervertexbitangentvectorperpendiculartothepervertextangentandnormalvectorsusingthecrossproduct. Tangent=normalize(Tangent-Normal*dot(Normal,Tangent)); Bitangent=cross(Normal,Tangent); Thetangentandbitangentvectorsarepassedontovertexshaderasvertexattributes. attributevec3att_Tangent,att_Bitangent; InGLSL1.2wedon'thavetheoptionofusingthe"layout(location=)in..."convention,sowehavetogetthelocationsoftheattributesusingtheglGetAttribLocationfunctionintheC/C++codefirst. NormalMapping.AttribLocations=newGLuint[2]; NormalMapping.AttribLocations[0]=glGetAttribLocation(NormalMapping,"att_Tangent"); NormalMapping.AttribLocations[1]=glGetAttribLocation(NormalMapping,"att_Bitangent"); WhenrenderingtheobjectweenablethevertexattributearrayusingtheglEnableVertexAttribArrayfunctionandwesetthearrayusingtheglVertexAttribPointerfunction.YoumayknowtheglEnableVertexAttribArrayandglVertexAttribPointerfunctionsfromtheOpenGL3.3tutorials,buttheyareoriginallyOpenGL2.0functions.Thisfactisoneofthereasons,whyyoushouldlearntheOpenGL2.1andolderwayofrenderingbeforeyoujumptoOpenGL3.3. glEnableVertexAttribArray(NormalMapping.AttribLocations[0]); glVertexAttribPointer(NormalMapping.AttribLocations[0],3,GL_FLOAT,GL_FALSE,68,(void*)44); glEnableVertexAttribArray(NormalMapping.AttribLocations[1]); glVertexAttribPointer(NormalMapping.AttribLocations[1],3,GL_FLOAT,GL_FALSE,68,(void*)56); Ifnormalmappingisenabled,intheglsl_normal_mapping.vsvertexshaderweonlypassonthetangent,bitangentandnormalvectorstotheglsl_normal_mapping.fsfragmentshader.ThenormalmatrixiscalculatedintheC/C++codeastransposeoftheinverseoftheupperleft3x3submatrixofthemodelmatrix,sothelightingcalculationsintheglsl_normal_mapping.fsfragmentshaderaredoneinworldspace.Thetangent,bitangentandnormalvectorsmustbenormalizedinfragmentshaderbecauseoftworeasons.Thenormalmatrixcancontaininversescalingtransformationandthetangent,bitangentandnormalvectorscanbepervertexdata.Withthenormalizedtangent,bitangentandnormalvectorswecanconstructtheTBNmatrixanduseittotransformthenormalfromnormalmapfromtangentspacetoobjectspace.Thenwehavetousethenormalmatrixtotransformnormalfromnormalmapfromobjectspacetoworldspace. opengl_21_tutorials_win32_framework.h ... classCVertexArrayElement { public: vec3Vertex; vec3Color; vec2TexCoord; vec3Normal; vec3Tangent; vec3Bitangent; }; ... classCOpenGLRenderer { protected: intWidth,Height; mat3x3TangentMatrix,NormalMatrix; mat4x4ModelMatrix,ViewMatrix,ProjectionMatrix; protected: CTextureTexture,NormalMap; CShaderProgramNormalMapping; CVertexArrayElement*VertexArray; GLuintVertexBufferObject; public: boolTexturingEnabled,NormalMappingEnabled,ShowEdges,ShowTBNs,ShowAxisGrid,Pause; public: CStringText; public: COpenGLRenderer(); ~COpenGLRenderer(); boolInit(); voidRender(floatFrameTime); voidResize(intWidth,intHeight); voidDestroy(); }; ... opengl_21_tutorials_win32_framework.cpp ... COpenGLRenderer::COpenGLRenderer() { TexturingEnabled=true; NormalMappingEnabled=true; ShowEdges=true; ShowTBNs=true; ShowAxisGrid=true; Pause=false; Camera.SetViewMatrixPointer(&ViewMatrix); } COpenGLRenderer::~COpenGLRenderer() { } boolCOpenGLRenderer::Init() { CShaderProgramConvertNormalMap; boolError=false; Error|=!Texture.LoadTexture2D("texture.jpg"); Error|=!NormalMap.LoadTexture2D("normal_map.jpg"); Error|=!ConvertNormalMap.Load("convert_normal_map.vs","convert_normal_map.fs"); Error|=!NormalMapping.Load("normal_mapping.vs","normal_mapping.fs"); if(Error) { returnfalse; } ConvertNormalMap.UniformLocations=newGLuint[1]; ConvertNormalMap.UniformLocations[0]=glGetUniformLocation(ConvertNormalMap,"Conversion"); NormalMapping.AttribLocations=newGLuint[2]; NormalMapping.AttribLocations[0]=glGetAttribLocation(NormalMapping,"att_Tangent"); NormalMapping.AttribLocations[1]=glGetAttribLocation(NormalMapping,"att_Bitangent"); NormalMapping.UniformLocations=newGLuint[6]; NormalMapping.UniformLocations[0]=glGetUniformLocation(NormalMapping,"ModelMatrix"); NormalMapping.UniformLocations[1]=glGetUniformLocation(NormalMapping,"NormalMatrix"); NormalMapping.UniformLocations[2]=glGetUniformLocation(NormalMapping,"TexturingEnabled"); NormalMapping.UniformLocations[3]=glGetUniformLocation(NormalMapping,"NormalMappingEnabled"); NormalMapping.UniformLocations[4]=glGetUniformLocation(NormalMapping,"LightPosition"); NormalMapping.UniformLocations[5]=glGetUniformLocation(NormalMapping,"CameraPosition"); glUseProgram(NormalMapping); glUniform1i(glGetUniformLocation(NormalMapping,"Texture"),0); glUniform1i(glGetUniformLocation(NormalMapping,"NormalMap"),1); glUseProgram(0); glViewport(0,0,512,512); glUseProgram(ConvertNormalMap); glUniform3fv(ConvertNormalMap.UniformLocations[0],1,&vec3(1.0f,-1.0f,1.0f)); glBindTexture(GL_TEXTURE_2D,NormalMap); glBegin(GL_QUADS); glVertex2f(0.0f,0.0f); glVertex2f(1.0f,0.0f); glVertex2f(1.0f,1.0f); glVertex2f(0.0f,1.0f); glEnd(); glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,512,512); glBindTexture(GL_TEXTURE_2D,0); glUseProgram(0); ConvertNormalMap.Destroy(); VertexArray=newCVertexArrayElement[36]; inti=0; VertexArray[i].Vertex=vec3(0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,0.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(-0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(1.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,1.0f);i++; VertexArray[i].Vertex=vec3(0.5f,-0.5f,-0.5f);VertexArray[i].Color=vec3(1.0f,1.0f,1.0f);VertexArray[i].TexCoord=vec2(0.0f,0.0f);i++; for(intt=0;t<12;t++) { intia=t*3,ib=ia+1,ic=ib+1; vec3vdab=VertexArray[ib].Vertex-VertexArray[ia].Vertex; vec3vdac=VertexArray[ic].Vertex-VertexArray[ia].Vertex; vec2tcdab=VertexArray[ib].TexCoord-VertexArray[ia].TexCoord; vec2tcdac=VertexArray[ic].TexCoord-VertexArray[ia].TexCoord; floatr=1.0f/(tcdab.x*tcdac.y-tcdab.y*tcdac.x); vec3Normal=normalize(cross(vdab,vdac)); vec3Tangent=normalize((vdab*tcdac.y-vdac*tcdab.y)*r); vec3Bitangent=normalize((vdac*tcdab.x-vdab*tcdac.x)*r); VertexArray[ia].Normal=Normal; VertexArray[ia].Tangent=Tangent; VertexArray[ia].Bitangent=Bitangent; VertexArray[ib].Normal=Normal; VertexArray[ib].Tangent=Tangent; VertexArray[ib].Bitangent=Bitangent; VertexArray[ic].Normal=Normal; VertexArray[ic].Tangent=Tangent; VertexArray[ic].Bitangent=Bitangent; } glGenBuffers(1,&VertexBufferObject); glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject); glBufferData(GL_ARRAY_BUFFER,36*68,VertexArray,GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER,0); Camera.Look(vec3(2.0f,1.75f,2.0f),vec3(0.5f,0.625f,0.5f)); returntrue; } voidCOpenGLRenderer::Render(floatFrameTime) { staticfloata=0.0f; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(&ViewMatrix); if(ShowAxisGrid) { glLineWidth(2.0f); glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f);glVertex3f(1.0f,0.0f,0.0f); glVertex3f(1.0f,0.1f,0.0f);glVertex3f(1.1f,-0.1f,0.0f); glVertex3f(1.1f,0.1f,0.0f);glVertex3f(1.0f,-0.1f,0.0f); glColor3f(0.0f,1.0f,0.0f); glVertex3f(0.0f,0.0f,0.0f);glVertex3f(0.0f,1.0f,0.0f); glVertex3f(-0.05f,1.25f,0.0f);glVertex3f(0.0f,1.15f,0.0f); glVertex3f(0.05f,1.25f,0.0f);glVertex3f(0.0f,1.15f,0.0f); glVertex3f(0.0f,1.15f,0.0f);glVertex3f(0.0f,1.05f,0.0f); glColor3f(0.0f,0.0f,1.0f); glVertex3f(0.0f,0.0f,0.0f);glVertex3f(0.0f,0.0f,1.0f); glVertex3f(-0.05f,0.1f,1.05f);glVertex3f(0.05f,0.1f,1.05f); glVertex3f(0.05f,0.1f,1.05f);glVertex3f(-0.05f,-0.1f,1.05f); glVertex3f(-0.05f,-0.1f,1.05f);glVertex3f(0.05f,-0.1f,1.05f); glEnd(); glLineWidth(1.0f); glColor3f(1.0f,1.0f,1.0f); glBegin(GL_LINES); floatd=50.0f; for(floati=-d;i<=d;i+=1.0f) { glVertex3f(i,0.0f,-d); glVertex3f(i,0.0f,d); glVertex3f(-d,0.0f,i); glVertex3f(d,0.0f,i); } glEnd(); } glMultMatrixf(&ModelMatrix); glUseProgram(NormalMapping); glUniformMatrix4fv(NormalMapping.UniformLocations[0],1,GL_FALSE,&ModelMatrix); glUniformMatrix3fv(NormalMapping.UniformLocations[1],1,GL_FALSE,&NormalMatrix); glUniform1i(NormalMapping.UniformLocations[2],TexturingEnabled); glUniform1i(NormalMapping.UniformLocations[3],NormalMappingEnabled); glUniform3fv(NormalMapping.UniformLocations[4],1,&vec3(0.5f,1.5f,0.5f)); glUniform3fv(NormalMapping.UniformLocations[5],1,&Camera.Position); glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_FLOAT,68,(void*)0); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3,GL_FLOAT,68,(void*)12); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,68,(void*)24); glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT,68,(void*)32); glEnableVertexAttribArray(NormalMapping.AttribLocations[0]); glVertexAttribPointer(NormalMapping.AttribLocations[0],3,GL_FLOAT,GL_FALSE,68,(void*)44); glEnableVertexAttribArray(NormalMapping.AttribLocations[1]); glVertexAttribPointer(NormalMapping.AttribLocations[1],3,GL_FLOAT,GL_FALSE,68,(void*)56); glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D,Texture); glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D,NormalMap); glDrawArrays(GL_TRIANGLES,0,36); glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D,0); glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D,0); glDisableVertexAttribArray(NormalMapping.AttribLocations[1]); glDisableVertexAttribArray(NormalMapping.AttribLocations[0]); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER,0); glUseProgram(0); if(ShowEdges) { glMatrixMode(GL_MODELVIEW); glLoadMatrixf(&ViewMatrix); glMultMatrixf(&ModelMatrix); for(intt=0;t<12;t++) { intia=t*3,ib=ia+1,ic=ib+1; glColor3f(0.0f,0.0f,0.0f); glBegin(GL_LINES); glVertex3fv(&VertexArray[ia].Vertex);glVertex3fv(&VertexArray[ib].Vertex); glVertex3fv(&VertexArray[ib].Vertex);glVertex3fv(&VertexArray[ic].Vertex); glVertex3fv(&VertexArray[ic].Vertex);glVertex3fv(&VertexArray[ia].Vertex); glEnd(); } } if(ShowTBNs) { glMatrixMode(GL_MODELVIEW); glLoadMatrixf(&ViewMatrix); for(intt=0;t<12;t++) { intia=t*3,ib=ia+1,ic=ib+1; vec3VertexA=*(vec3*)&(ModelMatrix*vec4(VertexArray[ia].Vertex,1.0f)); vec3VertexB=*(vec3*)&(ModelMatrix*vec4(VertexArray[ib].Vertex,1.0f)); vec3VertexC=*(vec3*)&(ModelMatrix*vec4(VertexArray[ic].Vertex,1.0f)); glLineWidth(1.0f); vec3Middle=(VertexA+VertexB+VertexC)/3.0f; glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f);glVertex3fv(&Middle);glVertex3fv(&(Middle+normalize(TangentMatrix*VertexArray[ia].Tangent)*0.25f)); glColor3f(0.0f,1.0f,0.0f);glVertex3fv(&Middle);glVertex3fv(&(Middle+normalize(TangentMatrix*VertexArray[ia].Bitangent)*0.25f)); glColor3f(0.0f,0.0f,1.0f);glVertex3fv(&Middle);glVertex3fv(&(Middle+normalize(NormalMatrix*VertexArray[ia].Normal)*0.25f)); glEnd(); } } glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); if(!Pause) { ModelMatrix=translate(0.5f,0.5f,0.5f)*rotate(a,vec3(0.0f,1.0f,0.0f))*rotate(a,vec3(1.0f,0.0f,0.0f))*scale(1.0f,0.75f,0.5f); TangentMatrix=mat3x3(ModelMatrix); NormalMatrix=transpose(inverse(TangentMatrix)); a+=11.25f*FrameTime; } } voidCOpenGLRenderer::Resize(intWidth,intHeight) { this->Width=Width; this->Height=Height; glViewport(0,0,Width,Height); ProjectionMatrix=perspective(45.0f,(float)Width/(float)Height,0.125f,512.0f); glMatrixMode(GL_PROJECTION); glLoadMatrixf(&ProjectionMatrix); } voidCOpenGLRenderer::Destroy() { Texture.Destroy(); NormalMap.Destroy(); NormalMapping.Destroy(); delete[]VertexArray; glDeleteBuffers(1,&VertexBufferObject); } ... voidCOpenGLView::OnKeyDown(UINTKey) { switch(Key) { caseVK_F1: OpenGLRenderer.TexturingEnabled=!OpenGLRenderer.TexturingEnabled; break; caseVK_F2: OpenGLRenderer.NormalMappingEnabled=!OpenGLRenderer.NormalMappingEnabled; break; caseVK_F3: OpenGLRenderer.ShowEdges=!OpenGLRenderer.ShowEdges; break; caseVK_F4: OpenGLRenderer.ShowTBNs=!OpenGLRenderer.ShowTBNs; break; caseVK_F5: OpenGLRenderer.ShowAxisGrid=!OpenGLRenderer.ShowAxisGrid; break; caseVK_SPACE: OpenGLRenderer.Pause=!OpenGLRenderer.Pause; break; } } ... convert_normal_map.vs #version120 voidmain() { gl_TexCoord[0]=gl_Vertex; gl_Position=gl_Vertex*2.0-1.0; } convert_normal_map.fs #version120 uniformsampler2DNormalMap; uniformvec3Conversion; voidmain() { vec3Normal=normalize(texture2D(NormalMap,gl_TexCoord[0].st).rgb*2.0-1.0); Normal=Normal*Conversion; gl_FragColor=vec4(Normal*0.5+0.5,1.0); } normal_mapping.vs #version120 uniformmat4x4ModelMatrix; uniformmat3x3NormalMatrix; uniformboolTexturingEnabled,NormalMappingEnabled; attributevec3att_Tangent,att_Bitangent; varyingvec3var_Position,var_Normal,var_Tangent,var_Bitangent; voidmain() { gl_FrontColor=gl_Color; if(TexturingEnabled||NormalMappingEnabled) { gl_TexCoord[0]=gl_MultiTexCoord0; } var_Position=(ModelMatrix*gl_Vertex).xyz; if(NormalMappingEnabled) { var_Normal=gl_Normal; var_Tangent=att_Tangent; var_Bitangent=att_Bitangent; } else { var_Normal=NormalMatrix*gl_Normal; } gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex; } normal_mapping.fs #version120 uniformsampler2DTexture,NormalMap; uniformmat3x3NormalMatrix; uniformvec3LightPosition,CameraPosition; uniformboolTexturingEnabled,NormalMappingEnabled; varyingvec3var_Position,var_Normal,var_Tangent,var_Bitangent; voidmain() { gl_FragColor=gl_Color; if(TexturingEnabled) { gl_FragColor.rgb*=texture2D(Texture,gl_TexCoord[0].st).rgb; } vec3Normal=normalize(var_Normal); if(NormalMappingEnabled) { vec3Tangent=normalize(var_Tangent); vec3Bitangent=normalize(var_Bitangent); mat3x3TBN=mat3x3(Tangent,Bitangent,Normal); Normal=normalize(NormalMatrix*(TBN*(texture2D(NormalMap,gl_TexCoord[0].st).rgb*2.0-1.0))); } vec3LightDirection=normalize(LightPosition-var_Position); floatNdotLD=max(dot(Normal,LightDirection),0.0); gl_FragColor.rgb*=0.25+0.75*NdotLD; vec3CameraDirection=normalize(CameraPosition-var_Position); vec3LightDirectionReflected=reflect(-LightDirection,Normal); floatCDdotLDR=max(dot(CameraDirection,LightDirectionReflected),0.0); gl_FragColor.rgb+=pow(CDdotLDR,128.0); } Download glsl_normal_mapping.zip(VisualStudio2008Professional) glsl_normal_mapping_devcpp4992.zip(Dev-C++4.9.9.2) ©2010-2016Bc.MichalBelanec,michalbelanec(at)centrum(dot)sk LastupdateJune25,2016 OpenGL®isaregisteredtrademarkofSiliconGraphicsInc.



請為這篇文章評分?