Results 1 to 6 of 6

Thread: Deforming a 3d Cube

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    9

    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. #2
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    9
    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);
     
    	glDrawArrays(GL_QUADS, 0, 24);
     
    	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);
     
    	glDrawArrays(GL_QUADS, 0, 24);
     
    	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);
     
    	glDrawArrays(GL_QUADS, 0, 24);
     
    	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);
    		glLoadIdentity();
    		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. #3
    Newbie Frequent Contributor
    Join Date
    Mar 2016
    Posts
    896
    #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. #4
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    9
    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. #5
    Newbie Frequent Contributor
    Join Date
    Mar 2016
    Posts
    896
    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. #6
    Junior Member Newbie
    Join Date
    Sep 2014
    Posts
    9
    Quote Originally Posted by carsten neumann View Post
    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!

Similar Threads

  1. Computing Tangents after deforming mesh in shader
    By Moetman in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 07-12-2017, 02:02 AM
  2. Cube Map without using OpenGL's Cube Mapping
    By someoney in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 02-10-2010, 01:05 PM
  3. Deforming a mesh with a skeletal structure?
    By redarrow in forum OpenGL: General
    Replies: 2
    Last Post: 04-28-2006, 08:38 AM
  4. display a cube inside another bigger cube
    By jyoung77 in forum OpenGL: Advanced Coding
    Replies: 3
    Last Post: 05-08-2003, 06:12 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean