如何使用我自己的功能将3D场景转换为2D



我正在尝试写一个简单的代码,使用自己实现的函数,可以旋转、平移和缩放3D场景的2D图片。我想我已经成功地完成了大部分工作,包括投影。困扰我的一件事是,为什么我画的物体这么小?同样,我不能做的是最后一步,在那里我实际上投影模型到2D图像。我想这与渲染有关。

这是我的代码:

#include <GLglew.h>
#include <GLfreeglut.h>
#include<math.h>
#include <stdlib.h>
const GLdouble cutleft = -10.0;
const GLdouble cutright = 10.0;
const GLdouble cuttop = 10.0;
const GLdouble cutbottom = -10.0;
const GLdouble cutnear = 25.0;
const GLdouble cutfar = 5.0;
const GLdouble TR[16] = {
2 * cutnear / (cutright - cutleft),        0,                                        (cutright + cutleft) / (cutright - cutleft),    0,
0,                                        2 * cutnear / (cuttop - cutbottom),        (cuttop + cutbottom) / (cuttop - cutbottom),    0,
0,                                        0,                                        (cutfar+cutnear) / (cutfar-cutnear),            2*cutfar*cutnear/(cutfar-cutnear),
0,                                        0,                                        -1,                                                0
};
GLfloat rotatex = 0.0;
GLfloat rotatey = 0.0;
GLfloat rotatez = 0.0;
GLdouble move = 0.0;
GLdouble scale = 1.0;
void klocek( int k)
{    
int i = 0;
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINES);
glVertex3i(i, i, i);
glVertex3i(i, i + k, i);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i + k, i);
glVertex3i(i + k, i + k, i);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i + k, i);
glVertex3i(i, i + k, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i, i);
glVertex3i(i + k, i, i);
glEnd();
glBegin(GL_LINES);
glVertex3i(i + k, i, i);
glVertex3i(i + k, i + k, i);
glEnd();
glBegin(GL_LINES);
glVertex3i(i + k, i, i);
glVertex3i(i + k, i, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i, i);
glVertex3i(i, i, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i, i + k);
glVertex3i(i, i + k, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i, i, i + k);
glVertex3i(i + k, i, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i + k, i + k, i + k);
glVertex3i(i + k, i + k, i);
glEnd();

glBegin(GL_LINES);
glVertex3i(i + k, i + k, i + k);
glVertex3i(i, i + k, i + k);
glEnd();
glBegin(GL_LINES);
glVertex3i(i + k, i + k, i + k);
glVertex3i(i + k, i, i + k);
glEnd();
}
void ulica_prymitywow()
{
glTranslatef(-5, 0, 0);
klocek(3);

glTranslatef(-1, 0, -4);
klocek(4);
glTranslatef(1, 0, -3);
klocek(3);
glTranslatef(10, 0, 7.5);
klocek(2);
glTranslatef(0, 0, -3);
klocek(3);
glTranslatef(0, 0, -4);
klocek(4);
}
void move_scene()
{
GLdouble T[16] = { 1, 0, 0, move,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
glMultMatrixd(T);
};
void scale_scene()
{
GLdouble T[16] = { scale, 0, 0, 0,
0, scale, 0, 0,
0, 0, scale, 0,
0, 0, 0, 1 };
//mnożenie macierzy widoku
glMultMatrixd(T);
}
void rotate_scene()
{
double cosinusx = cos(rotatex);
double sinusx = sin(rotatex);
GLdouble Tx[16] = { 1,    0,            0,                0,
0,    cosinusx,    -sinusx,        0,
0,    sinusx,        cosinusx,        0,
0,    0,            0,                1 };
glMultMatrixd(Tx);
double cosinusy = cos(rotatey);
double sinusy = sin(rotatey);
GLdouble Ty[16] = { cosinusy,        0,        sinusy,            0,
0,                1,        0,                0,
-sinusy,        0,        cosinusy,        0,
0,                0,        0,                1 };
glMultMatrixd(Ty);

double cosinusz = cos(rotatez);
double sinusz = sin(rotatez);
GLdouble Tz[16] = { cosinusz,        -sinusz,        0,        0,
sinusz,            cosinusz,        0,        0,
0,                0,                1,        0,
0,                0,                0,        1 };
glMultMatrixd(Tz);
}
void Display()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glTranslatef(0, 0, -(cutnear + cutfar) / 2);
rotate_scene();
move_scene();

scale_scene();
ulica_prymitywow();

glFlush();
glutSwapBuffers();
}
void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(TR);
Display();
}
void Keyboard(unsigned char key, int x, int y)
{
if (key == 'n')
move += 0.01;

else if (key == 'm')
move -= 0.01;

else if (key == '+')
scale += 0.01;

else if (key == '-')
scale -= 0.01;

Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}
void SpecialKeys(int key, int x, int y)
{
switch (key)
{

case GLUT_KEY_LEFT:
rotatey -= 0.1;
break;
case GLUT_KEY_UP:
rotatex -= 0.1;
break;
case GLUT_KEY_RIGHT:
rotatey += 0.1;
break;
case GLUT_KEY_DOWN:
rotatex += 0.1;
break;
case GLUT_KEY_PAGE_UP:
rotatez += 0.1;
break;
case GLUT_KEY_PAGE_DOWN:
rotatez -= 0.1;
break;
}
Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
}
enum
{
EXIT
};
void Menu(int wartosc)
{
switch (wartosc)
{
case EXIT:
exit(0);
}
}
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutCreateWindow("Ulica prymitywów");
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutSpecialFunc(SpecialKeys);
glutKeyboardFunc(Keyboard);
glutCreateMenu(Menu);
glutAddMenuEntry("Exit", EXIT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}; ```

您必须转置矩阵。特别是move_scene:

void move_scene()
{
GLdouble T[16] = { 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
move, 0, 0, 1 };
glMultMatrixd(T);
};

OpenGL矩阵以列主顺序存储。代码中的行不是行,而是列:

column 1:  { 1, 0, 0, 0,
column 2:    0, 1, 0, 0,
column 3:    0, 0, 1, 0,
column 4:    move, 0, 0, 1 };

最新更新