【问题标题】:How to stop stretching in opengl如何在opengl中停止拉伸
【发布时间】:2020-01-25 16:38:12
【问题描述】:

我创建了线条,当我旋转线条时。线会拉长。如何在旋转时停止拉伸。当我在 Ortho 中更改高度时,它将无法正确显示。当 Line 向左或向右移动时,它会开始拉伸,但当它到达主要点时,它会到达实际位置。

#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<glut.h>
using namespace std;
float yr = 0;
void introscreen();
void screen();
void screen1();
void PitchLadder();

int width = 1268;
int height = 720;

float translate =  0.0f;
GLfloat angle = 0.0f;

void display(void) {
    glClearColor(0, 0, 0, 0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-300, 300, -10, 25, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    static int center_x = 0;
    static int center_y = 0;
}

void specialKey(int key, int x, int y) {
    switch (key) {
    case GLUT_KEY_UP:
        translate += 1.0f;
        break;
    case GLUT_KEY_DOWN:
        translate -= 1.0f;
        break;
    case GLUT_KEY_LEFT:
        angle += 1.0f;
        break;
    case GLUT_KEY_RIGHT:
        angle -= 1.0f;
        break;
    }

    glutPostRedisplay();
}

void Rolling(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0, 1, 0);
    glPushMatrix();
    glRotatef(-angle, 0, 0, 1);
    glTranslatef(-10, translate,0);
    PitchLadder();
    glPopMatrix();
    glFlush();
}

void PitchLadder() {
    GLfloat y;
    GLfloat y2;
    GLfloat fSize[5];
    GLfloat fCurrSize;
    fCurrSize = fSize[2];
    for (y2 = -90.0f ; y2 <= 90.0f ; y2 += 10.0f) {
        glLineWidth(fCurrSize);
        glBegin(GL_LINES);
        glVertex3f(-50.0f , y2 , 0);
        glVertex3f(50.0f , y2 , 0);
        glEnd();
        fCurrSize += 1.0f;
        screen();
        screen1();
    }
}

void renderbitmap1(float x3, float y3, void *font1, char *string1) {
    char *c1;
    glRasterPos2f(x3, y3);
    for (c1=string1; *c1 != '\0'; c1++) {
        glutBitmapCharacter(font1, *c1);
    }
}

void screen(void) {
    glColor3f(0, 1, 0);
    char buf1[20] = { '\0' };
    for (int row1 = -90.0f; row1 <= 90 + yr; row1 +=10.0f) {
        sprintf_s(buf1,"%i", row1);
        renderbitmap1(70 , (yr+row1), GLUT_BITMAP_TIMES_ROMAN_24, buf1);
    }
 }

void renderbitmap2(float x4, float y4, void *font2, char *string2) {
    char *c1;
    glRasterPos2f(x4, y4);
    for (c1=string2; *c1 != '\0'; c1++) {
        glutBitmapCharacter(font2, *c1);
    }
}

void screen1(void) {
    glColor3f(0, 1, 0);
    char buf1[20] = { '\0' };
    for (int row1 = -90.0f; row1 <= 90 + yr; row1 +=10.0f) {
        sprintf_s(buf1,"%i", row1);
        renderbitmap2(-70 , (yr+row1), GLUT_BITMAP_TIMES_ROMAN_24, buf1);
    }
 }

int main(int arg, char** argv) {
    glutInit(&arg, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(width, height);
    glutInitWindowPosition(50, 100);
    glutCreateWindow("HUD Lines");
    display();
    glutDisplayFunc(Rolling);
    glutSpecialFunc(specialKey);
    glutMainLoop();
    return 0;
}

【问题讨论】:

标签: c++ opengl rotation stretch opengl-compat


【解决方案1】:

您的窗口大小和正交“视图”的纵横比不同:

// This creates a window that's 1268 x 720 (a wide rectangle)
int width = 1268;
int height = 720;
glutInitWindowSize(width, height);    

// This creates a "view" that's 300 x 300 (a square)
glOrtho(-300, 300, -10, 25, 0, 1);    

“视图”将被拉伸以填充视口(窗口)。您会看到一个 300 x 300 的图像被拉伸到 1268x720,这肯定会使水平线看起来比垂直线长,即使它们在代码中的长度相同。

您应该使用窗口的widthheight 变量调用glOrtho

glOrtho(0, width, 0, height, 0, 1);

请注意,我已将参数更改为 (left = 0, right = width, bottom = 0, top = height, ...)。这允许您使用类似于 2D 渲染的屏幕坐标空间,但左下角是(0,0),右上角是(width,height)

【讨论】:

  • 我试试这个,但它不会在中心显示我。
  • @Unknown,如果您将参数更改为glOrtho,这是预期的,因为这会将您的视图移动到 3D 世界中。您可以通过在x = width/2, y = height/2 处绘制来将正在绘制的对象移回中心。
【解决方案2】:

在正交投影中,视图空间坐标被线性映射到剪辑空间坐标和归一化的设备坐标。标准化的设备空间是一个立方体,最小值为 (-1, -1, -1),最大值为 (1, 1, 1)。
最后,标准化设备空间中的坐标被映射到矩形视口。

如果视口是矩形,则在将视图空间坐标转换为剪辑空间时,必须考虑纵横比。
归一化设备坐标到视口的映射通过视口的倒数纵横比扭曲了几何形状。这种失真必须通过正交投影来补偿。

当正交投影由glOrtho(left, right, bottom, top, near, far)设置时,则定义长方体体积,将(左、下、近)映射到(-1、-1、-1)和(右、上、远)到(1, 1, 1)。
正交投影的 x 和 y 范围不必等于视口矩形,比率(left-right)/(top-bottom)必须等于视口矩形的比率,否则几何将失真。

double size = 200.0f;
double aspect = (double)width / (double)height;
glOrtho(-aspect*size/2.0, aspect*size/2.0, -size/2.0, size/2.0, -1.0, 1.0);

【讨论】:

  • 你知道如何在 90 停止滚动吗?如果我按下或向上按钮,它将无限滚动。我想在 90 内停止滚动
  • @Unknown 例如case GLUT_KEY_UP:if (translate &lt; 90.0f ) { translate += 1.0f; }
  • 我尝试了,但它不起作用。它仍然处于无限循环中
  • @Unknown 你想限制旋转还是平移?
  • 它工作正常。我的错我做错了地方。抱歉,它工作得很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 2013-10-07
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
相关资源
最近更新 更多