Reputation: 1309
I am using GLBatch from the GLTools library to draw a tetrahedron. I want to draw the tetrahedron multiple times at different locations to draw a Sierpinski-Tetrahedron. Creating the geometry and drawing the cone works fine for one instance of the tetrahedron, but I want to draw the tetrahedron multiple times at different locations. Calling geometry.Draw()
multiple times (with different model view matrices) does not work. The cone is still drawn only once.
How can I draw the GLBatch multiple times?
Here is my code:
GLBatch geometry;
// This is called once on initialization.
void CreateTetrahedron()
{
geometry.Begin(GL_TRIANGLE_STRIP, 6);
geometry.Color4f(1, 0, 0, 1);
geometry.Vertex3f(0, 1, 0);
geometry.Color4f(1, 0, 0, 1);
geometry.Vertex3f(-0.5f, 0, 0.5f);
geometry.Color4f(1, 0, 0, 1);
geometry.Vertex3f(0.5f, 0, 0.5f);
if (recursionLevel < 3)
{
geometry.Color4f(0, 1, 0, 1);
geometry.Vertex3f(0, 0, -0.7f);
geometry.Color4f(0, 0, 1, 1);
geometry.Vertex3f(0, 1, 0);
geometry.Color4f(1, 1, 1, 1);
geometry.Vertex3f(-0.5f, 0, 0.5f);
}
geometry.End();
}
// This is where I want to draw it. The function is recursive, and thus the geometry should be drawn multiple times with different matrices.
void DrawSierpinskiTetrahedron(UINT32 level)
{
if (level == 0)
{
geometry.Draw();
}
else
{
modelViewMatrix.PushMatrix();
modelViewMatrix.Scale(0.5f, 0.5f, 0.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0, 1, 0);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(-0.5f, 0, 0.5f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0.5f, 0, 0.5f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0, 0, -0.7f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PopMatrix();
}
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix();
// Camera Translation
modelViewMatrix.Translate(xTrans, yTrans, zTrans);
// Model Translation, Rotatation und Scale
glm::mat4 trans = glm::translate(glm::mat4(), translation);
modelViewMatrix.MultMatrix(glm::value_ptr(trans));
glm::mat4 rot = glm::mat4_cast(rotation);
modelViewMatrix.MultMatrix(glm::value_ptr(rot));
glm::mat4 sc = glm::scale(glm::mat4(), scale);
modelViewMatrix.MultMatrix(glm::value_ptr(sc));
// Set the shader for rendering
shaderManager.UseStockShader(GLT_SHADER_FLAT_ATTRIBUTES, transformPipeline.GetModelViewProjectionMatrix());
if (recursionLevel < 0)
{
recursionLevel = 0;
}
if (recursionLevel > 5)
{
recursionLevel = 5;
}
DrawSierpinskiTetrahedron(recursionLevel);
gltCheckErrors(0);
modelViewMatrix.PopMatrix();
TwDraw();
glutSwapBuffers();
glutPostRedisplay();
}
// Initialize rendering context
void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
shaderManager.InitializeStockShaders();
transformPipeline.SetMatrixStacks(modelViewMatrix,projectionMatrix);
// Create the geometry
CreateTetrahedron();
InitGUI();
}
Update:
Doing the following does not scale the tetrahedron.
modelViewMatrix.PushMatrix();
modelViewMatrix.Scale(1000, 1000, 1000);
geometry.Draw();
modelViewMatrix.PopMatrix();
Upvotes: 0
Views: 113
Reputation: 210909
GLMatrixStack is a class which provides a matrix stack and operations to the top matrix of the stack.
The class GLShaderManager can load a shader and handles setting of the uniform variables of the shader.
The shader program transforms the vertex coordinates of the mesh by the model view matrix. This causes that the mseh can be rendered to different places an with different orientations in the scene.
If the modelview matrix is changed, it has to be set to the corresponding uniform variable in the shader program, to make the change work.
This can be done by calling GLShaderManager::UseStockShader
before drawing the mesh.
Adapt your code like this:
void DrawSierpinskiTetrahedron(UINT32 level)
{
if (level == 0)
{
shaderManager.UseStockShader(GLT_SHADER_FLAT_ATTRIBUTES, transformPipeline.GetModelViewProjectionMatrix());
geometry.Draw();
}
else
{
modelViewMatrix.PushMatrix();
modelViewMatrix.Scale(0.5f, 0.5f, 0.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0, 1, 0);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(-0.5f, 0, 0.5f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0.5f, 0, 0.5f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0, 0, -0.7f);
DrawSierpinskiTetrahedron(level - 1);
modelViewMatrix.PopMatrix();
modelViewMatrix.PopMatrix();
}
}
Upvotes: 1