使用 Ortho2D 移动当前图形在 GLUT 中不起作用
Moving current drawings using Ortho2D doesn't work in GLUT
我有一个用 C++/OpenGL 做的迷你项目,允许用户使用鼠标在屏幕上绘制形状。
现在我想允许用户使用他的键盘 move/pan 屏幕左右移动,假设屏幕上的不同位置有 4 个形状,我希望它们都向左移动 "A" 键被按下。
我已经在之前的项目中做到了,甚至放大/缩小,但在这个程序中有些东西不起作用,我设法做的最接近的事情是用户在之后创建的所有新形状"A" 键被按下在新的地方而不是他的鼠标所在的地方。
这是我的主要、初始化、显示和键盘代码:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(W_WIDTH, W_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL Excercise");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(My_mouse_routine);
createMenu();
glutMainLoop();
}
void init()
{
// Select a clear color
glClearColor(0.933, 0.933, 0.933, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
gluOrtho2D(0, W_WIDTH, W_HEIGHT, 0);
}
void display() {/* clear all pixels */
// draw text at the bottom
char* text_to_draw = "Press right mouse button for menu...";
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, W_WIDTH, 0, W_HEIGHT);
glColor3f(0.129, 0.129, 0.129);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, W_HEIGHT - 15); // move in 10 pixels from the left and bottom edges
for (int i = 0; i < (int)strlen(text_to_draw); ++i) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, text_to_draw[i]);
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
case 'A':
case 'a':
glMatrixMode(GL_PROJECTION); //start editing the projection matrix
glLoadIdentity(); //remove current projection
glPopMatrix();
gluOrtho2D(1,0,1,0); //create new one
glPushMatrix();
glMatrixMode(GL_MODELVIEW); //back to editing the modelview matrix
glFlush();
default:
break;
}
glutPostRedisplay();
}
最后是矩形绘图示例:
GLfloat colors[][3] = { { 0.957f, 0.263f, 0.212f },{ 0.298f, 0.686f, 0.314f },{ 0.129f, 0.588f, 0.953f }, };
static int col = 0;
glColor3f(colors[col][0], colors[col][1], colors[col][2]);
glBegin(GL_POLYGON);
glVertex3f(mouse_x - 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y + 50, 0.0);
glVertex3f(mouse_x - 50, mouse_y + 50, 0.0);
glEnd(); /* don't wait!!! start processing buffered OpenGL routines */
col += 1;
if (col == sizeof(colors) / sizeof(colors[0])) {
col = 0;
}
glutPostRedisplay();
我知道在这个网站和其他数百个网站上有很多关于这个问题的问题,我几乎肯定它与矩阵有关,但我不知道我做错了什么.
为什么要在 A
击键时更改投影矩阵?
我假设您想使用 WSAD(这对于像我这样的老派 OPQAM 人来说非常不舒服)平移查看。
第一个问题是您在 A
击键时更改了 GL_PROJECTION
,但在 display()
中渲染时重置它,渲染击键代码什么都不做。要解决这个问题,您应该在 init()
函数中初始化 GL_PROJECTION
。顺便说一句,您在那里缺少 glMatrixMode
并将其从 display()
.
中删除
另一个问题是您在 GL_PROJECTION
中使用 camera/view 矩阵而不是 GL_MODELVIEW
矩阵,它被称为:
当你使用高级照明和雾时,这会导致严重的问题(除非你切换到 GLSL)。
最后,当您通过 ortho 设置视图时,您应该仅使用 glTranslate
平移 这至少是我的意见。
你的场景存储在哪里?
根据您的文字,我认为这应该是一些简单的矢量绘画,例如能够 add/draw 将形状融入场景的编辑器。所以你需要有某种列表能够存储场景的所有信息,例如:
- 对象类型
- 控制点
- 颜色
我在你的代码中没有看到这样的信息,而是我看到直接使用鼠标坐标,这对于预览最后添加的点来说很好,但对于更复杂的形状(如线)会失败。
这里看看:
- simple Drag&Drop example in C++
关于如何完成的一些想法。
我有一个用 C++/OpenGL 做的迷你项目,允许用户使用鼠标在屏幕上绘制形状。
现在我想允许用户使用他的键盘 move/pan 屏幕左右移动,假设屏幕上的不同位置有 4 个形状,我希望它们都向左移动 "A" 键被按下。
我已经在之前的项目中做到了,甚至放大/缩小,但在这个程序中有些东西不起作用,我设法做的最接近的事情是用户在之后创建的所有新形状"A" 键被按下在新的地方而不是他的鼠标所在的地方。
这是我的主要、初始化、显示和键盘代码:
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(W_WIDTH, W_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("OpenGL Excercise");
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(My_mouse_routine);
createMenu();
glutMainLoop();
}
void init()
{
// Select a clear color
glClearColor(0.933, 0.933, 0.933, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
gluOrtho2D(0, W_WIDTH, W_HEIGHT, 0);
}
void display() {/* clear all pixels */
// draw text at the bottom
char* text_to_draw = "Press right mouse button for menu...";
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, W_WIDTH, 0, W_HEIGHT);
glColor3f(0.129, 0.129, 0.129);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos2i(10, W_HEIGHT - 15); // move in 10 pixels from the left and bottom edges
for (int i = 0; i < (int)strlen(text_to_draw); ++i) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, text_to_draw[i]);
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
case 'A':
case 'a':
glMatrixMode(GL_PROJECTION); //start editing the projection matrix
glLoadIdentity(); //remove current projection
glPopMatrix();
gluOrtho2D(1,0,1,0); //create new one
glPushMatrix();
glMatrixMode(GL_MODELVIEW); //back to editing the modelview matrix
glFlush();
default:
break;
}
glutPostRedisplay();
}
最后是矩形绘图示例:
GLfloat colors[][3] = { { 0.957f, 0.263f, 0.212f },{ 0.298f, 0.686f, 0.314f },{ 0.129f, 0.588f, 0.953f }, };
static int col = 0;
glColor3f(colors[col][0], colors[col][1], colors[col][2]);
glBegin(GL_POLYGON);
glVertex3f(mouse_x - 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y - 50, 0.0);
glVertex3f(mouse_x + 50, mouse_y + 50, 0.0);
glVertex3f(mouse_x - 50, mouse_y + 50, 0.0);
glEnd(); /* don't wait!!! start processing buffered OpenGL routines */
col += 1;
if (col == sizeof(colors) / sizeof(colors[0])) {
col = 0;
}
glutPostRedisplay();
我知道在这个网站和其他数百个网站上有很多关于这个问题的问题,我几乎肯定它与矩阵有关,但我不知道我做错了什么.
为什么要在
A
击键时更改投影矩阵?我假设您想使用 WSAD(这对于像我这样的老派 OPQAM 人来说非常不舒服)平移查看。
第一个问题是您在
中删除A
击键时更改了GL_PROJECTION
,但在display()
中渲染时重置它,渲染击键代码什么都不做。要解决这个问题,您应该在init()
函数中初始化GL_PROJECTION
。顺便说一句,您在那里缺少glMatrixMode
并将其从display()
.另一个问题是您在
GL_PROJECTION
中使用 camera/view 矩阵而不是GL_MODELVIEW
矩阵,它被称为:当你使用高级照明和雾时,这会导致严重的问题(除非你切换到 GLSL)。
最后,当您通过 ortho 设置视图时,您应该仅使用
glTranslate
平移 这至少是我的意见。你的场景存储在哪里?
根据您的文字,我认为这应该是一些简单的矢量绘画,例如能够 add/draw 将形状融入场景的编辑器。所以你需要有某种列表能够存储场景的所有信息,例如:
- 对象类型
- 控制点
- 颜色
我在你的代码中没有看到这样的信息,而是我看到直接使用鼠标坐标,这对于预览最后添加的点来说很好,但对于更复杂的形状(如线)会失败。
这里看看:
- simple Drag&Drop example in C++
关于如何完成的一些想法。