Created
May 9, 2014 20:13
-
-
Save luckyjajj/4a62154d90d3686d9fe7 to your computer and use it in GitHub Desktop.
OpenGL: Banner Modeling and Animation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.cpp | |
// Banner Modeling and Animation | |
// | |
// Created by Lakhveer Jajj on 2013-09-25. | |
// | |
#include <iostream> | |
#include <string> | |
#include <cstdlib> | |
#include <math.h> | |
#include <GLUT/GLUT.h> | |
#include <OpenGL/OpenGL.h> | |
typedef struct Point2D | |
{ | |
double x,y; | |
double nx,ny; | |
double u; | |
} Point2D; | |
#define MAXCONTROLPOINTS 30 | |
#define PI 3.14159265 | |
#define CHARS 20 | |
typedef struct SubdivisionCurve | |
{ | |
int numControlPoints; | |
Point2D controlPoints[MAXCONTROLPOINTS]; | |
int subdivisionSteps; | |
int numCurvePoints; | |
Point2D *curvePoints; | |
} SubivisionCurve; | |
void init(void); | |
void display(void); | |
void keyboardHandler(unsigned char key, int x, int y); | |
Point2D cPosition (double uValue); | |
void computeSubdivisionCurve(SubdivisionCurve *subcurve) ; | |
Point2D getPoint(Point2D *currentPoints, int numCurrentPoints, int j) ; | |
Point2D subdivide(Point2D v1, Point2D v2, Point2D v3, Point2D v4) ; | |
SubdivisionCurve subcurve; | |
Point2D cP1; | |
Point2D cP2; | |
Point2D cP3; | |
GLint windowWidth = 1000; | |
GLint windowHeight = 700; | |
GLint viewportWidth = windowWidth; | |
GLint viewportHeight = windowHeight; | |
GLdouble worldLeft = -500.0; | |
GLdouble worldRight = 500.0; | |
GLdouble worldBottom= -300.0; | |
GLdouble worldTop = 300.0; | |
// Boundaries of world view (wv) window - also called the clip window | |
GLdouble wvLeft = -200.0, wvRight = 200.0, wvBottom = -100.0, wvTop = 100.0; | |
//Real coordinates from mouse clicks | |
GLint m_viewport[4]; | |
GLdouble m_modelview[16]; | |
GLdouble m_projection[16]; | |
GLdouble rx, ry, rz; | |
//Text attributes | |
void *font = GLUT_STROKE_ROMAN; | |
static char message[20]; | |
static int len = (int) strlen(message); | |
//Animation Variblies | |
bool animate = true; | |
Point2D finalPos; | |
Point2D temp[CHARS]; | |
void init(void){ | |
glViewport(0, 0, viewportWidth, viewportHeight); | |
glMatrixMode(GL_PROJECTION); | |
// First set it to the identity matrix | |
glLoadIdentity(); | |
gluOrtho2D(wvLeft, wvRight, wvBottom, wvTop); | |
// Now set up the MODELVIEW matrix | |
glMatrixMode(GL_MODELVIEW); | |
int i; | |
for (i = 0; i <= len; i++){ | |
temp[i] = cPosition((double)(i)/len); | |
printf(""); | |
} | |
} | |
void display(void){ | |
glClear(GL_COLOR_BUFFER_BIT); | |
glLoadIdentity(); | |
glPushMatrix(); | |
//Display moveable control points | |
glColor3f(0, 1, 0); | |
glPointSize(10.0); | |
glBegin(GL_POINTS); | |
glVertex3f(cP1.x, cP1.y,0.0); | |
glVertex3f(cP2.x, cP2.y,0.0); | |
glVertex3f(cP3.x, cP3.y,0.0); | |
glEnd(); | |
//Draws curve from the controll points | |
glColor3f(1, 0, 0); | |
glBegin(GL_LINE_STRIP); | |
int i; | |
for (i=0; i < subcurve.numCurvePoints; i++){ | |
Point2D temp = subcurve.curvePoints[i]; | |
glVertex2f(temp.x, temp.y); | |
} | |
glEnd(); | |
glPopMatrix(); | |
//Draws characters to the line | |
for (i = 0; i <= len; i++){ | |
glColor3f(0, 0, 1); | |
glPushMatrix(); | |
glTranslatef(temp[i].x,temp[i].y+1,0.0); | |
double m = (temp[i].y-temp[i].ny)/ (temp[i].x-temp[i].nx); | |
glRotatef(atan(m)*180/PI,0.0,0.0,1.0); | |
glScalef(0.1,0.1,1.0); | |
glutStrokeCharacter(font, message[i]); | |
glPopMatrix(); | |
} | |
glFlush(); | |
} | |
Point2D cPosition (double uValue){ | |
double totalL; | |
int i; | |
float ox = subcurve.curvePoints[0].x; | |
float oy = subcurve.curvePoints[0].y; | |
for (i=1; i < subcurve.numCurvePoints; i++){ | |
Point2D temp = subcurve.curvePoints[i]; | |
double total = sqrt(pow((temp.x-ox),2)+pow((temp.y-oy),2)); | |
ox = temp.x; | |
oy = temp.y; | |
totalL = totalL +total; | |
} | |
ox = subcurve.curvePoints[0].x; | |
oy = subcurve.curvePoints[0].y; | |
double totalT=0; | |
double lastUVal =0; | |
for (i=1; i < subcurve.numCurvePoints; i++){ | |
Point2D temp = subcurve.curvePoints[i]; | |
double total = sqrt(pow((temp.x-ox),2)+pow((temp.y-oy),2)); | |
totalT = totalT +total; | |
if (uValue >= lastUVal && uValue <= totalT/totalL ){ | |
temp.nx = ox; | |
temp.ny= oy; | |
return temp; | |
} | |
ox = temp.x; | |
oy = temp.y; | |
lastUVal =totalT/totalL; | |
} | |
Point2D blank; | |
return blank; | |
} | |
void mouseHandler(int x, int y){ | |
glGetIntegerv(GL_VIEWPORT, m_viewport); | |
glGetDoublev(GL_MODELVIEW_MATRIX, m_modelview); | |
glGetDoublev(GL_PROJECTION_MATRIX, m_projection); | |
gluUnProject(x, y, 0, m_modelview, m_projection, m_viewport, &rx, &ry, &rz); | |
ry = ry *-1; | |
if (rx >= cP1.x-10 && rx <= cP1.x+10 && ry >= cP1.y-10 && ry <= cP1.y+10){ | |
cP1.x = rx; | |
cP1.y = ry; | |
subcurve.controlPoints[0] = cP1; | |
computeSubdivisionCurve(&subcurve); | |
int i; | |
for (i = 0; i <= len; i++){ | |
temp[i] = cPosition((double)(i)/len); | |
printf(""); | |
} | |
} | |
else if (rx >= cP2.x-10 && rx <= cP2.x+10 && ry >= cP2.y-10 && ry <= cP2.y+10){ | |
cP2.x = rx; | |
cP2.y = ry; | |
subcurve.controlPoints[1] = cP2; | |
computeSubdivisionCurve(&subcurve); | |
int i; | |
for (i = 0; i <= len; i++){ | |
temp[i] = cPosition((double)(i)/len); | |
printf(""); | |
} | |
} | |
else if (rx >= cP3.x-10 && rx <= cP3.x+10 && ry >= cP3.y-10 && ry <= cP3.y+10){ | |
cP3.x = rx; | |
cP3.y = ry; | |
subcurve.controlPoints[2] = cP3; | |
computeSubdivisionCurve(&subcurve); | |
int i; | |
for (i = 0; i <= len; i++){ | |
temp[i] = cPosition((double)(i)/len); | |
printf(""); | |
} | |
} | |
glutPostRedisplay(); | |
} | |
void keyboardHandler(unsigned char key, int x, int y){ | |
switch(key) | |
{ | |
case 'q': | |
case 'Q': | |
case 27: | |
/* Esc, q, or Q key = Quit */ | |
exit(0); | |
break; | |
} | |
glutPostRedisplay(); | |
} | |
int main(int argc, char ** argv){ | |
printf("Enter in text to display: "); | |
char temp[20]; | |
std::cin.getline(temp,20); | |
strlcpy(message,temp,20); | |
len = ((int) strlen(temp))-1; | |
cP1.x = -70; | |
cP1.y = 0; | |
cP2.x = 0; | |
cP2.y = 0; | |
cP3.x = 70; | |
cP3.y = 0; | |
subcurve.controlPoints[0] = cP1; | |
subcurve.controlPoints[1] = cP2; | |
subcurve.controlPoints[2] = cP3; | |
subcurve.numControlPoints = 3; | |
// Set desired number of subdivisionSteps | |
subcurve.subdivisionSteps = 5; | |
computeSubdivisionCurve(&subcurve); | |
glutInit(&argc, (char **)argv); | |
glutInitDisplayMode ( GLUT_SINGLE | GLUT_RGB); | |
//glutInitWindowPosition(100,100); | |
glutInitWindowSize(windowWidth,windowHeight); | |
glutCreateWindow ("Banner Modeling and Animation"); | |
glutDisplayFunc(display); | |
glutKeyboardFunc(keyboardHandler); | |
glutMotionFunc(mouseHandler); | |
init(); | |
glutMainLoop(); | |
return 0; | |
} | |
#define MAXSTEPS 6 | |
// Compute the subdivision curve | |
void computeSubdivisionCurve(SubdivisionCurve *subcurve) | |
{ | |
Point2D *curvePoints[MAXSTEPS]; | |
int numCurrentPoints = subcurve->numControlPoints; | |
int n; | |
Point2D *cur = subcurve->controlPoints; | |
Point2D *sub; | |
if (subcurve->subdivisionSteps > MAXSTEPS) return; | |
subcurve->numCurvePoints = subcurve->numControlPoints; | |
curvePoints[0] = subcurve->controlPoints; | |
for (int i=1; i <= subcurve->subdivisionSteps; i++) | |
{ | |
subcurve->numCurvePoints += subcurve->numCurvePoints - 1; | |
curvePoints[i] = (Point2D *) malloc(subcurve->numCurvePoints * sizeof(Point2D)); | |
} | |
sub = curvePoints[1]; | |
for (int i=0; i < subcurve->subdivisionSteps; i++) | |
{ | |
n = numCurrentPoints-1; | |
for (int j=0; j<n; j++) | |
{ | |
sub[2*j] = cur[j]; | |
sub[2*j+1] = subdivide(getPoint(cur,numCurrentPoints,j-1), | |
getPoint(cur,numCurrentPoints,j), | |
getPoint(cur,numCurrentPoints,j+1), | |
getPoint(cur,numCurrentPoints,j+2)); | |
} | |
sub[2*n]=cur[n]; | |
cur = sub; | |
sub = curvePoints[i+2]; | |
numCurrentPoints += n; | |
} | |
subcurve->curvePoints = curvePoints[subcurve->subdivisionSteps]; | |
} | |
Point2D getPoint(Point2D *currentPoints, int numCurrentPoints, int j) | |
{ | |
int n= numCurrentPoints; | |
if (j>=0 && j<n) return currentPoints[j]; | |
Point2D p0, p1; | |
// boundary cases | |
if (j==-1) | |
{ | |
p0 = currentPoints[0]; | |
p1 = currentPoints[1]; | |
} | |
if (j==n) | |
{ | |
p1 = currentPoints[n-2]; | |
p0 = currentPoints[n-1]; | |
} | |
Point2D linearCombo; | |
linearCombo.x = 2*p0.x + -1 * p1.x; | |
linearCombo.y = 2*p0.y + -1 * p1.y; | |
return linearCombo; | |
} | |
Point2D subdivide(Point2D v1, Point2D v2, Point2D v3, Point2D v4) | |
{ | |
Point2D result; | |
result.x = (9.0*(v2.x+v3.x)-v1.x-v4.x)/16.0; | |
result.y = (9.0*(v2.y+v3.y)-v1.y-v4.y)/16.0; | |
return result; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment