首先聲明自己是這方面的小白,希望大神可以對有問題以及可以優化的地方提出來。也歡迎指出不足和吐槽。希望幫到小白。
自己參考得比較多的網站是這個:
http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html
所有代碼都可以去github免費下載(不怎麼喜歡CSDN的積分下載):
https://github.com/Iamttp/OpenGLTest
不多廢話,好先上這一節的效果圖。
#include <gl/glut.h>
#include <iostream>
bool mouseDown = false;
float xrot = 0.0f;
float yrot = 0.0f;
float xdiff = 0.0f;
float ydiff = 0.0f;
// 繪製正方體
void drawBox() {
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
// FRONT
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
// BACK
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glColor3f(0.0f, 1.0f, 0.0f);
// LEFT
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
// RIGHT
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
// TOP
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
// BOTTOM
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glEnd();
}
// 繪製函數
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(
0.0f, 0.0f, 3.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
// 實現鼠標旋轉的核心
glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
drawBox();
glFlush();
glutSwapBuffers();
}
void resize(int w, int h) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45.0f, 1.0f * w / h, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// 鼠標事件
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
mouseDown = true;
xdiff = x - yrot;
ydiff = -y + xrot;
std::cout << "xdiff:" << xdiff << "\tydiff" << ydiff << std::endl;
}
else
mouseDown = false;
}
// 鼠標移動事件
void mouseMotion(int x, int y) {
if (mouseDown) {
yrot = x - xdiff;
xrot = y + ydiff;
std::cout << "yrot:" << yrot << "\txrot" << xrot << std::endl;
glutPostRedisplay();
}
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitWindowPosition(50, 50);
glutInitWindowSize(500, 500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("demo");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutReshapeFunc(resize);
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClearDepth(1.0f);
glutMainLoop();
return 0;
}
可以看到代碼非常的簡潔,這是根據國外的一個示例代碼縮減的。關鍵就是並不是改變了攝像頭的視角(gluLookAt),而是直接在繪製之前就旋轉座標系,讓之後繪製的東西都直接旋轉了。讓我們看起來像攝像頭視角在動(我只能說真cool)。