OpenGL 101: Drawing primitives - points, lines and triangles
文章推薦指數: 80 %
OpenGL 101: Drawing primitives - points, lines and triangles. Posted on May 13, 2013 by Paul. The code for this post is on GitHub: ...
OpenGL101:Drawingprimitives-points,linesandtrianglesPostedonMay13,2013byPaulThecodeforthispostisonGitHub:https://github.com/sol-prog/OpenGL-101.ThisisthesecondarticlefrommyOpenGL101series.Inthefirstarticlewe’veseenhowtoopenawindowforourOpenGLapplicationwiththeGLFWlibraryandhowtocompileandrunthecodeonWindows,OSXandLinux.ItistimetoactuallydrawsomethingusingOpenGL.First,letmementionthatOpenGLisalowlevelAPI,thismeansthatithasnosupportfordrawingcomplexgeometricalobjects.Itistheprogrammer’sjobtocombinethegeometricalprimitivesfromOpenGLincomplexshapesandbodies.ThebasicgeometricalprimitivesthatthecoreOpenGLprofileprovidetousarepoints,linesandtriangles.Forsimplicity,wearegoingtouseonlytwodimensionaldrawingsinthisarticle,butkeepinmindthatOpenGLallowsustorepresentthreedimensionalobjects,moreonthisinafuturearticle.Fornow,let’strytodrawthefourtrianglesfromthenextfigure:Fromageometricalpointofview,atriangleiscompletelydefinedbythepositioninspaceofhisthreecornersorvertices.InOpenGLterminology,avertexcanbeseenasacollectionofattributeslikeposition,color,texturecoordinatesetc…Intheabovefigurewehavefourtrianglesandtwelvevertices.Eachvertexfromourfigurehasapositionattribute,let’signoreforthemomentanyotherpossibleattributelikeacolor.WecanstoretheseverticesinaC++array:1 GLfloatvertices_position[24]={
2 0.0,0.0,
3 0.5,0.0,
4 0.5,0.5,
5
6 0.0,0.0,
7 0.0,0.5,
8 -0.5,0.5,
9
10 0.0,0.0,
11 -0.5,0.0,
12 -0.5,-0.5,
13
14 0.0,0.0,
15 0.0,-0.5,
16 0.5,-0.5,
17 };Ifyoulookclosely,youmaynoticethatthepointsarewrittencounterclockwise,thisisimportanttokeepinmind.Bydefault,inOpenGL,atrianglewithhisverticesstoredincounterclockwiseorderissaidtobefrontfacing.Whyisthisdistinctionimportant?WecaninstructOpenGLtorenderonlyoneofthetwofacesofatrianglesurface(thefrontortheback);thedefaultistorenderbothfaces.Anotherobservationabouttheabovearrayisthatitstoresonlythex,ycoordinatesforourtriangles,thisisbecausethezcoordinateiszeroforalltwelvevertices.So,howdoesOpenGLdrawsourtriangles,nowthatwehavetheirverticesinanarray?ThefirststepistotransferthecontentoftheabovearrayinaVertexBufferObject.AVertexBufferObject,orVBO,isachunkofmemorymanagedbyOpenGL,basicallyitisapieceofthememoryofyourvideocard.AVBOneedstobecreated,allocatedandfilledwithdata.WecanalsofilltheVBOwithdataintheallocationstep:1 //CreateaVectorBufferObjectthatwillstoretheverticesonvideomemory
2 GLuintvbo;
3 glGenBuffers(1,&vbo);
4
5 //AllocatespaceanduploadthedatafromCPUtoGPU
6 glBindBuffer(GL_ARRAY_BUFFER,vbo);
7 glBufferData(GL_ARRAY_BUFFER,sizeof(vertices_position),vertices_position,GL_STATIC_DRAW);Line3fromtheabovepieceofcodewillcreateahandleforourVBO,usingtheglGenBuffersfunction.Keepinmindthatthisfunctioncancreateanarrayofhandlesifneeded;forourparticularcasewehaveasingleVBOsoonehandlewillsuffice.OnceaVBOiscreated,weneedtobinditinordertomodifyoruseit,thisiswhatline6doeswiththeglBindBufferfunction.ThelastlinewillallocatespacefortheVBOandfillitwiththecontentofourvertices_positionarray.OncewehaveourdatainaVBO,wecansenditthroughtheOpenGLpipeline-anumberofstepsandtransformationsthroughwhichourverticeswillpass;theresultiswritteninaframebuffer.TheglfwSwapBuffers()functionfromGLFWwillreplacethecurrent,visibleframebuffer(thesurfaceofourwindow),withtheresultoftherenderingprocess.AsimplifiedschemeoftheOpenGLpipelineispresentedinthenextfigure:TheabovefigureisasimplifiedmodeloftheentireOpenGLpipeline,itdoesn’tincludeanyoftheoptionalsteps.Fromthepointofviewofabeginner,whatisimportantintheaboveschemearethevertexshaderandthefragmentshader.Ashaderisa,typicallysmall,programthatisexecutedonthevideocard.AshaderiswritteninGLSL,theOpenGLShadingLanguage,alanguagesimilarwithC.AvertexshaderisexecutedforeveryvertexinaVBO,hisroleisto,potentially,applyvarioustransformationsontheverticespositionattributeandpassthroughotherattributeslikecolor,texturecoordinatesetc…Itistheprogrammer’sresponsibilitytowriteavertexshaderforeveryOpenGLbasedapplication.Thenextstep,inoursimplifiedmodeloftheOpenGLpipeline,isthePrimitiveSetupstagethatwillorganizetheverticesintogeometricprimitives(points,linesandtriangles)forthenexttwostages.Intheclippingstage,theprimitivesthatliesoutsideoftheviewingvolumearesplitinsmallerprimitives.ThedefaultviewingvolumeinOpenGLisacube,[-1,+1]x[-1,+1]x[-1,+1],withtheorigininthemiddleofthecurrentviewport(arectangularareaofourwindow,forourcasetheviewporthasthesamedimensionsasourwindow),thepositivexaxispointstotheright,thepositiveyaxispointsupandthepositivezaxispointstowardtheviewer.If,forexample,oneofourtrianglescornerswillbeoutsideoftheviewingvolume,sayat-2.0,0,theclippingstagewillsplitthistriangleinsmallertrianglesandremovethetrianglesthatareoutsideoftheviewingvolume.ThisstageisexecutedbyOpenGL.Intherasterizationstage,theprimitivesthatexittheclippingstagearetransformedintofragments.Whichofthesefragmentswillendasapixelvalueinthefinalframebufferisdecidedinthenextstageofthepipeline.Inthebookrecommendedattheendofthisarticle,itissuggestedtothinkatthesefragmentsaspotentialpixels.Thefragmentshader,alsotheprogrammer’sresponsibility,canpotentiallydeterminethefragmentfinalcolor,discardsomefragments,orusetexturemapping.Afterthefragmentshader,thecolorofafragmentcanpotentiallybefurthermodifiedifthedepthandstenciltestsareenabled,orifblendingwasenabled.Fromoursimplifiedapproachpointofview,weareinterestedinthetwomandatoryshadersofanyOpenGLcoreapplication,thevertexandthefragmentshaders.Inotherwords,weneedtoimplementthesetwoshadersifwewanttodrawsomething.Let’sstartwiththeimplementationofasimplevertexshader:1#version150
2
3invec4position;
4
5voidmain(){
6 gl_Position=position;
7}Thefirstlineoftheaboveshaderspecifiestheshaderlanguageused,forOpenGL3.2thecorrespondingshaderlanguageversionis1.50.Next,wehaveaglobalvariableoftypevec4thatwillreceivethepositionofavertex,aGLSLvectorthatcanstore4values,bydefaultthisisinitializedwith(0,0,0,1).Asmallnotehere,OpenGLrepresentsinternallyanyvertexpositionasafourvaluevector,wearegoingtotalkmoreaboutthisinafuturearticleaboutMathinOpenGL:).Fromourpointofview,ifwesendatwovaluex,ypositiontotheshader,thelasttwonumberswillremainwiththedefaultvaluesof0and1.Anyshaderneedsamainfunction,liketheonedeclaredinline5.Line6setsthevalueofaninternalvariablefromGLSL,gl_position,tothevalueofourvertexposition.Next,wepresentasimplefragmentshader:1#version150
2
3outvec4out_color;
4
5voidmain(){
6 out_color=vec4(1.0,1.0,1.0,1.0);
7}Line3ofthefragmentshaderdefinesaglobalvariablethatwillbeusedtosetthecolorofeveryfragmenttowhite,seeline6.Asmentionedinthefirstarticleofthisseries,OpenGLusesinternallyafourdimensionalcolorspace,RGBA,inthisspace1.0,1.0,1.0,1.0representswhiteopaque(notransparency).Formaximumflexibility,wearegoingtosavetheabovetwoshadersintwoseparatefilesvert.shaderandfrag.shader.SomeauthorskeeptheshadersinC-stylestringsintheircode,whilethisavoidstheneedtoreadtheshaderfilesfromthediskitwillalsorequiretherecompilationoftheentireapplicationforanysmallchangeintheshaders.TherealproblemwiththeshadercodestoredasstringintheC++codeisthatwhenyouhaveanerrorinyourshadercodeitcouldbeabitdifficulttofindthecorrespondingerrorline.Anotherdisadvantageisthatyoudon’thavesyntaxhighlightinginwhatyoureditorinterpretsasaconstantstring.First,wearegoingtoneedafunctiontoreadtheshaderfromthedisk,nothingspectacularhere,justopenafileandreadthecontent,alsocheckifthefileisopen,youcanseethecompletefunctionontheGithubrepository:1voidread_shader_src(constchar*fname,std::vector
延伸文章資訊
- 1Drawing Lines is Hard - Matt DesLauriers - Svbtle
Twitter: @mattdesl Drawing lines might not sound like rocket science, but it's damn difficult to ...
- 2Hello Triangle - LearnOpenGL
In modern OpenGL we are required to define at least a vertex and fragment ... and back of all tri...
- 3Sample Modern OpenGL Programs - UCSD Math Department
SimpleDrawModern shows how to draw points, lines, line strips, line loops, and triangles. It incl...
- 4Drawing thin 3D lines with modern OpenGL - Reddit
Drawing thin 3D lines with modern OpenGL. I'm a bit confused on how render thin 3D lines without ...
- 5performance drop when drawing a line in OpenGL
There is no any function in modern OpenGL to draw a sphere using a simple one line command. You n...