Author Topic: Transition demo source code  (Read 7807 times)

0 Members and 1 Guest are viewing this topic.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Transition demo source code
« on: April 07, 2008 »
Here's the source of my transition demo.  Project file is for VS2008, but it should build pretty much anywhere.
Enjoy,

Jim
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: Transition demo source code
« Reply #1 on: April 08, 2008 »
there was far more to this than i first thought,

as always cheers jim for an insight into your code very handy k+.
Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #2 on: January 22, 2009 »
 :bfuck2:

Hi guys. I started to play with this code little bit and added mp3 playback and tried to to control the drawing like this (check the two for loops):

Code: [Select]
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg )
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;

case WM_ERASEBKGND:
return 1;

case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}

return 0;
}


/*void ogl_scale(void)
{
HDC dc;
GLenum err;

err = glGetError();
if (err != GL_NO_ERROR)
{
char tmp[256];
sprintf(tmp, "GLERROR %08X %d\n", err, err);
OutputDebugString(tmp);
}
glScalef(0.1f,0.1f,0.1f);
ogl_draw();
}
*/
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------------------------------------------
static char GLSampleClass[32] = "GLHelixTransitionClass";

int WINAPI WinMain(HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow)
{
WNDCLASS wc;
int style, exstyle;
RECT rect;

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = this_inst;
wc.hIcon = LoadIcon(NULL, (LPCSTR)IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = GLSampleClass;
RegisterClass(&wc);

style = WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION;
exstyle = WS_EX_APPWINDOW;
gameWindow = CreateWindowEx(
0,
GLSampleClass, // class
"Helix",
style,
CW_USEDEFAULT,CW_USEDEFAULT, // init. x,y pos
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL, // parent window
NULL, // menu handle
this_inst, // program handle
NULL // create parms
);

GetWindowRect(gameWindow, &rect);
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
SetWindowPos(gameWindow, NULL, 0,0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE);

ShowWindow(gameWindow, cmdshow);
UpdateWindow(gameWindow);

if (ogl_init() == 0)
{
MessageBox(gameWindow, "Failed Initialising OpenGL", "Failed", MB_OK);
return 0;
}

init_sprite_engine(gameWindow);

init();

quit = 0;
do
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0, PM_NOREMOVE))
{
if (GetMessage(&msg,NULL,0,0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
quit = 1;
break;
}
}

if (!IsPlaying)
{
    playmusic();
}

int i;

for (i=0; i<181; i++)
{
ogl_draw();
ogl_flip();
}

GLfloat j;

for (j=0.999f; j>0.0f;j-=0.001f)
{

glScalef(j,j,j);
ogl_draw();
}

} while (!quit);

ogl_shutdown();

return 0;
}

So, there is a problem that the picture doesn't scale to smaller :/ I tried to make decreasing for loop and put that value to glScalef's attributes, but nothing happens...when I put scaling to first for loop, it scaled nicely and showed me smaller picture. So what I want to do is: Spin the the picture 1 time and then stop it (I tweaked the for loop to make it stop nicely after flipping) and when the image is halted, scale it to eternity :D...but something is bugging this code and I don't know what it is. If somebody could give me hint I would be glad :)

- Kypho the beginner
« Last Edit: January 22, 2009 by kypho »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Transition demo source code
« Reply #3 on: January 22, 2009 »
Yes, the problem is that glScale/glRotate/glTranslate don't work just on their own.  What they do is update the currently active transformation matrix (the one set active by glMatrixMode).  After you've set the glScale, ogl_draw comes along and overwrites its effects.
The bit you want to change is at the start of ogl_draw.
Code: [Select]
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-5000);
glRotatef(c,0,0,1);
You should add your glScale after the glRotate.

btw, since you're not calling ogl_draw/ogl_flip inside the GetMessage loop any more, your app will eventually become unresponsive and crash.  You need to pump (Get/Dispatch) messages.
One way you might fix this is to add a parameter to ogl_draw which is the scale, and have two states.  One state is called 'rotating' the other called 'scaling'.

Jim
Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #4 on: January 25, 2009 »
Huh, I cannot get working still :(

I made the draw function have a parameter fxType and then some IF things to check what to do :/

Code: [Select]
bool ogl_draw(bool fxType)
{
static float a=0.0f, b=0.0f,binc=0.86f;
static float c=0;

glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
start:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-5000);
//rotation
if (fxType == false)
{
glRotatef(c,0,0,1);
}

//scale
if (fxType == true)
{
glScalef(scaleamount,scaleamount,scaleamount);
}

c+=0.5;
if (c > 90)
{c = 90, binc=0;
Sprite *img = images[0];
images[0] = images[1];
images[1] = img;

images[0]->flipx();
images[1]->flipx();
images[0]->dirty();
images[1]->dirty();

c=0,b=0,binc=0.86f;

goto start;
}

//glRotatef(a,axis.x,axis.y,0.0);
//a += 1.0f;
glPushMatrix();
a=0;
images[0]->settexture();
glCullFace(GL_FRONT);
for (int x = 0; x < HSEGS; x++)
{
glPushMatrix();
a = b+(b*x)/HSEGS;
if (a>180)a=180;
glRotatef(a,axis.x,axis.y,0.0);
segs[x]->draw();
glPopMatrix();
}
glPopMatrix();
a=0;
images[1]->settexture();
glCullFace(GL_BACK);
for (int x = 0; x < HSEGS; x++)
{
glPushMatrix();
a = b+(b*x)/HSEGS;
if (a>180)a=180;
glRotatef(a,axis.x,axis.y,0.0);
segs[x]->draw();
glPopMatrix();
}
b=b+binc;

return fxType;
}

and then in the while

Code: [Select]
do
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0, PM_NOREMOVE))
{
if (GetMessage(&msg,NULL,0,0)>0)
{

TranslateMessage(&msg);
DispatchMessage(&msg);

}
else
{
    quit = 1;
break;
}
}

if (!IsPlaying)
{
    playmusic();
}

int i;

for (i=0; i<181; i++)
{
ogl_draw(false);
ogl_flip();
}

float j;

for (j=0.999; j>0.0;j-=0.001)
{
float scaleamount = j;
ogl_draw(true);
}

} while (!quit);

so it should have scaleamount from here and also the bool parameter for scale/rotate choosing.

Quote
Jim wrote: btw, since you're not calling ogl_draw/ogl_flip inside the GetMessage loop any more, your app will eventually become unresponsive and crash.  You need to pump (Get/Dispatch) messages.

I don't understand this...those for loops are on the place where was earlier the ogl_draw() function and flip function too :P How this is not inside GetMessage loop? I understand the for loop is making this problem but I don't see any way to fix it. Cos I need some way to control the lenght of that flipping and as I see it the only way is with for loop(=?)

I also heard from my sister's husband that it would be wise to make a new Draw class for this and then make two "virtual" functions that have same name for example effect, one for scaling and one for rotating which you would use in the draw function by calling the effect function of wanted type...(but as you might know already, this was way beyond my skill level now, and I didn't quite understand it :P)...

-Kypho the beginner

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Transition demo source code
« Reply #5 on: January 26, 2009 »
Quote
I also heard from my sister's husband that it would be wise to make a new Draw class for this and then make two "virtual" functions that have same name for example effect, one for scaling and one for rotating which you would use in the draw function by calling the effect function of wanted type
That can be a good solution for some problems, but this isn't one of them.  virtual functions are part of C++ that let you implement the same thing for objects that have the same base class, for instance.

Code: [Select]
class shape
{
  protected virtual void draw();
}

class square : shape
{
  protected virtual draw()
  {
     //code to draw a square
  }
}

class triangle : shape
{
  protected virtual draw()
  {
     //code to draw a triangle
  }
}
Then, any time someone hands you a 'shape' object, you can call shape->draw() and it will know how to draw that shape whether it's a triangle or a square.

Quote
Quote
btw, since you're not calling ogl_draw/ogl_flip inside the GetMessage loop any more, your app will eventually become unresponsive and crash.  You need to pump (Get/Dispatch) messages.
I don't understand this...those for loops are on the place where was earlier the ogl_draw() function and flip function too  How this is not inside GetMessage loop? I understand the for loop is making this problem but I don't see any way to fix it. Cos I need some way to control the lenght of that flipping and as I see it the only way is with for loop(=?)
OK, they were inside the loop, but if you draw 1180 frames, that's over 20seconds you are not responding to messages, and Windows will complain.

Here is roughly how I would do it:

Code: [Select]
//setup
#define ROTATING 1
#define SCALING 2
#define FINISHED 3

int state = ROTATING;
float scale = 1.0f;
float angle = 0.0f;
int frame = 0;
...
...

do
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0, PM_NOREMOVE))
{
if (GetMessage(&msg,NULL,0,0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
quit = 1;
break;
}
}

  if (state == ROTATING)
  {
    angle += 0.5f;
    frame++;
    if (frame > 180)
      state = SCALING;
  }
  else if (state == SCALING)
  {
    scale -= 0.001f;
    frame++;
    if (frame > 180 + 1000)
      state = FINISHED;
  }
  ogl_draw(angle, scale);
  ogl_flip();

} while (!quit);

Code: [Select]
bool ogl_draw(float angle, float scale)
{
...
glTranslatef(0,0,-5000);
glRotatef(angle,0,0,1);
glScalef(scale,scale,scale);
}
I think that will work.


On a separate note, you wrote this
Code: [Select]
for (j=0.999; j>0.0;j-=0.001)
{
float scaleamount = j;
ogl_draw(true);
}
and then inside ogl_draw() you had this
Code: [Select]
glScalef(scaleamount,scaleamount,scaleamount);
I guess you must also have added a global variable line at the top of the code like this
Code: [Select]
float scaleamount;

The problem is these two scale amounts are not the same scaleamount.  The one in the for loop only lives inside the for loop.  The other one would be unaffected.  This is called 'scoping'.  If you'd like to understand that more then give me a shout. :)

Jim



Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #6 on: January 26, 2009 »
Hi Jim.

Thanks for your quick response and help :) I really appreciate you're willing to help beginner like me. I will try that kind of code later tonight or tomorrow :) and I would of course like to hear about that scaleamount variable difference (scoping it was) more...always willing to learn more.

One thing, is it easy to build some kind of timer thing to this program, for example I would like to rotate for 2 sec (and in 2sec the pic flips 1 time) and then use 3 secs for scale (and in 3 secs the pic scales away)? It could be cool to keep in "the rhythm" somehow :P but anyway, thanks and I will be back ;)

- Kypho the beginner

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Transition demo source code
« Reply #7 on: January 26, 2009 »
The timing is easy.  Every frame is 1/60th of a second.  So if you keep a counter of frames (frame++ in my example) then every 60 counts is 1 second.

Jim

Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #8 on: January 27, 2009 »
This some APRON/NEHE example code

I wonder how I could put this code to the transition code, cos simply putting this function to the program and then call it doesn't do the trick :(

Code: [Select]
///NEW CUBE

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
    // Clear Screen And Depth Buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // Reset The Current Modelview Matrix
    glLoadIdentity();

//NEW//////////////////NEW//////////////////NEW//////////////////NEW/////////////

  glTranslatef(0.0f, 0.0f,-7.0f); // Translate Into The Screen 7.0 Units
  glRotatef(rotqube,0.0f,1.0f,0.0f); // Rotate The cube around the Y axis
  glRotatef(rotqube,1.0f,1.0f,1.0f);
  glBegin(GL_QUADS); // Draw The Cube Using quads
    glColor3f(0.0f,1.0f,0.0f); // Color Blue
    glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
    glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
    glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
    glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
    glColor3f(1.0f,0.5f,0.0f); // Color Orange
    glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
    glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
    glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
    glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
    glColor3f(1.0f,0.0f,0.0f); // Color Red
    glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
    glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
    glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
    glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
    glColor3f(1.0f,1.0f,0.0f); // Color Yellow
    glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
    glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
    glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
    glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
    glColor3f(0.0f,0.0f,1.0f); // Color Blue
    glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
    glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
    glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
    glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
    glColor3f(1.0f,0.0f,1.0f); // Color Violet
    glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
    glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
    glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
    glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
  glEnd(); // End Drawing The Cube

  rotqube +=0.9f; // Increase Angle

//NEW//////////////////NEW//////////////////NEW//////////////////NEW/////////////

    return TRUE; // Keep Going
}

/////END OF NEW CUBE

Then I have the following in my main
 
Code: [Select]
 
if (state == FINISHED)
  {
  DrawGLScene();
  }


.-Kypho the beginner

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Transition demo source code
« Reply #9 on: January 27, 2009 »
You haven't set up any model or view matrix so the object will be about 2 pixels in size.
Try adding
glScale(100,100,1) after the glRotates.

Jim

Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #10 on: January 29, 2009 »
Hi.

I put now     glMatrixMode(GL_MODELVIEW);   and     glPushMatrix();      and something happened, it seems that it draws my earlier texture (the picture which kept flipping) but colored it with purple :P It rotates that picture somehow, but I cannot see the cube yet there. I wonder how could I set the texture and get that thing more cubish, cos now it seems that it makes the flipping picture there and uses that old data (rotates it then and so on)...I would like to "clear" all the old data away or something :)

- Kypho the beginner

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Transition demo source code
« Reply #11 on: January 29, 2009 »
You most certainly don't want a glPushMatrix call unless you have a glPopMatrix call to match it.  Each Push stores the current matrix on a stack, so you can then change it, draw something with the new matrix, and 'Pop' back to the original one.  The stack is usually only 8 deep, so you will get errors very quickly if your Push and Pops don't match.

Have you read any OpenGL documentation?  There's some great stuff here
http://www.sgi.com/products/software/opengl/tech_info.html

You won't fund a 'reset' function.  OpenGL works as a state based system.  ie.  There is a current value of everything in the system - the current texture, the current uv, the current 3d position, the current colour, the current zbuffer culling method, etc, etc.  Each command in OpenGL affects one of these states.  If you want to reset, you have to re-write lots of states back to the way you want them.  That's why it can be hard to combine two people's OpenGL codes - they rely on having a different state set at the start.

Jim
Challenge Trophies Won:

Offline kypho

  • C= 64
  • **
  • Posts: 26
  • Karma: 1
    • View Profile
Re: Transition demo source code
« Reply #12 on: January 30, 2009 »
hmm, seems to be complicated-..I take closer look of this later when I have free time :) that document will come handy for sure.

- Kypho the beginner