我试图这样做,当我按下W,A,S或D时,它会在屏幕上移动一堆线条。我从文件中读取所有行并显示它们,并且工作正常。
所以我有一个键盘函数,它有一个switch语句,它增加了我在显示函数里面的glTranslate中使用的X和Y变量,但是我的行不会移动。任何人都可以帮我解决这个问题吗?
#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
int height = 640, width = 640;
int X = 0, Y = 0;
void drawPolyLineFile(char * fileName) {
std::fstream inStream;
inStream.open(fileName, std::ios::in);
if (inStream.fail()) {
std::cerr<< "Error opening file";
return;
}
glClear(GL_COLOR_BUFFER_BIT);
GLint numpolys, numLines, x, y;
inStream >> numpolys;
for ( int j =0; j < numpolys; j++) {
inStream >> numLines;
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numLines; i++) {
inStream >> x >> y;
glVertex2i(x, y);
}
glEnd();
}
//glutSwapBuffers();
inStream.close();
}
void display(void)
{
/* clear all pixels */
glClear (GL_COLOR_BUFFER_BIT);
glTranslatef(X, Y, 0);
drawPolyLineFile("dino.dat");
/* don't wait!
* start processing buffered OpenGL routines
*/
glutSwapBuffers();
}
void init (void)
{
/* select clearing color */
glClearColor (0.0, 0.0, 0.0, 0.0);
/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640.0, 0.0, 640.0, -1.0, 1.0);
}
void keyboard(unsigned char key, int x, int y) {
float speed = 5.0f;
switch ( key ) {
case 'a':
X -= speed;
std::cerr<< X << std::endl;
break;
case 'd':
X += speed;
std::cerr<< X << std::endl;
break;
case 's':
Y -= speed;
std::cerr<< Y << std::endl;
break;
case 'w':
Y += speed;
std::cerr<< Y << std::endl;
break;
default:
break;
}
}
/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (640, 640);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
答案 0 :(得分:1)
我没有仔细阅读,但你很可能错过了
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
在致电glTranslate
之前。 glTranslate撰写翻译。从你的代码看,你似乎期望它设置一个翻译。
您可能还希望避免在每一帧都从磁盘读取。在启动时将模型加载到数据结构中,然后从中进行渲染。
答案 1 :(得分:0)
您的键盘处理程序中缺少glutPostRedisplay
。没有它,就不会重新开始重新绘制窗口。设置显示为空闲功能也可以做到这一点,但工作方式不同:窗口不断重绘,几乎所有CPU时间都用于绘图。您的代码也有其他一些谬误。我解决了这个问题。
#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
int X = 0, Y = 0;
void drawPolyLineFile(char * fileName) throw(std::runtime_error)
{
std::fstream inStream;
inStream.open(fileName, std::ios::in);
if (inStream.fail()) {
throw std::runtime_error("Error opening file")
}
GLint numpolys, numLines, x, y;
inStream >> numpolys;
for ( int j =0; j < numpolys; j++) {
inStream >> numLines;
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numLines; i++) {
inStream >> x >> y;
glVertex2i(x, y);
}
glEnd();
}
inStream.close();
}
void display(void)
{
int window_width, window_height;
window_width = glutGet(WINDOW_WIDTH);
window_height = glutGet(WINDOW_HEIGHT);
glViewport(0, 0, window_width, window_height);
/* clear all pixels */
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
/* always set all projection parameters a new
* each rendering pass
*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(X, Y, 0);
drawPolyLineFile("dino.dat");
/*
* SwapBuffers will flush the OpenGL queue indeed,
* but more importantly it brings the content from
* the back buffer to the front
*/
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
float speed = 5.0f;
switch ( key ) {
case 'a':
X -= speed;
std::cerr<< X << std::endl;
break;
case 'd':
X += speed;
std::cerr<< X << std::endl;
break;
case 's':
Y -= speed;
std::cerr<< Y << std::endl;
break;
case 'w':
Y += speed;
std::cerr<< Y << std::endl;
break;
default:
break;
}
glutPostRedisplay();
}
/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (640, 640);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
try {
glutMainLoop();
} catch (std::runtime_error &err) {
std::cerr << err.what();
}
return 0;
}