按负数不按比例翻转 Opengl 绘图

Flipping Opengl drawing without scale by negative numbers

我正在尝试绘制两个彼此面对的 2D 钻石。 所以我画了第一颗钻石然后我画了第二颗钻石使用后:

glTranslated(0, -150, 0);

所以它可以正好出现在我的第一颗钻石下面。 但是,我 运行 遇到了一个问题,我无法翻转第二颗钻石,使它看起来像一面镜子。

这是我正在尝试做的事情:

我在网上搜索解决方案,他们都提到我应该 使用

glScalef(1.0f,-1.0f,1.0f); 

但每次我使用它时,绘图都会消失。

函数

glRotatef(angle,x,y,z); 

引起了我的注意,但我无法正确使用它导致方向错误。

这是我的图片现在没有 glRotate() 时的样子:

所以我认为我需要适当的技术来使用这些功能中的任何一个。

注意:我使用了很多线环和顶点来绘制。

  #include <windows.h>  // For MS Windows
  #include <GL/glut.h>   // (or others, depending on the system in use)
  void init(void)
  {
     glClearColor(1.0, 1.0, 1.0, 0.0);  // Set display-window color to 
      white.
    glMatrixMode(GL_PROJECTION);       // Set projection parameters.
    gluOrtho2D(0.0, 400.0, 0.0, 400.0);
  }
  void drawDiamond()
     {
  glBegin(GL_LINE_LOOP);
  glVertex2f(125, 350);
  glVertex2f(245, 350);
  glVertex2f(290, 300);
  glVertex2f(182, 200);
  glVertex2f(75, 300);
  glEnd();


 glBegin(GL_LINE_LOOP);
 glVertex2f(109, 333);
 glVertex2f(138, 350);
 glVertex2f(159, 337);
 glVertex2f(123, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(109, 333);
glVertex2f(123, 300);
glVertex2f(154, 225);
glVertex2f(92, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(290, 300);
glVertex2f(75, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(123, 300);
glVertex2f(159, 337);
glVertex2f(154, 300);
glVertex2f(171, 225);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(159, 337);
glVertex2f(181, 350);
glVertex2f(209, 337);
glVertex2f(181, 300);
glVertex2f(171, 225);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(181, 300);
glVertex2f(209, 337);
glVertex2f(219, 300);
glVertex2f(195, 225);
glVertex2f(181, 300);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(243, 300);
glVertex2f(195, 225);
glVertex2f(219, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(209, 337);
glVertex2f(229, 350);
glVertex2f(260, 333);
glVertex2f(243, 300);
glVertex2f(209, 337);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(260, 333);
glVertex2f(278, 300);
glVertex2f(210, 225);
glVertex2f(243, 300);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(195, 225);
glVertex2f(182, 200);
glEnd();

glBegin(GL_LINE_LOOP);
glVertex2f(171, 225);
glVertex2f(182, 200);
glEnd();

}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);  // Clear display window.
glColor3f(0.0, 0.0, 0.0);      // Set line segment color to blue.

                               // your code goes here
drawDiamond();
glTranslatef(0.0f, -150, 0.0f);
drawDiamond();
glFlush();     // Process all OpenGL routines as quickly as possible.

}
void main(int argc, char** argv)
{
glutInit(&argc, argv);                         // Initialize GLUT.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);   // Set display mode.
glutInitWindowPosition(50, 100);   // Set top-left display-window 
position.
glutInitWindowSize(400, 400);      // Set display-window width and 
height. 
glutCreateWindow("Diamond Project"); // Create display window. 

init();                            // Execute initialization procedure. 
glutDisplayFunc(display);       // Send graphics to display window. 


glutMainLoop();                    // Display everything and wait.      

}

根据您的顶点设置方式以及您是否启用了背面剔除,您可能需要将菱形或(模型的)中心点更改为底部尖端,然后您可以简单地围绕 X 旋转轴,前提是您将其声明为水平轴。这样做应该没有那么难。它看起来像:

glRotatef( 180.0f, 1, 0, 0 );

如果您旋转的是度数而不是弧度。

对于每个顶点(我假设您使用直接模式来指定顶点),您可以 glVertex2i(myVertex.x, symmetryLine - myVertex.y, 0) 其中 myVertex 是您之前使用的 x 和 y 值,而 symmetryLine 是您希望镜像的值反对。不过,最好的方法是使用负数 glScale。您的钻石是旋转对称的 glRotate 也可以,但是您知道,这不是一种非常优雅的方法。

您要做的是围绕平行于 X-axis 的轴镜像(翻转)对象,并穿过对象(菱形)的底部边界。

为此,必须找到底部 Y 坐标 (bottomY),并且必须在 相反 方向平移对象。注意模型坐标(顶点)的底部和不是视口上最终坐标的底部:

float bottomY = 200.0f;
glTranslatef( 0.0f, -bottomY , 0.0f );

接下来必须翻转对象。这可以通过

glRotatef(180.0f, 1.0f, 0.0f, 0.0f);

glScalef(1.0f, -1.0f, 0.0f)

注意,这两个操作产生相同的变换矩阵,因为cos(90°) = cos(-90°), sin(90°) = -sin(90°).

那么bottomY的翻译要反过来:

glTranslatef( 0.0f, bottomY, 0.0f );

但请注意,OpenGL 固定功能管道堆栈以相反的顺序运行,因为当前矩阵乘以新操作指定的矩阵。

翻译:见glTranslate的文档:

glTranslate produces a translation by x y z . The current matrix (see glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix.

旋转:参见glRotate的文档:

glRotate produces a rotation of angle degrees around the vector x y z . The current matrix (see glMatrixMode) is multiplied by a rotation matrix with the product replacing the current matrix.

缩放:参见glScale的文档:

glScaleproduces a nonuniform scaling along the x, y, and z axes. The three parameters indicate the desired scale factor along each of the three axes. The current matrix (see glMatrixMode) is multiplied by this scale matrix.


这意味着以下应该做你想做的事:

float bottomY = 200.0f;

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

drawDiamond();

glTranslatef( 0.0f, bottomY , 0.0f );
glRotatef( 180.0f, 1.0f, 0.0f, 0.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );

drawDiamond();

并且与:

相同
glTranslatef( 0.0f, bottomY , 0.0f );
glScalef( 1.0f, -1.0f, 1.0f );
glTranslatef( 0.0f, -bottomY , 0.0f );