3

I'm new to OpenGL, SDL and OBJ-files and am fighting with an issue for many days now.

  1. setting up the SDL-Window (i've dropped the basic SDL-Init-stuff)

    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 );
    
  2. Starting the OpenGL functionality (where "obj" is my class for parsing OBJ and loading Texture)

    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 );
    
  3. a short look into the OBJ-file... (no vn - normals in it)

    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
    .
    .
    .
    
  4. Texture comes as BMP file with resolution 1024x1024

OBJ texture image:

enter image description here

  1. running the display loop

    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) );
    }
    
  2. ...comes to this results:

Results: OpenGL-object in SDL-window:

enter image description here

below picture resulted from changing one display-code-line to:

    glTranslatef( 0.0, 1.0, -19.5 );

My aim is to "fit" in the "OpenGL thing" (what's it called...? Model? Framebuffer? Object?) into the bounds of the SDL-window. Or maybe "resize" the SDL-window to the OpenGL object. Why? Because in the next step I'm "exporting" the whole SDL-window to a bitmap that is going to be used as digitize background in a GIS-software for georeferencing purposes.

Do I have to change the view-settings or is there a possibility to "grab" the size of the OpenGL object for adapting the SDL main window?

For example if I change one line in the displaying code to:

    glTranslatef( 0.0, 1.0, -19.5 );

What are exactly the "coordinates" of the vertices "v" in the OBJ file? Which "measurement unit" do they own? Is it a local coosys?

What is the textured OpenGL object "pixel-size" (because the pixel-size of the texture template is 1024x1024)??

Many of the codelines I took from online tutorials, but I'm not sure how they affect my screen in detail. I'm too confused of all the possibilities to change views etc.

So any help is appreciated. This gives me bad sleep...

Sabuncu
  • 5,095
  • 5
  • 55
  • 89
peha1968
  • 31
  • 4
  • So, you want to fit/stretch your OBJ model so that it fits the screen size exactly? Since you're using a perspective projection, as far as I know you need to calculate the object's horizontal dimensions, calculate the Z distance from the camera to the closest point, determine the view frustum dimensions at that Z depth and scale the object to fit. Maybe someone knows an easier way... You could always use an ortho projection so you don't get the perspective distortion. – aslg May 13 '16 at 10:37
  • When I use the glOrtho version (in the code above commented out) I see nothing at all in my SDL view, only the grey background, so that's because I use the perspective code...I assume that the object is outside the SDL window then or I've totally screwed up with my glOrtho parameters. – peha1968 May 13 '16 at 10:52
  • Ah I didn't see you had an ortho commented. Indeed, your object was both too small to be visible and too far deep to be rendered. Set your ortho like this `glOrtho( -512, 512, -384, 384, -16, 16 )`. This ortho will match your window size (assuming it is 1024x768?) and allow objects within [-16,16] Z to be seen, probably more than enough for your object. Remove your object translation and instead scale your object, e.g `gl Scalef( 100.0f, 100.0f, 1.0f )`. Then work on finding the right scale to fit the window. – aslg May 13 '16 at 11:18
  • Thank you, this was indeed very helpful. glOrtho and glScalef are affecting the results dramatically. Now I have more "feeling" for manipulating my view and perspective and am getting better results. Could you explain the "Z" value? Is it corresponding with the 3rd vertex coordinate from the OBJ? – peha1968 May 13 '16 at 13:41

1 Answers1

1

One way you could do that is, find the object dimensions (iterate through all pixels and determine the minimum and maximum values in each axis), find the depth of the object relative to the camera viewpoint and the view-frustum dimensions at that depth. Finally you can find the best scale to apply to your object so that it covers the entire screen.

But that is complicated. It would be easier to utilize an orthographic projection and then "play around" with the scale of your object. You can still find the object dimensions as I mentioned above for a direct way to do this. Use these:

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

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

This should allow you to see your object with an orthographic projection. From here you should be able to tweak the scale values until you get what you want.


Could you explain the "Z" value?

First off it's my mistake. It's not exactly a Z value but a depth value.

By default, when you specify a viewing volume in OpenGL whether using an orthographic or perspective projection, the "camera" will be looking in the direction of the negative Z axis. You can change the direction using the lookAt function, but in your example you don't so you get the default view direction. For this reason you'll often see Z-Depth being used.

An orthographic projection defines a cube/prism viewing-volume whose effect is that all objects, no matter how far from the viewer, will appear at the same scale. The last 2 arguments of the glOrtho function are the near and far values, define the depth of the viewing volume. In the comments I sugested using:

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

Since, by default, the camera is looking in the negative Z direction, centered at 0, we can see objects within the volume in a relative depth of [-16,16]. That is:

At a near value of |-16 * (0,0,-1)| = 16 and a far value of |16 * (0,0,-1)| = -16.

Example ortho viewing volume

What are exactly the "coordinates" of the vertices "v" in the OBJ file?

It's likely that they are in object coordinates (object space), which define the position of each vertex relative to the object itself, with the origin at 0,0,0. So yes, a local coordinate system of the object. When you apply transforms to an object, namely translations, the resulting values will be in world coordinates (world space).

Do I have to change the view-settings or is there a possibility to "grab" the size of the OpenGL object for adapting the SDL main window?

That is up to you to decide. But it might make more sense to scale your object to fit the window than the other way around. I showed you a way to scale the object.

What is the textured OpenGL object "pixel-size" (because the pixel-size of the texture template is 1024x1024)??

When referring to texture pixels we call them texels. But I don't understand what you're asking.

(what's it called...? Model? Framebuffer? Object?)

I guess you mean the 3D Object / Model that you're rendering with a texture. See Default Framebuffer and Framebuffer to be sure.

aslg
  • 1,966
  • 2
  • 15
  • 20