PDA

View Full Version : Cannot generate window to view fractal animation



ibarra1988
04-12-2010, 02:57 PM
I'm taking an intro course into computer graphics and our first lab has us using opengl and programming in C. I am not experienced in either so this is a learning experience for me. The professor gave us a starter program and then gave us instructions on what to fix and add to the program. I can't link to the starter program but I found one that is exactly the same from a few years ago here: http://www.cse.ohio-state.edu/~raghu/teaching/CSE581/labs/lab1/main.cpp One of the things I can't figure out how to do is pre-compute all frames of the fractal animation once and store the entire animation in main memory. I think my inability to accomplish this is why the code does not even generate a window. Any advice would help. Oh and he is requiring that we run the program on Microsoft Visual Studio 2008 since that is what supplied by the graphics lab.

Here is what I have so far: (sorry if it is long I don't write in forums much and don't know how to condense it.)

#include <windows.h>
#include <winbase.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <stdio.h>
#include <math.h> // Trig functions
#include <string.h> // Memory functions such as memset

#define WIDTH 512
#define HEIGHT 512
#define NFRAMES 48

const float PI=3.14159265358979;

float XPoint(float,float, float,float, float,float);
float YPoint(float,float, float,float, float,float);
void fractal(float,float,int,const float);

unsigned char allFrame[NFRAMES][WIDTH * HEIGHT * 3];
unsigned char currentFrame[WIDTH * HEIGHT * 3];

void display()
{
glClear(GL_COLOR_BUFFER_BIT);


for (unsigned int i = 0; i < NFRAMES; i++)
{

memset(allFrame[i], 0, WIDTH * HEIGHT);
//fractal(0,0,20,PI*i/(NFRAMES * 0.5));

glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, allFrame[i]);
Sleep(25);
glFlush();


}
}

void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN){

glClear(GL_COLOR_BUFFER_BIT);
//cycle through animation
for (unsigned int i = 0; i < NFRAMES; i++) {
glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, allFrame[i]);
Sleep(25);
glFlush();
}
}

}

void keyboard(unsigned char key, int x, int y)
{
//variable to iterate through frames
int frames = NFRAMES;

//move back a frame
if (key == 'd' || key == 'D'){
if (frames == 0){
frames = 47;
} else {
frames--;
}

glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, allFrame[frames]);
glFlush();

} else if (key == 'f' || key == 'F'){
// move forward a frame
if (frames >= 47){
frames = 0;
} else {
frames++;
}
glDrawPixels(WIDTH, HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, allFrame[frames]);
glFlush();

} else if (key == 's' || key == 'S'){
//save img to ppm file

int nx = WIDTH;
int ny = HEIGHT;

FILE *stream;
stream = fopen("out.ppm", "wb" );
fprintf( stream, "P6\n%d %d\n255\n", nx, ny );

for( int iy = 0; iy < ny; iy++) {
for( int ix = 0; ix < nx; ix++ ) {
fwrite(allFrame[frames] + (iy * ny + ix) * 3, 1, 3, stream);
}
}
}

}



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

//this may causing my problem. I don't know how to implement storing each frame into memory
// or how I should iterate through an array C since everything seems to use pointers.
for (unsigned int i = 0; i < NFRAMES; i++) {
glClearColor(1.0, 1.0, 1.0, 1.0);
fractal(0,0,20,PI*i/((int)allFrame[i] * 0.5));

}

glutInit(&amp;argc, argv);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Fractal Browser");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);

glutMainLoop();

return 0;
}

float XPoint(float xc,float yc, float theta,float scale, float x,float y){
return ((x*cos(theta)-y*sin(theta))*scale+xc);
}

float YPoint(float xc,float yc, float theta,float scale, float x,float y){
return ((x*sin(theta)+y*cos(theta))*scale+yc);
}

void fractal(float x, float y, int depth, const float ang) {
if (depth==0) {

int xc,yc;

xc = int( (x-(-2)) * WIDTH/4. );

if (xc < 0) {
xc = 0;
} else if ( xc > WIDTH) {
xc = WIDTH - 1;
}

yc = int( (y-(-2)) * HEIGHT/4. );

if (yc < 0) {
yc = 0;
} else if ( yc > HEIGHT) {
yc = HEIGHT - 1;
}

int location = (WIDTH * yc + xc)*3;

currentFrame[location] = 204;
currentFrame[location +1] = 51;
currentFrame[location+2] = 153;

} else {
fractal(XPoint(1,0,0+ang,.70710678,x,y),YPoint(1,0 ,0+ang,.70710678,x,y),depth-1,ang);
fractal(XPoint(-1,0,0-ang,.70710678,x,y),YPoint(-1,0,0-ang,.70710678,x,y),depth-1,ang);
}
}

ibarra1988
04-12-2010, 03:00 PM
This is the instruction that is giving me trouble in more detail:

The speed bottleneck of the starter program is computing each frame of the fractal's animation on-the-fly whenever we need to refresh the GLUT window. To overcome this bottleneck we can pre-compute all frames of the fractal animation once and store the entire animation in main memory. So, whenever we want to see the animation, we simply pay the cost of copying the frames one at a time to the hardware framebuffer without having to re-compute the fractal at all.
Replace the memory buffer oneFrame to a memory buffer that can hold all frames of the animation, for example:
unsigned char allFrames[NFRAMES][WIDTH * HEIGHT].
Do NOT call the function fractal after you have pre-computed and stored in main memory all the frames of the fractal's animation.
To display, index to the frame you want to display and use glDrawPixels to display the frame.
You should notice a considerable speedup in your program's response time.