如何在opengl中停止拉伸
How to stop stretching in opengl
我创建了线条并在旋转线条时。线会被拉伸。我怎样才能在旋转时停止拉伸。当我在 Ortho 中更改高度时,它将无法正确显示。当线向左或向右移动时,它会开始拉伸,但当它到达主要点时,它会到达真实位置。
#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 != '[=10=]'; c1++) {
glutBitmapCharacter(font1, *c1);
}
}
void screen(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '[=10=]' };
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 != '[=10=]'; c1++) {
glutBitmapCharacter(font2, *c1);
}
}
void screen1(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '[=10=]' };
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;
}
您的 window 大小和正字法 "view" 的宽高比不同:
// 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);
"view" 将被拉伸以填充视口 (window)。您看到 300 x 300 的图像被拉伸到 1268x720,这肯定会使水平线看起来比垂直线长,即使它们在代码中的长度相同。
您应该使用 window:
的 width
和 height
变量来调用 glOrtho
glOrtho(0, width, 0, height, 0, 1);
请注意,我已将参数更改为 (left = 0, right = width, bottom = 0, top = height, ...)
。这允许您使用类似于 2D 渲染的屏幕坐标 space,但左下角是 (0,0)
,右上角是 (width,height)
。
在正交投影中,视图 space 坐标线性映射到剪辑 space 坐标,分别归一化设备坐标。标准化设备 space 是一个立方体,最小值为 (-1, -1, -1),最大值为 (1, 1, 1)。
最后,规范化设备 space 中的坐标映射到矩形视口。
如果视口是矩形的,则必须考虑长宽比,当视图 space 坐标转换为剪辑 space。
归一化设备坐标到视口的映射通过视口的倒数纵横比扭曲了几何形状。这种失真必须通过正射投影来补偿。
当glOrtho(left, right, bottom, top, near, far)
设置了正射投影时,则定义了长方体体积,将(left, bottom, near)映射到(-1, -1, -1)和(right, top) , 远) 到 (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);
我创建了线条并在旋转线条时。线会被拉伸。我怎样才能在旋转时停止拉伸。当我在 Ortho 中更改高度时,它将无法正确显示。当线向左或向右移动时,它会开始拉伸,但当它到达主要点时,它会到达真实位置。
#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 != '[=10=]'; c1++) {
glutBitmapCharacter(font1, *c1);
}
}
void screen(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '[=10=]' };
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 != '[=10=]'; c1++) {
glutBitmapCharacter(font2, *c1);
}
}
void screen1(void) {
glColor3f(0, 1, 0);
char buf1[20] = { '[=10=]' };
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;
}
您的 window 大小和正字法 "view" 的宽高比不同:
// 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);
"view" 将被拉伸以填充视口 (window)。您看到 300 x 300 的图像被拉伸到 1268x720,这肯定会使水平线看起来比垂直线长,即使它们在代码中的长度相同。
您应该使用 window:
的width
和 height
变量来调用 glOrtho
glOrtho(0, width, 0, height, 0, 1);
请注意,我已将参数更改为 (left = 0, right = width, bottom = 0, top = height, ...)
。这允许您使用类似于 2D 渲染的屏幕坐标 space,但左下角是 (0,0)
,右上角是 (width,height)
。
在正交投影中,视图 space 坐标线性映射到剪辑 space 坐标,分别归一化设备坐标。标准化设备 space 是一个立方体,最小值为 (-1, -1, -1),最大值为 (1, 1, 1)。
最后,规范化设备 space 中的坐标映射到矩形视口。
如果视口是矩形的,则必须考虑长宽比,当视图 space 坐标转换为剪辑 space。
归一化设备坐标到视口的映射通过视口的倒数纵横比扭曲了几何形状。这种失真必须通过正射投影来补偿。
当glOrtho(left, right, bottom, top, near, far)
设置了正射投影时,则定义了长方体体积,将(left, bottom, near)映射到(-1, -1, -1)和(right, top) , 远) 到 (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);