Есть 2 файла, 

draw.h

#pragma once
#include <SDL.h>
#include <cassert>

// #include "mesh.h"
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <glm/gtx/normal.hpp>

#define TINYOBJLOADER_IMPLEMENTATION

#include "tiny_obj_loader.h"
// Screen dimension constants
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;

#define RGB32(r, g, b) static_cast<uint32_t>((((static_cast<uint32_t>(b) << 8) | g) << 8) | r)


void load_obj(std::string file, std::vector<glm::vec3> &vertices, std::vector<glm::uvec3> &faces)
{
    // load a Wavefront .obj file at 'file' and store vertex coordinates as vec3 and faces as uvec3 of indices
    tinyobj::attrib_t attrib;
    std::vector<tinyobj::shape_t> shapes;
    std::vector<tinyobj::material_t> materials;// necessary for function call, but will be discarded
    std::string err;
    std::string warning;

    // load all data in Obj file
    //'triangulate' option defaults to 'true' so all faces should be triangles
    bool success = tinyobj::LoadObj(&attrib, &shapes, &materials, &warning, &err, file.c_str());

    // boilerplate error handling
    if (!err.empty()) {
        // std::cerr << err << std::endl;
    }
    if (!success) {
        exit(1);
    }

    // convert the vertices into our format
    for (size_t vert = 0; vert < attrib.vertices.size() - 2; vert += 3) {
        vertices.push_back(
          glm::vec3(attrib.vertices[vert],
            attrib.vertices[vert + 1],
            attrib.vertices[vert + 2]));
    }

    // convert the faces into our format
    // faces should all be triangles due to triangulate=true
    for (size_t shape = 0; shape < shapes.size(); shape++) {
        std::vector<tinyobj::index_t> indices = shapes[shape].mesh.indices;
        for (size_t face = 0; face < indices.size() - 2; face += 3) {
            faces.push_back(
              glm::uvec3(indices[face].vertex_index,
                indices[face + 1].vertex_index,
                indices[face + 2].vertex_index));
        }
    }
}

class Object
{
  public:
    Object() {}// constructor
    void init(const char *objPath)
    {
        const float aspect = (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;

        load_obj(std::string(objPath), vertices, faces);

        Projection = glm::ortho(-1.0f, 1.0f, -1.0f * aspect, 1.0f * aspect, 0.1f, 200.0f);

        eye = glm::vec3(0, 0, 1);
        center = glm::vec3(0, 0, 0);
        up = glm::vec3(0, 1, 0);

        View = glm::lookAt(
          eye,// Camera is at (4,3,3), in World Space
          center,// and looks at the origin
          up// Head is up (set to 0,-1,0 to look upside-down)
        );

        // Model matrix : an identity matrix (model will be at the origin)
        Model = glm::mat4(1.0f);
        Model = glm::translate(Model, glm::vec3(0, 0, -5));// z = z - 5
    }

    void draw(SDL_Surface *s, SDL_Renderer *r)
    {
        glm::mat4 Device =
          glm::mat4(
            SCREEN_WIDTH / 2, 0, 0, 0,
            0, -SCREEN_HEIGHT / 2, 0, 0,
            0, 0, 1, 0,
            SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0, 1);

        glm::mat4 MVP = Projection * View * Model;

        {
            // Draw axis
            glm::vec4 pp;
            glm::mat4 M = Device * MVP;
            glm::vec4 p = M * glm::vec4(0, 0, 0, 1);
            glm::vec4 x = M * glm::vec4(1, 0, 0, 1);
            glm::vec4 y = M * glm::vec4(0, 1, 0, 1);
            glm::vec4 z = M * glm::vec4(0, 0, 1, 1);

           DrawCircle(r, p[0], p[1], 3);

            SDL_SetRenderDrawColor(r, 255, 0, 0, 0);
            SDL_RenderDrawLine(r, p[0], p[1], x[0], x[1]);
            SDL_SetRenderDrawColor(r, 0, 255, 0, 0);
            SDL_RenderDrawLine(r, p[0], p[1], y[0], y[1]);
            SDL_SetRenderDrawColor(r, 0, 0, 255, 0);
            SDL_RenderDrawLine(r, p[0], p[1], z[0], z[1]);

            SDL_SetRenderDrawColor(r, 0, 205, 205, 0);

            for (auto v : faces) {
                glm::vec4 p0 = M * glm::vec4(vertices[v[0]], 1);
                glm::vec4 p1 = M * glm::vec4(vertices[v[1]], 1);
                glm::vec4 p2 = M * glm::vec4(vertices[v[2]], 1);

                glm::vec3 n = glm::triangleNormal(vertices[v[0]], vertices[v[1]], vertices[v[2]]);

                {
                    DrawCircle(r, p0[0], p0[1], 3);
                    DrawCircle(r, p1[0], p1[1], 3);
                    DrawCircle(r, p2[0], p2[1], 3);
                    SDL_RenderDrawLine(r, p0[0], p0[1], p1[0], p1[1]);
                    SDL_RenderDrawLine(r, p1[0], p1[1], p2[0], p2[1]);
                    SDL_RenderDrawLine(r, p2[0], p2[1], p0[0], p0[1]);
                }
            }
        }
    }

    void DrawCircle(SDL_Renderer *renderer, int32_t centreX, int32_t centreY, int32_t radius)
    {
        const int32_t diameter = (radius * 2);

        int32_t x = (radius - 1);
        int32_t y = 0;
        int32_t tx = 1;
        int32_t ty = 1;
        int32_t error = (tx - diameter);

        while (x >= y) {
            //  Each of the following renders an octant of the circle
            SDL_RenderDrawPoint(renderer, centreX + x, centreY - y);
            SDL_RenderDrawPoint(renderer, centreX + x, centreY + y);
            SDL_RenderDrawPoint(renderer, centreX - x, centreY - y);
            SDL_RenderDrawPoint(renderer, centreX - x, centreY + y);
            SDL_RenderDrawPoint(renderer, centreX + y, centreY - x);
            SDL_RenderDrawPoint(renderer, centreX + y, centreY + x);
            SDL_RenderDrawPoint(renderer, centreX - y, centreY - x);
            SDL_RenderDrawPoint(renderer, centreX - y, centreY + x);

            if (error <= 0) {
                ++y;
                error += ty;
                ty += 2;
            }

            if (error > 0) {
                --x;
                tx += 2;
                error += (tx - diameter);
            }
        }
    }

    void translate(glm::vec3 val)
    {
        Model = glm::translate(Model, val);
    }

    void scale(float val)
    {
        Model = glm::scale(Model, glm::vec3(val, val, val));
    }

    void roate_z(float val)
    {
        // Model = glm::rotate(Model, val, glm::vec3(1, 1, 0));
        Model = glm::rotate(Model, val, glm::vec3(0, 0, 1));
    }

    void roate_x(float val)
    {
        // Model = glm::rotate(Model, val, glm::vec3(1, 1, 0));
        Model = glm::rotate(Model, val, glm::vec3(1, 0, 0));
    }

    void roate_y(float val)
    {
        // Model = glm::rotate(Model, val, glm::vec3(1, 1, 0));
        Model = glm::rotate(Model, val, glm::vec3(0, 1, 0));
    }

  private:
    void put_pixel32(SDL_Surface *surface, int x, int y, Uint32 pixel)
    {
        assert(NULL != surface);
        // assert(x < SCREEN_WIDTH);
        // assert(y < SCREEN_HEIGHT);

        Uint32 *pixels = (Uint32 *)surface->pixels;
        if (x < SCREEN_WIDTH && y < SCREEN_HEIGHT)
            pixels[(y * surface->w) + x] = pixel;
    }

    Uint32 get_pixel32(SDL_Surface *surface, int x, int y)
    {
        assert(NULL != surface);
        assert(x < SCREEN_WIDTH);
        assert(y < SCREEN_HEIGHT);

        Uint32 *pixels = (Uint32 *)surface->pixels;
        return pixels[(y * surface->w) + x];
    }

    //  Mesh m;
    std::vector<glm::vec3> vertices;
    std::vector<glm::uvec3> faces;
    glm::mat4 Projection;// Store the projection matrix
    glm::mat4 View;// Store the view matrix
    glm::mat4 Model;// Store the model matrix

    // camera
    glm::vec3 eye;
    glm::vec3 center;
    glm::vec3 up;
};

и main.cpp

#include "draw.h"

#include <SDL.h>
#include <stdio.h>
#include <string>
#include <cassert>
#include <glm/glm.hpp>
#include <glm/ext.hpp>

#include <stdlib.h>

bool init();
void close();

SDL_Window *gWindow = NULL;
SDL_Renderer *gRenderer = NULL;
SDL_Texture *gTexture = NULL;
SDL_Surface *loadedSurface = NULL;

bool init()
{
    bool success = true;
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
        success = false;
    } else {
        gWindow = SDL_CreateWindow("AOKG Lab 4", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        if (gWindow == NULL) {
            printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
            success = false;
        } else {
            gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_SOFTWARE);
            if (gRenderer == NULL) {
                printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError());
                success = false;
            } else {
                SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
            }
        }
    }
    return success;
}

void close()
{
    SDL_DestroyTexture(gTexture);
    gTexture = NULL;
    SDL_DestroyRenderer(gRenderer);
    SDL_DestroyWindow(gWindow);
    gWindow = NULL;
    gRenderer = NULL;
    SDL_Quit();
}

int main(int argc, char *argv[])
{
    if (!init()) {
        printf("Failed to initialize!\n");
    } else {
        loadedSurface = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32,
          0x00FF0000,// R
          0x0000FF00,// G
          0x000000FF,// B
          0x00000000);// alpha

        gTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);

        if (NULL == gTexture) {
            printf("Failed to load media!\n");
        } else {
            bool quit = false;
            SDL_Event e;
            Object obj1;
            obj1.init("C:/Users/i4ppt/Desktop/labexample-3d-mesh_Moded/res/stairs.obj");


            printf("!!");
            const float step = 0.05;
            int numObjects = 5;// Количество объектов для отрисовки
            float offset = 0.2;// Заданный сдвиг

            while (!quit) {
                while (SDL_PollEvent(&e) != 0) {
                    if (SDL_QUIT == e.type) {
                        quit = true;
                    }
                    if (SDL_KEYDOWN == e.type) {
                        switch (e.key.keysym.scancode) {
                        case SDL_SCANCODE_1:
                            obj1.scale(1.05);
                            break;
                        case SDL_SCANCODE_2:
                            obj1.scale(0.95);
                            break;
                        case SDL_SCANCODE_W:
                            obj1.roate_x(0.3);
                            break;
                        case SDL_SCANCODE_Q:
                            obj1.roate_y(0.3);
                            break;
                        case SDL_SCANCODE_E:
                            obj1.roate_z(0.3);
                            break;
                        case SDL_SCANCODE_UP:
                            obj1.translate(glm::vec3(0, step, 0));
                            break;
                        case SDL_SCANCODE_DOWN:
                            obj1.translate(glm::vec3(0, -step, 0));
                            break;
                        case SDL_SCANCODE_LEFT:
                            obj1.translate(glm::vec3(-step, 0, 0));
                            break;
                        case SDL_SCANCODE_RIGHT:
                            obj1.translate(glm::vec3(step, 0, 0));
                            break;
                        case SDL_SCANCODE_ESCAPE:
                            quit = true;
                            break;
                        default:
                            break;
                        }
                    }
                }
                SDL_SetRenderDrawBlendMode(gRenderer, SDL_BLENDMODE_BLEND);
                SDL_SetRenderDrawBlendMode(gRenderer, SDL_BLENDMODE_NONE);

                SDL_RenderClear(gRenderer);

                SDL_SetRenderDrawColor(gRenderer, 255, 255, 255, 0);
                SDL_RenderClear(gRenderer);
                SDL_SetRenderDrawColor(gRenderer, 0, 205, 205, 0);
                    obj1.draw(loadedSurface, gRenderer);
                SDL_RenderPresent(gRenderer);
            }
        }
    }
    close();
    return 0;
}


происходит отрисовка .obj файла stairs.obj, однако скомпилированный код отображает модель с эффектом x-ray, то есть я вижу грани которые по идее должны закрываться полигонами, сделай так чтобы эффекта x-ray не было. Я думаю необходимо использовать depth buffer и shading, помоги