游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4581|回复: 13

为什么不能连续转动?

[复制链接]

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2005-12-30 10:56:00 | 显示全部楼层 |阅读模式
我刚学opengGL,写了一小段程序,想让立方体连续旋转,但是渲染出来时是没有动,为什么阿?请高手赐教!
以下是我的display函数。

static GLfloat rotateAngle = 0.0;

void display(void)
{
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(1.0, 1.0, 1.0);
        glRotatef(rotateAngle, 0.0, 0.0, 1.0);
        glTranslatef(0.0, 0.0, -5.0);
        glScalef(1.0, 2.0, 1.0);
        glutWireCube(1.0);
        glFlush();

        rotateAngle += 3.0;
        if(rotateAngle > 360)
                rotateAngle -= 360;
} [em7]

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
 楼主| 发表于 2005-12-30 12:06:00 | 显示全部楼层

Re:为什么不能连续转动?

谢谢这位大哥。这种方法我试过了,但是不行。为了找出具体问题,我把完整的代码列出来。
#include "GL/glut.h"

#pragma comment( lib, "glut32.lib")

static GLfloat rotateAngle = 0.0;

void init(void)
{
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glShadeModel(GL_FLAT);
}

void display(void)
{
        glClear(GL_COLOR_BUFFER_BIT);
        glLoadIdentity();       
        glColor3f(1.0, 1.0, 1.0);
        glTranslatef(0.0, 0.0, -5.0);
        glRotatef(rotateAngle, 0.0, 1.0, 0.0);       
        glScalef(1.0, 2.0, 1.0);
        glutWireCube(1.0);
        glFlush();

        rotateAngle += 3.0;
        if(rotateAngle > 360)
                rotateAngle -= 360;
}

void reshape(int w, int h)
{
        glViewport(0, 0, (GLsizei)w, (GLsizei)h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
               gluPerspective(60.0, 1.0, 1.5, 20.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
}

int main(int argc, char **argv)
{
        glutInit(&argc, argv);       
        glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
       
        glutInitWindowSize(500, 500);
        glutInitWindowPosition(100, 100);
        glutCreateWindow(argv[0]);
        init();
        glutDisplayFunc(display);
        glutReshapeFunc(reshape);
        glutMainLoop();
        return 0;
}

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
 楼主| 发表于 2005-12-30 14:21:00 | 显示全部楼层

Re:为什么不能连续转动?

按你说的还是不行
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

24

主题

256

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2005-12-30 14:21:00 | 显示全部楼层

Re:为什么不能连续转动?

你想知到为什么吗?我告诉你,因为你的display()函数没有循环运行,也就是说,display()函数在整个程序中只被执行一次。

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
 楼主| 发表于 2005-12-30 14:23:00 | 显示全部楼层

Re:为什么不能连续转动?

楼上这位大哥,我在display里面设了断点,每次都到阿,全局变量的值每次都改变了,但就是没有旋转

24

主题

256

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2005-12-30 14:37:00 | 显示全部楼层

Re:为什么不能连续转动?

#include "GL/glut.h"

#pragma comment( lib, "glut32.lib")

static GLfloat rotateAngle = 0.0;



void TimeFun(int n);

void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);

glutTimerFunc(10,TimeFun,0);

}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 1.0, 1.0);
glTranslatef(0.0, 0.0, -5.0);
glRotatef(rotateAngle, 0.0, 1.0, 0.0);
glScalef(1.0, 2.0, 1.0);
glutWireCube(1.0);
glFlush();


}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
               gluPerspective(60.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void TimeFun(int n)
{
        rotateAngle += 3.0;
        if(rotateAngle > 360)
        rotateAngle -= 360;       

        display();

        glutTimerFunc(10,TimeFun,0);
}


int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);


glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);



glutMainLoop();
return 0;
}

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
 楼主| 发表于 2005-12-30 14:53:00 | 显示全部楼层

Re:为什么不能连续转动?

谢谢楼上的!你这种做法可以达到连续旋转的效果。但为什么一定要用timer function呢?
我先前看的<学openGL编3D游戏>中就没有用timer function。只不过它是的win32,这是不是glut的缘故呢?display明明是每次都在执行啊?请帮小弟解惑,谢谢!

24

主题

256

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2005-12-30 15:30:00 | 显示全部楼层

Re:为什么不能连续转动?


  1.         while ( TRUE ) {
  2.                 //see if there is a message waiting

  3.                 if ( ::PeekMessage ( &msg, NULL, 0, 0, PM_NOREMOVE ) ) {
  4.                         do //if there is pump all waiting
  5.                         {
  6.                                 if ( !PumpMessage () )
  7.                                         return ExitInstance ();
  8.                         } while ( ::PeekMessage ( &msg, NULL, 0, 0, PM_NOREMOVE ) );
  9.                 } else {

  10.                         // use the appropriate method to get time
  11.                         // and calculate elapsed time since last frame

  12.                         if ( m_bPerFlag ) {
  13.                                 QueryPerformanceCounter ( ( LARGE_INTEGER * ) &m_lCurTime );       
  14.                         } else {
  15.                                 m_lCurTime=timeGetTime ();
  16.                         }

  17.                         // is it time to render the frame?

  18.                         if ( m_lCurTime > m_lNextTime ) {

  19.                                 // calculate elapsed time

  20.                                 m_dTimeElapsed = ( m_lCurTime - m_lLastTime ) * m_dTimeScale;
  21.                                

  22.                                 // save frame time

  23.                                 m_lLastTime = m_lCurTime;
  24.                                
  25.                                 // yes, render the frame

  26.                                 if ( !pFrame->m_bAppIsActive )
  27.                                         WaitMessage();
  28.                                 else
  29.                                          <B>pFrame->RenderGLScene ();</B>

  30.                                 // set time for next frame

  31.                                 m_lNextTime = m_lCurTime + m_dwTimeCount;

  32.                         } // end if

  33.                 } // end if else

  34.         } // end while

复制代码



在win32中用一个死循环不不段查询有没有消息,如果有则处理消息,没有消息就刷新屏幕:
<B>pFrame->RenderGLScene ();</B>
而在glut中没有这个循环机制,glut的程序运行后便进入一种等待状太,直到有消息把它换醒。

更有意思的是:glut中的glutTimerFunc(10,TimeFun,0); 函数是一次性的,用了一次就没了,不像win32中的SetTimer(),在win32中一但启动了计时器,它就是会自动的不断向窗口发送OnTime();消息,而glutTimerFunc()涵数却不会这样。它只会调用TimeFun()一次;

这也就是为什么要在TimeFun()函数中再次调用glutTimerFunc()的原因。

void TimeFun(int n)
{
rotateAngle += 3.0;
if(rotateAngle > 360)
rotateAngle -= 360;

display();

glutTimerFunc(10,TimeFun,0);
}

1

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
 楼主| 发表于 2005-12-30 16:08:00 | 显示全部楼层

Re:为什么不能连续转动?

“glut的程序运行后便进入一种等待状太,直到有消息把它换醒”

我在reshape里面设断点单步执行时,发现cube是旋转了的,只是每次到断点时,都转了个很大的角度,我试着该小了旋转角度,还是没反应。
按你的说法,我应该可以在reshape里加 glutPostRedisplay()唤醒,但这样会运行慢好多,而且转动得非常快!不知道楼上的是怎么解决这个问题的阿?

24

主题

256

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2005-12-30 17:17:00 | 显示全部楼层

Re:为什么不能连续转动?

1、没有发现你说的“转了个很大的角度”的现像。

2、“在reshape里加 glutPostRedisplay()唤醒” 是多些一举的行为。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 03:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表