February 16, 2014

I MADE FLAPPY BIRD EVEN FLAPPIER

This is kind of a semester long project for my rendering class.  The first assignment was to build a randomly generated maze, display it on the screen, and let the user press keys to navigate in the array, leaving a trail behind wherever they went.  I used a recursive backtracking method and it worked pretty well.

The second assignment (this), was to make it 3D and display 3D objects, using hierarchical transformations.  Additionally, we had to build a robot that navigated the maze and moved along the way.

My roommate is obsessed with Flappy Bird (I think he got a high score of 40) and I thought of him when implementing this.  My flappy bird is just as awkward as the original:


Except mine is animated and moves and stuff.  The pupils go up and down as you move, the wings flap awkwardly, and the lower lip gapes open and closed as you move around.

Until I figure out CamStudio, I'm stuck with this awful animation (I swear it looks better in real life) but it gives a gist of the personality of Flappy Bird I've managed to capture.



Not posting code here since class assignment, but it was fun to work on.  Haven't implemented collision detection yet, but it would be cool if I did.  Flappy Bird would rotate downwards and then plummet at a 180 degree angle.

February 11, 2014

OpenGL - Drawing a cube

Started playing around with 3D in preparation for my upcoming lab assignment.  I always like to start small, so I tried making a simple cube.  Instead of hardcoding values in for the square, I noticed that vertices follow a simple pattern, which I'm too lazy to describe here but I realized it was codeable.  So I did.  Here is my "draw a cube" program:

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>

void display();
void specialKeys();
double rotate_y=0;
double rotate_x=0;

void display(){

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  // Rotate when user changes rotate_x and rotate_y
  glRotatef( rotate_x, 1.0, 0.0, 0.0 );
  glRotatef( rotate_y, 0.0, 1.0, 0.0 );

  float c = 0.5;
  glColor3f( 1.0, 0.0, 0.0 );
  glBegin(GL_TRIANGLES);

  int a[3] = {0, 0, 0,};
  int b[12] = { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1 };
  for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++)
{
int k = 0;
while (k < 12)
{
if (k % 2 == 0) {
glColor3f( b[k], b[k], b[k] );
}

a[i] = j;
a[(i + 1) % 3] = b[k++];
a[(i + 2) % 3] = b[k++];

float x = a[0] == 0 ? -1 : 1;
float y = a[1] == 0 ? -1 : 1;
float z = a[2] == 0 ? -1 : 1;

glVertex3f(c * x, c * y, c * z);
}
}
  }
  glEnd();

  glFlush();
  glutSwapBuffers();

}

// ----------------------------------------------------------
// specialKeys() Callback Function
// ----------------------------------------------------------
void specialKeys( int key, int x, int y ) {

  if (key == GLUT_KEY_RIGHT)
    rotate_y += 5;
  else if (key == GLUT_KEY_LEFT)
    rotate_y -= 5;
  else if (key == GLUT_KEY_UP)
    rotate_x += 5;
  else if (key == GLUT_KEY_DOWN)
    rotate_x -= 5;

  //  Request display update
  glutPostRedisplay();

}

int main(int argc, char* argv[]){

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutCreateWindow("Awesome Cube");
  glEnable(GL_DEPTH_TEST);
  glutDisplayFunc(display);
  glutSpecialFunc(specialKeys);
  glutMainLoop();
  return 0;

}

Some of the base code I stole somewhere from online but I coded everything in the display() function except for the two glRotatef calls.

Here is my cube:

Unfortunately I'm not sure I can use that algorithm for my lab if I wanna use VBO's for extra credit..

My next goal is to have two cubes (like another smaller cube on top of this cube) and be able to apply transformations to the base cube (moving the smaller cube) and the smaller cube (moving only the smaller cube).  Start small, start small.  Eventually I'm going to code up a T rex made entirely of square and rectangles.

Simplest VBO Program

For our class assignment we can use OpenGL VBO's for extra credit.  They're a lot more difficult to set up than glBegin() and glEnd() but they're supposed to be a lot more efficient.

Scouring the web for simple examples never really turns up any simple examples.. people always have to add fancy stuff.  Which is cool, except if I don't understand the basics, how am I going to understand all the more complicated things?

Here is an OpenGL program, using VBO's, that outputs a single point.  That's it.  Caused me a lot of trouble.

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glext.h>

float vertices[] = {0.0, 0.0};
GLubyte indices[1]= {0};

GLuint vboHandle[1];
GLuint indexVBO;
void InitVBO() {
  indices[0] = 0;

  glGenBuffers(1, vboHandle); // (1)
  glBindBuffer(GL_ARRAY_BUFFER, vboHandle[0]); // (2)
  glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2, vertices, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  glGenBuffers(1, &indexVBO);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte), indices, GL_STATIC_DRAW);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void display()
{
  glClear(GL_COLOR_BUFFER_BIT);
  glColor4f(1,1,0,1);
  glPointSize(10);

  glBindBuffer(GL_ARRAY_BUFFER, vboHandle[0]);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(2, GL_FLOAT, 0, (char*)NULL + 0);
  glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, (char*)NULL + 0);

  glDisableClientState(GL_VERTEX_ARRAY);

  glFlush();
}


///////////////////////////////////////////////////////////////

int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutCreateWindow("simple");
  glewInit();
  glutDisplayFunc(display);

  InitVBO();
  glutMainLoop();
}

Don't fully understand any of it yet.  But hopefully I will soon.

The much anticipated image:

BAM.

Not quite worth it for all the trouble needed to hook it up.. but I'm sure for more objects it'll scale a lot better.

February 10, 2014

Polar Graphs - Part 6

Updated my code so you can specify an offset in the position.

In drawAngle method in main.cpp:
std::tuple<float, float> positions = valueOfOffsets(a);
float x = r * cos(angle) + std::get<0>(positions);
float y = r * sin(angle) + std::get<1>(positions);

Added this function declaration in Parser.h:
std::tuple<float, float> valueOfOffsets(char source[]);

And added this code in Parser.cpp, although it could use a little refactoring:
float GetDecimal(char source[], int i) {
float value = 0;
bool isNeg = source[i] == '-';

if (isNeg) i++;

while (source[i] >= '0' && source[i] <= '9') {
value *= 10;
value += (float)(source[i] - '0');
i++;
}

float trailing = 0.0;
int placeHolder = 10;
if (source[i] == '.') {
remove(source, 1);
while (source[i] >= '0' && source[i] <= '9') {
float digit = (float)(source[i] - '0') / placeHolder;
placeHolder *= 10;
trailing += digit;
i++;
}
}
return isNeg ? -1 * (value + trailing) : value + trailing;
}

float GetX(char source[], int i) {
while (source[i] != '\0' && source[i] != 'x') {
i++;
}
i += 2;

return GetDecimal(source, i);
}

float GetY(char source[], int i) {
while (source[i] != '\0' && source[i] != 'y') {
i++;
}
i += 2;

return GetDecimal(source, i);
}

std::tuple<float, float> valueOfOffsets(char source[]) {
int i = 0;
float x = GetX(source, i);
float y = GetY(source, i);

std::tuple<float, float> positions (x, y);
return positions;
}

So I'm getting to the main point of this project, I wanna start making images with polar coordinates because why not

Unfortunately I haven't made the ranges parameterizable so I can't draw eyebrows or smiley faces yet or anything

Here's Guy Whistling:

February 04, 2014

Polar graphs - Part 5

Refactoring my code was actually the most frustrating part of this project so far.. I'm used to being able to quickly create files in C# and having the IDE take care of all the linking for me.  Before, I'd vaguely heard of header and source files in C++ but never had to deal with them.. Well, now I have.  Such a freaking headache but I've got a lot of my files finally separated.  My goal is to only have OpenGL related functions in my main.cpp, it's almost getting there.

Here are all of my files:

Main.cpp

constants.h

Parameters.h

Equations.h

Equations.cpp

ColorTriple.h

ColorTriple.cpp

ColorMap.h

ColorMap.cpp

Parser.h

Parser.cpp

Some things I learned along the way:
- Never put using statements in your header files
- It's okay to put #include though
- If you have a single variable in your header file, put extern in front of it (to indicate it's declared elsewhere) and in the .cpp file that's where you declare it (and you don't use extern there).  This caused me a lot of trouble
- Map does not keep ordering.  I guess I just assumed it did.  So I was surprised when my colors all came out looking different
- Use #pragma once in header files to make life easier.  I don't know how guards work as a result
- printf("%s") for strings doesn't work, because %s only works for char*.  Use s.c_str() instead.