PDA

View Full Version : About sine wave animation



shirleydd
09-12-2010, 06:44 PM
hi, everyone,

I wanna ask a question about the sine wave animation.

I have drawn a rectangle and then I wanna make it move like sine wave. I knew I can use look-up table and interpolation. But I don't know in which function I should add the look-up talbe and interpolation (now I am adding in the timer function)

I am not sure whether I wrote the correct code. Appreciate your advice. Thank you very much!


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>


int nFPS = 60;
float fRotateAngle = 0.f;

void init (void)
{
glClearColor(1.0,0.9,0.9,1.0); //clear color is white
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //uncomment this function if you only want to draw wireframe model
glPointSize(4.0); //point size is 4.0
}

void display (void) // funtion to do all the drawing
{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // put your OpenGL display commands here

//reset openGL transformation matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); //reset transformation matrix to identity

//setup look at transformation
//eye is at: (0,0,2)
//look at center is at :(0,0,0)
//up direction is +y axis
gluLookAt(0.f,0.f,2.f,0.f,0.f,0.f,0.f,1.f,0.f);

glRotatef(fRotateAngle,0.f,1.f,0.f); //rotate the 'I' on Y axis


// draw the triangle strip
glBegin(GL_Line_STRIP);
glColor3f(0.0,1.0,0.0); //set the draw color to green
glVertex3f(-0.6,1.0,0.0);
glColor3f(1.0,0.0,0.0);
glVertex3f(0.6,1.0,0.0);
glVertex3f(0.6,0.6,0.0);
glVertex3f(-0.6,0.6,0.0);
glEnd();

//glFlush();
glutSwapBuffers(); //swap front/back framebuffer to avoid flickering


}

void resize (int w, int h)
{
//reset viewport (drawing screen) size
glViewport(0,0,w,h);
float fAspect=((float)w)/h;

//reset openGL projection matrix (must have, in order to display the "I")
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //replace the current matrix with the identity matrix
gluPerspective(70.f,fAspect,0.001f,30.f); // setup a perspective projection matrix
}

void key(unsigned char key, int x, int y)
{
if (key==27) // hit ESC
{
printf("quit.\n"); //quit "dancing"
exit(0);
}
}

void timer(int v)
{
//setup look-up table


//float sine[91], pi=3.141592653, y;
//for (int i; i<=90;i++)
//{
//sine[i]=sin(pi/180*i);
//y= sine[i] +(sine[i+1]-sine[i])/2;
//}

fRotateAngle +=2.f; //change rotation angles
glutPostRedisplay(); //trigger display function by spending redraw into message queue
glutTimerFunc(1000/nFPS, timer, v); //registers a timer callback to be triggered in a specified number of milliseconds
}

void main(int argc, char** argv)
{
int mode=GLUT_RGB|GLUT_DOUBLE;
glutInitDisplayMode(mode);
glutInitWindowSize (500, 500);
glutInitWindowPosition (400, 100); //the window 'hello UIUC''s position in the screen
glutCreateWindow ((const char*)"Hello UIUC :)");
init(); // setting up user data & OpenGL environment

//set up the call-back functions
glutDisplayFunc(display); //called when drawing
glutReshapeFunc(resize); //called when changing window size
glutKeyboardFunc(key); //called when received keyboard interation
glutTimerFunc(100, timer,nFPS); //a periodic timer. used for updating animation
glutMainLoop(); //start the main message-callback loop

}

ZbuffeR
09-13-2010, 02:12 AM
I knew I can use look-up table and interpolation
For a simple sin() ? Are you coding for a 486 ?

First, make it work as simple as possible, without lut+interpolation.
Then benchmark, then try fancy coding tricks from 1990, then benchmark to verify it was useful (probably not).

mhagain
09-13-2010, 04:41 AM
Benchmarking a lookup table versus a sin function I get the lookup (with 2048 entries) being over 50 times faster, even on a modern CPU. This is a measurement of times for approx 10,000,000 sin calculations, and may admittedly be biased towards the lookup as the table contents will most likely be in, and stay in, cache for the duration of the exercise.

But all the same, it does highlight the fact that you should benchmark your own app and determine which is best for your own uses, bearing in mind that the lookup table will give a coarser scale which may be inappropriate, and that in the longer term using a fragment shader and calculating the sin per-fragment may be the best way to go (a sine wave doesn't interpolate well).

ZbuffeR
09-13-2010, 06:03 AM
Does your bench times the lookup+interpolate or only lookup ?
Then it depends if you app is CPU limited or GPU limited, and as it takes caches size from the cpu as well which may or may not hamper other computations.

mhagain
09-13-2010, 08:14 AM
Both with and without. With was slightly slower than without, but still in the same ballpark.

In any event I suspect that my lookup results are completely invalid because of the data being in CPU cache. To more accurately simulate a real-world usage one would need to (1) do a few calculations or lookups, (2) store these somewhere for later use, (3) do a batch of other work, and (4) repeat enough times to make the results statistically valid.

What's more, like I said, sine is not a linear function so interpolation can give wildly inaccurate results; e.g. a linear interpolation path between two peaks in the wave would be a straight line.