opengl 将SDL窗口调整为对象大小

busg9geu  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(129)

设置SDL窗口:

sdl_window = SDL_CreateWindow(
                           "Viewer",
                           SDL_WINDOWPOS_UNDEFINED,
                           SDL_WINDOWPOS_UNDEFINED,
                           1024,
                           768,
                           SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
if( sdl_window == NULL )
    printf("SDL_CreateWindow failed: %s\n", SDL_GetError());

SDL_GLContext glContext = SDL_GL_CreateContext( sdl_window );
if( glContext == NULL )
    printf("SDL_GL_CreateContext failed: %s\n", SDL_GetError());

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

启动OpenGL功能(obj是我用来解析.obj文件和加载纹理的类):

int         my_object;
objloader   obj;

glClearColor( 0.5f, 0.5f, 0.5f, 1.0f );
glViewport( 0, 0, 1024, 768 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45, 1024.0/768.0, 1.0, 500.0 );
//glOrtho( 0, 512, 384, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glEnable( GL_DEPTH_TEST );

my_object = obj.load( "D:\myfile.obj" );

glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
float col[] = {1.0,1.0,1.0,1.0};
glLightfv( GL_LIGHT0, GL_DIFFUSE, col );

.obj文件:

mtllib ./test.mtl
usemtl Haufwerk
v -0.388155 5.580893 2.490415
v -0.336669 5.566026 2.507601
v -0.408834 5.515674 2.533414
v -0.403397 5.444500 2.540850
v -0.482161 5.577362 2.447329
.
.
.
v -0.533898 5.328258 1.909646
v -0.439773 5.344517 1.849366
vt 0.710938 0.273924
vt 0.711743 0.270957
vt 0.712080 0.277021
vt 0.713371 0.278851
vt 0.711261 0.303822
.
.
.
vt 0.845899 0.687021
vt 0.841930 0.687169
f 5616/687 5617/688 4642/686
f 5617/691 5618/692 4642/690
f 5616/687 4642/686 5618/689
f 5617/688 5616/687 5618/689
f 12657/633 12659/634 13191/637
.
.
.

纹理为.bmp文件,分辨率为1024x1024:

显示循环:

while( running )
{
    start = SDL_GetTicks();

    while( SDL_PollEvent(&event) )
    {
        switch(event.type)
        {
            case SDL_QUIT:
                running = false;
                break;
        }
    }

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity();
    float pos[] = {-1.0,1.0,-2.0,1.0};
    glLightfv( GL_LIGHT0, GL_POSITION, pos );
    //glScalef( 1.f, 1.f, 1.f );
    glTranslatef(0.0, -30.0,-20.0);
    //glTranslatef( 10.0, 10.0, -50.0 );
    //glTranslatef( 0.0, 1.0, -19.5 );
    glCallList( myobject ); //and display it

    SDL_GL_SwapWindow( sdl_window );

    if( 1000/30 > (SDL_GetTicks() - start) )
        SDL_Delay( 1000/30 - (SDL_GetTicks() - start) );
}

SDL窗口中的对象:

将一行更改为:

glTranslatef( 0.0, 1.0, -19.5 );

我的目标是使模型适合窗口的边界或调整窗口的大小。我出口的窗口,以位图作为背景的地理信息系统软件。我是否必须更改视图设置或如何获取OpenGL对象的大小以适应窗口?.obj文件中顶点“v”的坐标是什么?什么计量单位?什么是纹理OpenGL对象的像素大小?

yrdbyhpb

yrdbyhpb1#

一种方法是,找到对象尺寸(遍历所有像素并确定每个轴上的最小值和最大值),找到对象相对于相机视点的深度以及该深度处的视锥尺寸。最后,您可以找到应用于对象的最佳比例,以便它覆盖整个屏幕。
但这很复杂。这将是更容易利用正交投影,然后“玩”与比例的对象。你仍然可以找到我上面提到的对象尺寸,这是一种直接的方法。使用这些:

glOrtho( -512, 512, -384, 384, -16, 16 );

// Remove the translations you were applying to your object
glScalef( 100.0f, 100.0f, 1.0f );

这将允许您使用正交投影查看对象。从这里你应该能够调整比例值,直到你得到你想要的。
你能解释一下Z值吗
首先这是我的错它不是一个Z值,而是一个 * 深度 * 值。
默认情况下,当您在OpenGL中指定一个视见体时,无论是使用正交投影还是透视投影,“相机”都将沿负Z轴方向观察。您可以使用lookAt函数更改方向,但在您的示例中,您没有这样做,因此您将获得默认的视图方向。因此,您经常会看到使用 Z-Depth
正交投影定义了一个立方体/棱镜视见体,其效果是所有对象,无论离观察者多远,都将以相同的比例出现。glOrtho函数的最后两个参数是nearfar值,定义了视见体积的 * 深度 *。在我建议使用的评论中:

glOrtho( -512, 512, -384, 384, -16, 16 )

由于默认情况下,相机在负Z方向上观察,以0为中心,因此我们可以看到体积内相对深度为[-16,16]的对象。即:
在近值|-16 * (0,0,-1)| = 16和远值|16 * (0,0,-1)| = -16处。

OBJ文件中顶点“v”的“坐标”到底是什么?
它们很可能位于对象坐标(对象空间)中,对象坐标定义了每个顶点相对于对象本身的位置,原点为0,0,0。所以是的,物体的局部坐标系。当您对对象应用变换(即平移)时,结果值将以世界坐标(世界空间)表示。
我是否必须更改视图设置,或者是否有可能“抓取”OpenGL对象的大小以适应SDL主窗口?
这由你来决定。但是,缩放对象以适应窗口可能比相反更有意义。我给你们展示了一种缩放物体的方法。
什么是纹理OpenGL对象的“像素大小”(因为纹理模板的像素大小是1024 x1024)??
当提到纹理像素时,我们称它们为 texels。但我不明白你在问什么。
(what是不是叫.?模型?帧缓冲器?反对?)
我猜你指的是你用纹理渲染的3D对象/模型。请参阅Default FramebufferFramebuffer以确保。

相关问题