我是使用C ++图形的新手,我有以下代码 tutorial
这是代码
#include <windows.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
#include <math.h>
float angle = 0.0f;
float lx = 0.0f, lz = -1.0f;
float x = 0.0f, z = 5.0f;
float deltaAngle = 0.0f;
float deltaMove = 0;
void drawSnowMan(){
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef(0.0f, 0.75f, 0.0f);
glutSolidSphere(0.75f, 20, 20);
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.25f, 20, 20);
glPushMatrix();
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.5f, 0.10f, 0.18f);
glutSolidSphere(0.05f, 10, 10);
glTranslatef(-0.1f, 0.0f, 0.0f);
glutSolidSphere(0.05f, 10, 10);
glPopMatrix();
glColor3f(1.0f, 0.5f, 0.5f);
glutSolidCone(0.8f, 0.5f, 10, 2);
}
void changeSize(int w, int h){
if(h == 0)
h = 1;
float ratio = 1.0*w/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w,h);
gluPerspective(45.0f, ratio, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
void computePos(float deltaMove){
x += deltaMove * lx * 0.1f;
z += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle){
angle += deltaAngle;
lx = sin(angle/75.0);
lz = -cos(angle/75.0);
}
void pressKey(int key, int xx, int yy){
switch(key){
case GLUT_KEY_LEFT: deltaAngle = -0.5f; break;
case GLUT_KEY_RIGHT: deltaAngle = 0.5; break;
case GLUT_KEY_UP: deltaMove = 0.5f; break;
case GLUT_KEY_DOWN: deltaMove = -0.5f; break;
}
}
void relaseKey(int key, int x, int y){
switch(key){
case GLUT_KEY_LEFT:
case GLUT_KEY_RIGHT: deltaAngle = 0.0f; break;
case GLUT_KEY_UP:
case GLUT_KEY_DOWN: deltaMove = 0; break;
}
}
void renderScene(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
if(deltaMove)
computePos(deltaMove);
if(deltaAngle)
computeDir(deltaAngle);
gluLookAt( x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f
);
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, 0.0f, -100.0f);
glVertex3f(-100.0f, 0.0f, 100.0f);
glVertex3f(100.0f, 0.0f, 100.0f);
glVertex3f(100.0f, 0.0f, -100.0f);
glEnd();
angle += 0.1f;
for(int i = -3; i < 3; i++){
for(int j = -3; j < 3; j++){
glPushMatrix();
glTranslatef(i*10.0,0, j*10.0);
drawSnowMan();
glPopMatrix();
}
}
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(320,320);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Lighthouse 3D");
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glutSpecialFunc(pressKey);
glutIgnoreKeyRepeat(1);
glutSpecialUpFunc(relaseKey);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return 1;
}
我的问题如下,当我尝试向左转,我按下左键时,一切正常。当我尝试击中左侧时,一旦动作不顺畅。在某些情况下,如果按钮行程太快,它甚至会转向相反的方向!
答案 0 :(得分:2)
我认为你的意思是键盘而不是鼠标,在这种情况下,要有一个更好的&#34;更顺畅的&#34;和#34;慢&#34;您需要调整deltaAngle
值,这可能会过高。
这只是一个临时修复,因为这些值可能以不同的方式影响其他机器 - 有些可能更快,有些可能更慢。您需要在渲染循环中计算主机的FPS并将delta
值乘以它,以便在每台计算机上具有相同的性能。这称为基于时间的移动,是每个现代图形应用程序的基本功能。
这正是以下教程中发生的事情,当点在屏幕上移动太快时。
答案 1 :(得分:0)
glutIdleFunc()
将占用您的所有电池/ CPU / GPU,而是使用glutTimerFunc()
重绘可预测的,理智的计划。glutTimerFunc()
,而不是尝试在您的keyup / keydown回调中正确执行。glutResizeFunc()
,在抽奖之前完成所有操作。<cmath>
而不是<math.h>
。所有在一起:
#include <GL/glut.h>
#include <cmath>
#include <map>
std::map< int, bool > keys;
void pressKey(int key, int xx, int yy)
{
keys[ key ] = true;
}
void relaseKey(int key, int x, int y)
{
keys[ key ] = false;
}
float angle = 0.0f;
float lx = 0.0f, lz = -1.0f;
float x = 0.0f, z = 5.0f;
void update()
{
const float angleStep = 0.5f;
if( keys[ GLUT_KEY_LEFT ] ) angle -= angleStep;
if( keys[ GLUT_KEY_RIGHT ] ) angle += angleStep;
const float moveStep = 0.5f;
float move = 0.0f;
if( keys[ GLUT_KEY_DOWN ] ) move -= moveStep;
if( keys[ GLUT_KEY_UP ] ) move += moveStep;
x += move * lx * 0.1f;
z += move * lz * 0.1f;
lx = sin(angle/75.0);
lz = -cos(angle/75.0);
}
void drawSnowMan()
{
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef(0.0f, 0.75f, 0.0f);
glutSolidSphere(0.75f, 20, 20);
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.25f, 20, 20);
glPushMatrix();
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.5f, 0.10f, 0.18f);
glutSolidSphere(0.05f, 10, 10);
glTranslatef(-0.1f, 0.0f, 0.0f);
glutSolidSphere(0.05f, 10, 10);
glPopMatrix();
glColor3f(1.0f, 0.5f, 0.5f);
glutSolidCone(0.8f, 0.5f, 10, 2);
}
void renderScene(void)
{
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const double w = glutGet( GLUT_WINDOW_WIDTH );
const double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(45.0f, w / h, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt
(
x, 1.0f, z,
x+lx, 1.0f, z+lz,
0.0f, 1.0f, 0.0f
);
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, 0.0f, -100.0f);
glVertex3f(-100.0f, 0.0f, 100.0f);
glVertex3f(100.0f, 0.0f, 100.0f);
glVertex3f(100.0f, 0.0f, -100.0f);
glEnd();
for(int i = -3; i < 3; i++)
{
for(int j = -3; j < 3; j++)
{
glPushMatrix();
glTranslatef(i*10.0,0, j*10.0);
drawSnowMan();
glPopMatrix();
}
}
glutSwapBuffers();
}
void timer( int value )
{
update();
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(320,320);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Lighthouse 3D");
glutDisplayFunc(renderScene);
glutSpecialFunc(pressKey);
glutSpecialUpFunc(relaseKey);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 1;
}