Instancing - OpenGL ES SDK for Android - GitHub Pages
文章推薦指數: 80 %
This sample presents the instanced drawing technique using OpenGL ES 3.0. Overview. Instancing_android.png. Each cube is an instance of the same object. There ...
OpenGLESSDKforAndroid
ARMDeveloperCenter
Home
Pages
Namespaces
Files
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ThissamplepresentstheinstanceddrawingtechniqueusingOpenGLES3.0.
Overview
Eachcubeisaninstanceofthesameobject.
Thereisonlyonecopyofthecubevertexdatainmemory,andeachofthecubesdrawnisaninstanceofthatdata.ThisreducestheamountofmemorythatneedstobetransferredtotheGPU.Byusinggl_instanceIDintheshader,eachcubecanhaveadifferentposition,rotationspeedandcolour.Thistechniquecanbeusedwhereverrepeatedgeometryisusedinascene.
GeneratingaGeometry
Torenderacube(whichisthemostbasic3Dshape)weneedtogeneratecoordinatesforitsvertices.Thisisthefirststepwewouldliketofocuson.Pleaselookattheimagebelow.
Coordinatesofcubevertices.
Asshownintheimage,thecubevertexcoordinatesarearrangedaroundpoint<0,0,0>whichplacesthemin[,<1,1,1>]range.Thisisnotnecessary.Youareabletotranslatethecoordinatesinanydirectionortoscalethecube,butyouhavetobesurethatyourcubewillbestillvisibleonthescreen.Ifyouarenotsurehowtodothat,justfollowoursuggestions.Thereisanotherreasonforustousethecoordinatesarrangedaroundthecenterofthescreen(point<0,0,0>)-wewillthengeneratecopiesofthecubeandeachinstancewillbetranslatedtoanewposition(sothatthecubesmoveonacirculartrajectory).Butmoreaboutthislater.
Tohavecubeverticesisnotenoughtodrawthecubicshape.ThebasicOpenGLESrenderingtechniqueisbasedondrawingtrianglesthatmakeuparequestedshape.Thiswillbeournextstep.Thisisimportanttomentionherethatwhilstdescribingcubetrianglevertices,youshouldfollowtheclockwiseorcounter-clockwiseorder,otherwiseOpenGLESwillhavesometroublewithdetectingfrontandbackfaces.Inthisexampleweareusingclockwise(CW)ordertodescribecubecoordinatesasthisisthedefaultforOpenGLES.
Triangleswhichmakeupacubicshape.
Pleaselookatthecodepresentedbelowformoredetails.
/*Pleaseseeheaderforthespecification.*/
voidCubeModel::getTriangleRepresentation(float**coordinatesPtrPtr,
int*numberOfCoordinatesPtr,
int*numberOfPointsPtr,
floatscalingFactor)
{
ASSERT(coordinatesPtrPtr!=NULL,
"Cannotusenullpointerwhilecalculatingcoordinates");
/*Indexofanarraywewillputnewpointcoordinatesat.*/
intcurrentIndex=0;
/*6facesofcube,2trianglesforeachface,3pointsoftriangle,3coordinatesforeachpoint.*/
constintnumberOfCubeTriangleCoordinates=NUMBER_OF_CUBE_FACES*
NUMBER_OF_TRIANGLES_IN_QUAD*
NUMBER_OF_TRIANGLE_VERTICES*
NUMBER_OF_POINT_COORDINATES;
/*Allocatememoryforresultarray.*/
*coordinatesPtrPtr=(float*)malloc(numberOfCubeTriangleCoordinates*sizeof(float));
/*Isallocationsuccessful?.*/
ASSERT(*coordinatesPtrPtr!=NULL,
"Couldnotallocatememoryforresultarray.")
/*Example:
*Coordinatesforcubepoints:
*A-1.0f,1.0f,1.0f
*B-1.0f,1.0f,-1.0f
*C1.0f,1.0f,-1.0f
*D1.0f,1.0f,1.0f
*E-1.0f,-1.0f,1.0f
*F-1.0f,-1.0f,-1.0f
*G1.0f,-1.0f,-1.0f
*H1.0f,-1.0f,1.0f
*Create2trianglesforeachfaceofthecube.Verticesarewritteninclockwiseorder.
*B________C
*/|/|
*A.........D|
*.|.|
*.F|__.___|G
*././
*E.........H
*/
constVec3fpointA={-1.0f,1.0f,1.0f};
constVec3fpointB={-1.0f,1.0f,-1.0f};
constVec3fpointC={1.0f,1.0f,-1.0f};
constVec3fpointD={1.0f,1.0f,1.0f};
constVec3fpointE={-1.0f,-1.0f,1.0f};
constVec3fpointF={-1.0f,-1.0f,-1.0f};
constVec3fpointG={1.0f,-1.0f,-1.0f};
constVec3fpointH={1.0f,-1.0f,1.0f};
/*Fillthearraywithcoordinates.*/
/*Topface.*/
/*A*/
(*coordinatesPtrPtr)[currentIndex++]=pointA.x;
(*coordinatesPtrPtr)[currentIndex++]=pointA.y;
(*coordinatesPtrPtr)[currentIndex++]=pointA.z;
/*B*/
(*coordinatesPtrPtr)[currentIndex++]=pointB.x;
(*coordinatesPtrPtr)[currentIndex++]=pointB.y;
(*coordinatesPtrPtr)[currentIndex++]=pointB.z;
/*C*/
(*coordinatesPtrPtr)[currentIndex++]=pointC.x;
(*coordinatesPtrPtr)[currentIndex++]=pointC.y;
(*coordinatesPtrPtr)[currentIndex++]=pointC.z;
/*A*/
(*coordinatesPtrPtr)[currentIndex++]=pointA.x;
(*coordinatesPtrPtr)[currentIndex++]=pointA.y;
(*coordinatesPtrPtr)[currentIndex++]=pointA.z;
/*C*/
(*coordinatesPtrPtr)[currentIndex++]=pointC.x;
(*coordinatesPtrPtr)[currentIndex++]=pointC.y;
(*coordinatesPtrPtr)[currentIndex++]=pointC.z;
/*D*/
(*coordinatesPtrPtr)[currentIndex++]=pointD.x;
(*coordinatesPtrPtr)[currentIndex++]=pointD.y;
(*coordinatesPtrPtr)[currentIndex++]=pointD.z;
/*Bottomface.*/
/*F*/
(*coordinatesPtrPtr)[currentIndex++]=pointF.x;;
(*coordinatesPtrPtr)[currentIndex++]=pointF.y;;
(*coordinatesPtrPtr)[currentIndex++]=pointF.z;;
/*E*/
(*coordinatesPtrPtr)[currentIndex++]=pointE.x;
(*coordinatesPtrPtr)[currentIndex++]=pointE.y;
(*coordinatesPtrPtr)[currentIndex++]=pointE.z;
/*H*/
(*coordinatesPtrPtr)[currentIndex++]=pointH.x;
(*coordinatesPtrPtr)[currentIndex++]=pointH.y;
(*coordinatesPtrPtr)[currentIndex++]=pointH.z;
/*F*/
(*coordinatesPtrPtr)[currentIndex++]=pointF.x;
(*coordinatesPtrPtr)[currentIndex++]=pointF.y;
(*coordinatesPtrPtr)[currentIndex++]=pointF.z;
/*H*/
(*coordinatesPtrPtr)[currentIndex++]=pointH.x;
(*coordinatesPtrPtr)[currentIndex++]=pointH.y;
(*coordinatesPtrPtr)[currentIndex++]=pointH.z;
/*G*/
(*coordinatesPtrPtr)[currentIndex++]=pointG.x;
(*coordinatesPtrPtr)[currentIndex++]=pointG.y;
(*coordinatesPtrPtr)[currentIndex++]=pointG.z;
/*Backface.*/
/*G*/
(*coordinatesPtrPtr)[currentIndex++]=pointG.x;
(*coordinatesPtrPtr)[currentIndex++]=pointG.y;
(*coordinatesPtrPtr)[currentIndex++]=pointG.z;
/*C*/
(*coordinatesPtrPtr)[currentIndex++]=pointC.x;
(*coordinatesPtrPtr)[currentIndex++]=pointC.y;
(*coordinatesPtrPtr)[currentIndex++]=pointC.z;
/*B*/
(*coordinatesPtrPtr)[currentIndex++]=pointB.x;
(*coordinatesPtrPtr)[currentIndex++]=pointB.y;
(*coordinatesPtrPtr)[currentIndex++]=pointB.z;
/*G*/
(*coordinatesPtrPtr)[currentIndex++]=pointG.x;
(*coordinatesPtrPtr)[currentIndex++]=pointG.y;
(*coordinatesPtrPtr)[currentIndex++]=pointG.z;
/*B*/
(*coordinatesPtrPtr)[currentIndex++]=pointB.x;
(*coordinatesPtrPtr)[currentIndex++]=pointB.y;
(*coordinatesPtrPtr)[currentIndex++]=pointB.z;
/*F*/
(*coordinatesPtrPtr)[currentIndex++]=pointF.x;
(*coordinatesPtrPtr)[currentIndex++]=pointF.y;
(*coordinatesPtrPtr)[currentIndex++]=pointF.z;
/*Frontface.*/
/*E*/
(*coordinatesPtrPtr)[currentIndex++]=pointE.x;
(*coordinatesPtrPtr)[currentIndex++]=pointE.y;
(*coordinatesPtrPtr)[currentIndex++]=pointE.z;
/*A*/
(*coordinatesPtrPtr)[currentIndex++]=pointA.x;
(*coordinatesPtrPtr)[currentIndex++]=pointA.y;
(*coordinatesPtrPtr)[currentIndex++]=pointA.z;
/*D*/
(*coordinatesPtrPtr)[currentIndex++]=pointD.x;
(*coordinatesPtrPtr)[currentIndex++]=pointD.y;
(*coordinatesPtrPtr)[currentIndex++]=pointD.z;
/*E*/
(*coordinatesPtrPtr)[currentIndex++]=pointE.x;
(*coordinatesPtrPtr)[currentIndex++]=pointE.y;
(*coordinatesPtrPtr)[currentIndex++]=pointE.z;
/*D*/
(*coordinatesPtrPtr)[currentIndex++]=pointD.x;
(*coordinatesPtrPtr)[currentIndex++]=pointD.y;
(*coordinatesPtrPtr)[currentIndex++]=pointD.z;
/*H*/
(*coordinatesPtrPtr)[currentIndex++]=pointH.x;
(*coordinatesPtrPtr)[currentIndex++]=pointH.y;
(*coordinatesPtrPtr)[currentIndex++]=pointH.z;
/*Rightface.*/
/*H*/
(*coordinatesPtrPtr)[currentIndex++]=pointH.x;
(*coordinatesPtrPtr)[currentIndex++]=pointH.y;
(*coordinatesPtrPtr)[currentIndex++]=pointH.z;
/*D*/
(*coordinatesPtrPtr)[currentIndex++]=pointD.x;
(*coordinatesPtrPtr)[currentIndex++]=pointD.y;
(*coordinatesPtrPtr)[currentIndex++]=pointD.z;
/*C*/
(*coordinatesPtrPtr)[currentIndex++]=pointC.x;
(*coordinatesPtrPtr)[currentIndex++]=pointC.y;
(*coordinatesPtrPtr)[currentIndex++]=pointC.z;
/*H*/
(*coordinatesPtrPtr)[currentIndex++]=pointH.x;
(*coordinatesPtrPtr)[currentIndex++]=pointH.y;
(*coordinatesPtrPtr)[currentIndex++]=pointH.z;
/*C*/
(*coordinatesPtrPtr)[currentIndex++]=pointC.x;
(*coordinatesPtrPtr)[currentIndex++]=pointC.y;
(*coordinatesPtrPtr)[currentIndex++]=pointC.z;
/*G*/
(*coordinatesPtrPtr)[currentIndex++]=pointG.x;
(*coordinatesPtrPtr)[currentIndex++]=pointG.y;
(*coordinatesPtrPtr)[currentIndex++]=pointG.z;
/*Leftface.*/
/*F*/
(*coordinatesPtrPtr)[currentIndex++]=pointF.x;
(*coordinatesPtrPtr)[currentIndex++]=pointF.y;
(*coordinatesPtrPtr)[currentIndex++]=pointF.z;
/*B*/
(*coordinatesPtrPtr)[currentIndex++]=pointB.x;
(*coordinatesPtrPtr)[currentIndex++]=pointB.y;
(*coordinatesPtrPtr)[currentIndex++]=pointB.z;
/*A*/
(*coordinatesPtrPtr)[currentIndex++]=pointA.x;
(*coordinatesPtrPtr)[currentIndex++]=pointA.y;
(*coordinatesPtrPtr)[currentIndex++]=pointA.z;
/*F*/
(*coordinatesPtrPtr)[currentIndex++]=pointF.x;
(*coordinatesPtrPtr)[currentIndex++]=pointF.y;
(*coordinatesPtrPtr)[currentIndex++]=pointF.z;
/*A*/
(*coordinatesPtrPtr)[currentIndex++]=pointA.x;
(*coordinatesPtrPtr)[currentIndex++]=pointA.y;
(*coordinatesPtrPtr)[currentIndex++]=pointA.z;
/*E*/
(*coordinatesPtrPtr)[currentIndex++]=pointE.x;
(*coordinatesPtrPtr)[currentIndex++]=pointE.y;
(*coordinatesPtrPtr)[currentIndex++]=pointE.z;
/*Calculatesizeofacube.*/
if(scalingFactor!=1.0f)
{
for(inti=0;i
延伸文章資訊
- 1Instancing in OpenGL
Whenever you find yourself in a situation where you want to render many copies of a single object...
- 2Particles / Instancing - OpenGL Tutorial
Thanks to instancing, they will be shared by all particles. static const GLfloat ... Update the b...
- 3Instancing - LearnOpenGL
Instancing is a technique where we draw many (equal mesh data) objects at once with a single rend...
- 4Instancing - OpenGL ES SDK for Android - GitHub Pages
This sample presents the instanced drawing technique using OpenGL ES 3.0. Overview. Instancing_an...
- 5opengl Tutorial => Instancing by Vertex Attribute Arrays
A single instance represents one object or group of vertices (one grass leaf etc). Attributes ass...