# Thread: Deforming a 3d Cube

1. ## Deforming a 3d Cube

Hey guys,

I'm trying to draw a 3D cube and then deform it using matrices. I've managed
to draw the cube, get it rotating, and even shear it. But I want to bend, twist,
and taper the object.

I know the matrix operations needed to do these, but I can't figure out how
to execute it in code. My algorithm for twisting is
 cos(theta(y)) 0 sin(theta(y)) 0 0 1 0 0 -sin(theta(y)) 0 cos(theta(y)) 0 0 0 0 1

times the vector containing x, y, z, w.

However I can't figure out how to get the current vector for x, y, z, w
so that I can get the y value. I am assuming that I just use glMultMatrixf
to multiply the current matrix by the matrix mentioned about, right?
I used an array of vertices and glVertexPointer to feed these vertices
into glDrawArrays.

2. So I've figured out how to do it, I think. But I seem to have run into a problem.

Here is my program:

Code :
```#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include<glm/glm.hpp>
#include <iostream>

#define WIDTH 600
#define HEIGHT 480
#define TIME_BETWEEN_TRANSFORMATIONS  7

using std::cerr;
using std::cout;
using glm::mat4;
using glm::vec4;

GLFWwindow* initializeWindow(const int width, const int height)
{
//Initialize GLFW, and return NULL if glfwInit fails
if (!glfwInit())
{
cerr << "Failed to initialize GLFW.\n";
return NULL;
}

//Sets glfwWindowHint vaules
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing

GLFWwindow* window = glfwCreateWindow(width, height, "Assignment 1", NULL, NULL);

if (window == NULL)
{
cerr << "Failed to create window.\n";
return NULL;
}

glfwMakeContextCurrent(window);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
return window;

}

void drawCube()
{
GLfloat vertices[] =
{
-1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1,
1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1,
-1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1,
-1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1,
-1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1
};

GLfloat colors[] =
{
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 0.2f, 1.f, 0.6f, 0.f, 1.f, 1.f, 0.f, 0.9f, 0.1f,
0.f, 0.f, 0.f, 0.1f, 0.9f, 1.f, 1.f, 1.f, 0.f, 0.5f, 0.6f, 0.f,
0.6f, 0.5f, 0.6f, 0.8f, 0.9f, 0.2f, 0.3f, 0.2f, 1.f, 0.f, 0.8f, 0.f,
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 1.f, 1.f, 1.f, 1.f, 0.7f, 1.f, 0.f, 0.9f, 0.1f
};

static float rotation = 0;

glRotatef(rotation, 0.1f, 1.0f, 0.3f);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
rotation += 0.15f;
}

int transformationType(float currentTime, float rotateTime, float shearTime, float taperTime, float twistTime, float bendTime)
{
if (currentTime < rotateTime) return 0;
if (currentTime < shearTime) return 1;
if (currentTime < taperTime) return 2;
if (currentTime < twistTime) return 3;
if (currentTime < bendTime) return 4;
else return 0;
}

void drawShearedCube()
{
GLfloat vertices[] =
{
-1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1,
1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1,
-1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1,
-1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1,
-1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1,
-1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1
};

GLfloat colors[] =
{
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 0.2f, 1.f, 0.6f, 0.f, 1.f, 1.f, 0.f, 0.9f, 0.1f,
0.f, 0.f, 0.f, 0.1f, 0.9f, 1.f, 1.f, 1.f, 0.f, 0.5f, 0.6f, 0.f,
0.6f, 0.5f, 0.6f, 0.8f, 0.9f, 0.2f, 0.3f, 0.2f, 1.f, 0.f, 0.8f, 0.f,
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 1.f, 1.f, 1.f, 1.f, 0.7f, 1.f, 0.f, 0.9f, 0.1f
};

static float rotation = 0;

glRotatef(rotation, 0.1f, 1.0f, 0.3f);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);

float m[] = {
1, 0, 0, 0,
.3, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
glMultMatrixf(m);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
rotation += 0.1f;
}

void drawTwistedCube()
{
GLfloat vertices[] =
{
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f
};

GLfloat colors[] =
{
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 0.2f, 1.f, 0.6f, 0.f, 1.f, 1.f, 0.f, 0.9f, 0.1f,
0.f, 0.f, 0.f, 0.1f, 0.9f, 1.f, 1.f, 1.f, 0.f, 0.5f, 0.6f, 0.f,
0.6f, 0.5f, 0.6f, 0.8f, 0.9f, 0.2f, 0.3f, 0.2f, 1.f, 0.f, 0.8f, 0.f,
0.f, 0.5f, 0.2f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.f, 0.5f, 0.3f, 0.6f,
1.f, 0.5f, 0.3f, 1.f, 1.f, 1.f, 1.f, 0.7f, 1.f, 0.f, 0.9f, 0.1f
};

int i = 0;
while (i < 71)
{
vec4 tempVector = vec4(vertices[i], vertices[i + 1], vertices[i + 2], vertices[i + 3]);
mat4 twistMatrix = mat4(2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
//mat4 twistMatrix = mat4(cos(.2*vertices[i + 1]), 0, sin(.2*vertices[i + 1]), 0, 0, 1, 0, 0, -sin(.2*vertices[i + 1]),
//0, cos(.2*vertices[i + 1]), 0, 0, 0, 0, 1);

tempVector = twistMatrix * tempVector;

vertices[i] = tempVector[0];
vertices[i + 1] = tempVector[1];
vertices[i + 2] = tempVector[2];
vertices[i + 3] = tempVector[3];

i = i + 4;
}

cout << "START";
for (int i = 0; i < 72; i++)
{
cout << vertices[i];
if ((i % 4) == 3) cout << "\n";
}

static float rotation = 0;

glRotatef(rotation, 0.1f, 1.0f, 0.3f);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, vertices);
glColorPointer(3, GL_FLOAT, 0, colors);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
rotation += 0.1f;
}

void display(GLFWwindow* window)
{
//Sets up time variables
float startTime, rotateTime, shearTime, taperTime, twistTime, bendTime;
startTime = glfwGetTime();
rotateTime = startTime + TIME_BETWEEN_TRANSFORMATIONS;
shearTime = rotateTime + TIME_BETWEEN_TRANSFORMATIONS;
taperTime = shearTime + TIME_BETWEEN_TRANSFORMATIONS;
twistTime = taperTime + TIME_BETWEEN_TRANSFORMATIONS;
bendTime = twistTime + TIME_BETWEEN_TRANSFORMATIONS;

float translateValue = 0;

while (!glfwWindowShouldClose(window))
{
// Scale to window size
GLint windowWidth, windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
glViewport(0, 0, windowWidth, windowHeight);

// Draw stuff
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION_MATRIX);
gluPerspective(70, (double)windowWidth / (double)windowHeight, 0.1, 100);

glMatrixMode(GL_MODELVIEW_MATRIX);
glTranslatef(0, 0, translateValue);

switch (transformationType(glfwGetTime(), rotateTime, shearTime, taperTime, twistTime, bendTime))
{
case 0:
drawCube();
break;
case 1:
drawTwistedCube();
break;
case 2:
drawCube();
break;
case 3:
drawCube();
break;
case 4:
drawTwistedCube();
break;
}

// Update Screen
glfwSwapBuffers(window);

// Check for any input, or window movement
glfwPollEvents();

if (translateValue > -5)
translateValue -= 0.001f;
}
}

int main()
{
GLFWwindow* window = initializeWindow(WIDTH, HEIGHT);
if (window != NULL)
{
display(window);
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}```

when I run drawTwistedCube() which, as it stands now should just scale the cube by a factor of 2,
it leaves 2 sides un-scaled and I can't figure out why. Can anyone help me figure out why this is?

Thanks!

3. #faces * #vertices per face * #floats per vertex = 6 * 4 * 4 = 96
In other words: your loop bounds are too small and you are not transforming all positions.

4. Ooooh okay. Thanks. I turned the matrix into 4 points per vertex instead of 3 and forgot to increase the size of the loop accordingly.
One thing I don't understand though, is the value placed in:

Code :
`glDrawArrays(GL_QUADS, 0, 24);`

I tried messing around with the value placed as the third argument and it seemed
to make little difference unless the number I provided was less than 24. But when
I changed my vertices to contain 4 numbers instead of 3, 24 was still sufficient.
Can anyone explain that to me? I tried reading the documentation and was still
confused afterwards.

5. Your cube has 24 vertices, independent of how many components the vectors to specify the positions have. Using a number larger than 24 means you are reading off the end of your arrays and just happen to be lucky that it does not crash/render garbage/melt your computer (the latter is a rare case though ) - still it's a bug to tell OpenGL to render more vertices than you have data available for.

6. Originally Posted by carsten neumann
Your cube has 24 vertices, independent of how many components the vectors to specify the positions have. Using a number larger than 24 means you are reading off the end of your arrays and just happen to be lucky that it does not crash/render garbage/melt your computer (the latter is a rare case though ) - still it's a bug to tell OpenGL to render more vertices than you have data available for.
Ooh, that makes sense. Thanks!

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•