Hi forum,
I am trying to update an old opengl code to the modern opengl one and I am not getting the expected output. I believe that I am confused with the matrix manipulation . Please check the old code snippet:
void drawHilbertCurve(float x, float y, std::string lrep)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
/*
browse through the grammar of the hilbert curve that is generated
for a number of iteration
*/
for(std::string::iterator it = lrep.begin(); it != lrep.end(); it++)
{
if(*it == 'F')
{
//define the color of the primitive to be drawn
glColor4f(0.5f, 1.0f, 0.0f, 1.0f);
//define the line width
glLineWidth(4.0f);
//define the vertex array
GLfloat vertices[] = {x, y, x + LINE_LENGTH, y};
//the following fucked up every thing
//GLfloat vertices[] = {x, y, x , y + LINE_LENGTH };
//increment the x - position
x = x + LINE_LENGTH;
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_LINES, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
}
if(*it == '-' || *it == '+')
{
glTranslatef(x, y, 0.0f);
x = 0.0f;
y = 0.0f;
float angle = ((*it == '-') ? 90.0f : -90.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
}
}
glPopMatrix();
}
The corresponding code in modern opengl as follows:
void Hilbert2DScene::populateHilbertLSystem(const std::string &LString)
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
//the vertex to start from
glm::vec3 p1(x,y,0.0);
mVertices.push_back(p1);
glm::vec3 p2;
for(std::string::const_iterator it = LString.begin(); it != LString.end();it++)
{
if(*it == 'F')
{
p2.x += 1.0;
mVertices.push_back(p2);
}
if(*it == '-' || *it == '+')
{
glm::mat4 trans = glm::translate(glm::mat4(1.0),p2);
x = 0.0f;
y = 0.0f;
float angle = ((*it == '-') ? 90.0f : -90.0f);
mHilbertOrientation = glm::rotate(trans,glm::radians(angle),glm::vec3(0.0,0.0,1.0));
}
}
//normalize the inserted value inside the vector
//normalize the points data
unsigned long N = 1 << mIteration;
for(std::vector<glm::vec3>::iterator it = mVertices.begin(), itend = mVertices.end(); it != itend;++it)
{
(*it).x /= (N - 1);
(*it).y /= (N - 1);
(*it).z /= 0.5;
}
}
void Hilbert2DScene::render()
{
if(!mInitialized)
return;
mShader->Use();
GL_CHECK_ERRORS;
//allocate the buffer if the buffer is not allocated yet
if(!mIsBufferAllocated)
{
populateHilbertLSystem(hilbertWithLSystem(mIteration));
//specify the amount of storage we want to use for the buffer
/*
* 1st - the target the buffer I want to allocate storage for is bound to
* 2nd - how big the buffer should be
* 3rd - pointer to some initial data for the buffer
* */
glBufferData(GL_ARRAY_BUFFER,sizeof(glm::vec3) * mVertices.size(),&mVertices[0],GL_STATIC_DRAW);
mIsBufferAllocated = true;
mShowPoints = getNumberOfPointsForIteration(mIteration,mDim);
static const GLfloat color[] = {0.0f,0.0f,0.0f,1.0f};
static const GLfloat depth = 1.0f;
glClearBufferfv(GL_COLOR,0,color);
glClearBufferfv(GL_DEPTH,0,&depth);
//draw stuff
//transfer the scene along the z-axis
glm::mat4 T = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f,mDist));
//centralize the whole scene
glm::mat4 centralizeTranslation = glm::translate(T,glm::vec3(-0.5,-0.5,-0.5));
centralizeTranslation = centralizeTranslation * mHilbertOrientation;
//the rotation matrix along X concatenated with the translation matrix
glm::mat4 Rx = glm::rotate(centralizeTranslation, glm::radians(static_cast<float>(mRX)),glm::vec3(1.0f,0.0f,0.0f));
//rotation matrix along Y is concatenated with the rotation matrix along X
glm::mat4 MV = glm::rotate(Rx,glm::radians(static_cast<float>(mRY)),glm::vec3(0.0f,1.0f,0.0f));
mModelViewMatrix = mProjectionMatrix * MV;
/*
* Bind the vertex array object and vertex buffer object
* */
glBindVertexArray(mVaoID);
/*
* Now bind it to the context using the GL_ARRAY_BUFFER binding point
* */
glBindBuffer(GL_ARRAY_BUFFER,mVboVerticesID);
/*
* Tell OpenGL to use the data in the buffer to fill the vertex attribute rather than
* using the data we give it using one of the functions as glVertexAttrib*() functions
* */
glEnableVertexAttribArray((GLuint)0);
//set the uniform matrix value that will be passed to the shader
glUniformMatrix4fv(mShader->getUniform("MVP"),1,GL_FALSE,glm::value_ptr(mModelViewMatrix));
glUniform4fv(mShader->getUniform("modelColor"),1,glm::value_ptr(glm::vec4(1.0,1.0,0.0,1.0)));
if(mShowPoints < getNumberOfPointsForIteration(mIteration,mDim))
++mShowPoints;
/*
* OpenGL draw command
* Sends vertices to the OpenGL pipeline
*
* 1st - what type of graphics primitive we want to render
* 2nd -
* 3rd - the number of vertices we want to render
* */
glDrawArrays(GL_LINE_STRIP,0,mShowPoints);
glBindBuffer(GL_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
GL_CHECK_ERRORS;
mShader->UnUse();
}
Please note that the hilbertWithLSystem() is just generating a pool of the characters represented as a string. If I include the mHilbertOrientation into the render function I see blank and if I do not include it I just a line which in either case is not the expected output. I am supposed to get a hilbert curve here for a certain number of iteration. I gues I am having trouble to map the glTranslate or glRotate function . What do you think ?
Some references would be of great help.
Thanks