# 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.

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

Here is my program:

``````
#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.
";
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.
";
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 << "
";
}

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!

#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.

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:

``````