在不同位置多次绘制 GLBatch
Posted
技术标签:
【中文标题】在不同位置多次绘制 GLBatch【英文标题】:Drawing GLBatch multiple times at different locations 【发布时间】:2018-04-23 15:22:52 【问题描述】:我正在使用 GLTools 库中的 GLBatch 来绘制四面体。我想在不同的位置多次绘制四面体以绘制Sierpinski-Tetrahedron。对于四面体的一个实例,创建几何图形和绘制圆锥体效果很好,但我想在不同的位置多次绘制四面体。多次调用geometry.Draw()
(使用不同的模型视图矩阵)不起作用。圆锥仍然只绘制一次。
如何多次绘制 GLBatch?
这是我的代码:
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();
更新:
执行以下操作不会缩放四面体。
modelViewMatrix.PushMatrix();
modelViewMatrix.Scale(1000, 1000, 1000);
geometry.Draw();
modelViewMatrix.PopMatrix();
【问题讨论】:
原始矩阵是否会影响网格的绘制? 看起来不像。请参阅问题的编辑。 那么,矩阵是如何从modelViewMatrix
进入你的着色器的呢?
我添加了两个我认为着色器已初始化的函数。我只是在学习 OpenGL 并从代码框架开始。它也使用 GLUT。
就是这样!谢谢你。我认为这只需要进行一次初始化。如果它不是最好的解决方案,那也不是问题,因为我还处于学习的开始阶段,其他概念现在更重要。这对我帮助很大。
【参考方案1】:
GLMatrixStack 是一个提供矩阵堆栈和对堆栈顶部矩阵的操作的类。
GLShaderManager 类可以加载着色器并处理着色器的统一变量的设置。
着色器程序通过模型视图矩阵转换网格的顶点坐标。这导致可以将 mseh 渲染到场景中具有不同方向的不同位置。
如果模型视图矩阵发生变化,则必须在着色器程序中将其设置为相应的统一变量,以使更改生效。
这可以通过在绘制网格之前调用GLShaderManager::UseStockShader
来完成。
像这样调整你的代码:
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();
【讨论】:
以上是关于在不同位置多次绘制 GLBatch的主要内容,如果未能解决你的问题,请参考以下文章