How to do instancing the right way in OpenGL. - Stack Overflow
文章推薦指數: 80 %
glDrawElementsInstanced use gl_InstanceID variable as if it were a static integer vertex attribute. When the first copy of the vertices is sent to OpenGL, ...
2022DeveloperSurveyisopen!Takesurvey.
Home
Public
Questions
Tags
Users
Companies
Collectives
ExploreCollectives
Teams
StackOverflowforTeams
–Startcollaboratingandsharingorganizationalknowledge.
CreateafreeTeam
WhyTeams?
Teams
CreatefreeTeam
Collectives™onStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
Learnmore
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
Learnmore
HowtodoinstancingtherightwayinOpenGL.
AskQuestion
Asked
8years,3monthsago
Modified
8years,3monthsago
Viewed
17ktimes
4
1
IamtryingtouseVBOandInstancingmechanismthemostefficentway.IhaveaworldbasedonvoxelsandIwouldliketodrawthemusingleastpossiblenumberofdraw-calls.ThecodebelowpreparesVBOwithaquad:
voidVoxelView::initVBOs(){
/*---------------------MainOpenGLProgram---------------------*/
/*Verticesofatriangle(counter-clockwisewinding)*/
floatdata[6][3]={
//Leftbottomtriangle
{-0.5f,0.5f,0.0f},
{-0.5f,-0.5f,0.0f},
{0.5f,-0.5f,0.0f},
//Righttoptriangle
{0.5f,-0.5f,0.0f},
{0.5f,0.5f,0.0f},
{-0.5f,0.5f,0.0f}
};
/*----------------------InitialiseVBO-(Note:doonlyonce,atstartofprogram)---------------------*/
/*CreateanewVBOandusethevariable"triangleVBO"tostoretheVBOid*/
glGenBuffers(1,&triangleVBO);
/*MakethenewVBOactive*/
glBindBuffer(GL_ARRAY_BUFFER,triangleVBO);
/*Uploadvertexdatatothevideodevice*/
glBufferData(GL_ARRAY_BUFFER,6*3*sizeof(float),data,GL_STATIC_DRAW);
/*Specifythatourcoordinatedataisgoingintoattributeindex0(shaderAttribute),andcontainsthreefloatspervertex*/
glVertexAttribPointer(shaderAttribute,3,GL_FLOAT,GL_FALSE,0,0);
/*Enableattributeindex0(shaderAttribute)asbeingused*/
glEnableVertexAttribArray(shaderAttribute);
/*MakethenewVBOactive.*/
glBindBuffer(GL_ARRAY_BUFFER,triangleVBO);
/*-------------------------------------------------------------------------------------------------------*/
/*---------------------LoadVertexandFragmentshadersfromfilesandcompilethem--------------------*/
/*Readourshadersintotheappropriatebuffers*/
vertexSource=filetobuf("Shaders/exampleVertexShader1.vert");
fragmentSource=filetobuf("Shaders/exampleFragmentShader1.frag");
/*Assignourhandlesa"name"tonewshaderobjects*/
vertexShader=glCreateShader(GL_VERTEX_SHADER);
fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
/*Associatethesourcecodebufferswitheachhandle*/
glShaderSource(vertexShader,1,(constGLchar**)&vertexSource,0);
glShaderSource(fragmentShader,1,(constGLchar**)&fragmentSource,0);
/*Freethetemporaryallocatedmemory*/
free(vertexSource);
free(fragmentSource);
/*Compileourshaderobjects*/
glCompileShader(vertexShader);
glCompileShader(fragmentShader);
/*-------------------------------------------------------------------------------------------------------*/
/*--------------------Createshaderprogram,attachshaderstoitandthenlinkit---------------------*/
/*Assignourprogramhandlea"name"*/
shaderProgram=glCreateProgram();
/*Attachourshaderstoourprogram*/
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
/*Bindattributeindex0(shaderAttribute)toin_Position*/
/*"in_Position"willrepresent"data"array'scontentsinthevertexshader*/
glBindAttribLocation(shaderProgram,shaderAttribute,"in_Position");
/*Linkshaderprogram*/
glLinkProgram(shaderProgram);
Iamrenderingthequadthefollowingway:
voidVoxelView::renderVBO()
{
/*Setshaderprogramasbeingactivelyused*/
glUseProgram(shaderProgram);
/*SetbackgroundcolourtoBLACK*/
glClearColor(0.0,0.0,0.0,1.0);
/*ClearbackgroundwithBLACKcolour*/
glClear(GL_COLOR_BUFFER_BIT);
/*Actuallydrawthetriangle,givingthenumberofverticesprovidedbyinvokeglDrawArrays
whiletellingthatourdataisatriangleandwewanttodraw0-3vertexes
*/
glDrawArrays(GL_TRIANGLES,0,6);
}
Iwouldliketodrawthisquad(whichusesVBO)multipletimesusingtheinstancingmechanizm.IwouldlikeittofefairlysimpleasIwanttoimplementitformoresophisticatedcode.IknowthatIshoulduseglDrawElementsInstancedmethodtouseinstancingbutIdon'tknowhowtodoit.Doesanybodyknowhowtodoit?
c++openglvbogpu
Share
Improvethisquestion
Follow
askedFeb3,2014at22:32
PawełJastrzębskiPawełJastrzębski
72711goldbadge66silverbadges2424bronzebadges
1
AlwaysincludeyourOpenGLversioninfuture...itmakesanenormousdifferenceasyouprobablyknow.
– Engineer
Dec20,2014at19:09
Addacomment
|
1Answer
1
Sortedby:
Resettodefault
Highestscore(default)
Datemodified(newestfirst)
Datecreated(oldestfirst)
7
WhenusingglDrawElementsInstancedyouneedtomakeyourshadersusegl_InstanceiD
#version410
layout(location=0)invec3Position;
layout(location=1)invec2TexCoord;
layout(location=2)invec3Normal;
layout(location=3)inmat4WVP;
layout(location=7)inmat4World;
outvec2TexCoord0;
outvec3Normal0;
outvec3WorldPos0;
flatoutintInstanceID;
voidmain()
{
gl_Position=WVP*vec4(Position,1.0);
TexCoord0=TexCoord;
Normal0=World*vec4(Normal,0.0)).xyz;
WorldPos0=World*vec4(Position,1.0)).xyz;
InstanceID=gl_InstanceID;
};
glDrawElementsInstancedusegl_InstanceIDvariableasifitwereastaticintegervertexattribute.WhenthefirstcopyoftheverticesissenttoOpenGL,
gl_InstanceIDwillbezero.ItwillthenbeincrementedonceforeachcopyofthegeometryandwilleventuallyreachinstanceCount-1.
Itbehaveslikethis
for(intn=0;n
延伸文章資訊
- 1实例化
如果我们能够将数据一次发送给GPU,就会更方便,然后告诉OpenGL使用一个绘制函数,将这些数据绘制为多个物体。这就是我们将要展开讨论的实例化(Instancing)。
- 2opengl Tutorial => Instancing by Vertex Attribute Arrays
A single instance represents one object or group of vertices (one grass leaf etc). Attributes ass...
- 3Instancing - LearnOpenGL
Instancing is a technique where we draw many (equal mesh data) objects at once with a single rend...
- 4Instancing in OpenGL
Whenever you find yourself in a situation where you want to render many copies of a single object...
- 5Instanced Rendering - OpenGL Wiki
Instanced Rendering. From OpenGL Wiki. Redirect page. Jump to navigation Jump to search. Redirect...