проблема с тестом глубины, не работает тест глубины когда рендерю в текстуру, OpenGL

Рейтинг: 1Ответов: 0Опубликовано: 08.01.2023

рендер карты глубины и использование ее как тени работает отлично, но хочу внедрить в свою программу post processing, но сетка которую отобразил на текстуре имеет проблемы с тестом глубины: введите сюда описание изображения

введите сюда описание изображения код программы:

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
    SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_OPENGL);
    SDL_Event* event = new SDL_Event();
    SDL_SetWindowResizable(window, SDL_TRUE);
    SDL_GL_CreateContext(window);
    glewInit();

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_CULL_FACE);

    Shader* render = new Shader("shaders/render/vertex.glsl", "shaders/render/fragment.glsl"); // шейдер для отображение сцены с тенями (2-й проход)
    Shader* depth = new Shader("shaders/depth/vertex.glsl", "shaders/depth/fragment.glsl"); // шейдер для отображения карты глубины (1-й проход, делается 3 раза для 3-х уровней теней)
    Shader* pp = new Shader("shaders/pp/vertex.glsl", "shaders/pp/fragment.glsl"); // шейдер пост процессинг

    Mesh* mesh = loadObj("mesh/obj/monkey.obj");
    Mesh* plane = loadObj("mesh/obj/plane.obj");

    int w;
    int h;
    SDL_GetWindowSize(window, &w, &h);
    glViewport(0, 0, w, h);

    double now = 0.0f;
    double last = 0.0f;
    double dtime = 0.0f;
    double time = 0.0f;
    int fps = 0;

    float lrx = -45.0f;
    float lry = 45.0f;
    mat4* lproj = new mat4[3]
    {
        ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.1f, 100.0f),
        ortho(-30.0f, 30.0f, -30.0f, 30.0f, 0.1f, 100.0f),
        ortho(-90.0f, 90.0f, -90.0f, 90.0f, 0.1f, 100.0f)
    };
    vec3 f = vec3(0.0f, 0.0f, -1.0f);
    vec3 u = vec3(0.0f, 1.0f, 0.0f);
    mat4 rx = rotate(mat4(1.0f), radians(-45.0f), vec3(1.0f, 0.0f, 0.0f));
    mat4 ry = rotate(mat4(1.0f), radians(45.0f), vec3(0.0f, 1.0f, 0.0f));
    mat4 lwrld = lookAt(vec3(0.0f, 0.0f, 0.0f), vec3(ry * rx * vec4(f, 1.0f)), vec3(ry * rx * vec4(u, 1.0f)));

    int sw = 2048;
    int sh = 2048;

    unsigned int stexId;
    glGenTextures(3, &stexId);
    unsigned int sfboId;
    glGenFramebuffers(3, &sfboId);
    for (int i = 0; i < 3; i++)
    {
        glBindTexture(GL_TEXTURE_2D, stexId + i);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, sw, sh, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
        glBindTexture(GL_TEXTURE_2D, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, sfboId + i);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, stexId + i, 0);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    unsigned int pptexId; // текстура для пост процессинга
    glGenTextures(1, &pptexId);
    glBindTexture(GL_TEXTURE_2D, pptexId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);
 
    unsigned int ppfboId; // кадровый буффер для пост процессинга
    glGenFramebuffers(1, &ppfboId);
    glBindFramebuffer(GL_FRAMEBUFFER, ppfboId);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pptexId, 0);
    glGenFramebuffers(1, 0);

    vec3 cameraOrigin = vec3(0.0f, 2.0f, 5.0f);
    float cameraRotationX = 0.0f;
    float cameraRotationY = 0.0f;

    bool open = true;
    while (open)
    {
        while (SDL_PollEvent(event))
        {
            switch (event->type)
            {
            case SDL_WINDOWEVENT:
                switch (event->window.event)
                {
                case SDL_WINDOWEVENT_CLOSE:
                    open = false;
                    break;
                case SDL_WINDOWEVENT_RESIZED:
                    SDL_GetWindowSize(window, &w, &h);
                    glBindTexture(GL_TEXTURE_2D, pptexId);
                    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_FLOAT, 0);
                    glBindTexture(GL_TEXTURE_2D, 0);
                    break;
                }
                break;
            }
        }
        vec3 cameraFront = vec3(0.0f, 0.0f, -1.0f);
        vec3 cameraBack = vec3(0.0f, 0.0f, 1.0f);
        vec3 cameraLeft = vec3(-1.0f, 0.0f, 0.0f);
        vec3 cameraRight = vec3(1.0f, 0.0f, 0.0f);
        mat4 cameraRotationXMatrix = rotate(mat4(1.0f), radians(cameraRotationX), vec3(1.0f, 0.0f, 0.0f));
        mat4 cameraRotationYMatrix = rotate(mat4(1.0f), radians(cameraRotationY), vec3(0.0f, 1.0f, 0.0f));
        cameraFront = vec3(cameraRotationYMatrix * cameraRotationXMatrix * vec4(cameraFront, 1.0f));
        cameraBack = vec3(cameraRotationYMatrix * cameraRotationXMatrix * vec4(cameraBack, 1.0f));
        cameraLeft = vec3(cameraRotationYMatrix * cameraRotationXMatrix * vec4(cameraLeft, 1.0f));
        cameraRight = vec3(cameraRotationYMatrix * cameraRotationXMatrix * vec4(cameraRight, 1.0f));
        if (GetAsyncKeyState('W') & 0x8000)
        {
            cameraOrigin += cameraFront * (float)dtime;
        }
        if (GetAsyncKeyState('S') & 0x8000)
        {
            cameraOrigin += cameraBack * (float)dtime;
        }
        if (GetAsyncKeyState('D') & 0x8000)
        {
            cameraOrigin += cameraRight * (float)dtime;
        }
        if (GetAsyncKeyState('A') & 0x8000)
        {
            cameraOrigin += cameraLeft * (float)dtime;
        }
        if (GetAsyncKeyState(VK_LEFT) & 0x8000)
        {
            cameraRotationY += (float)dtime * 45.0f;
        }
        if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
        {
            cameraRotationY -= (float)dtime * 45.0f;
        }
        if (GetAsyncKeyState(VK_DOWN) & 0x8000)
        {
            cameraRotationX -= (float)dtime * 45.0f;
            cameraRotationX = max(cameraRotationX, -90.0f);
        }
        if (GetAsyncKeyState(VK_UP) & 0x8000)
        {
            cameraRotationX += (float)dtime * 45.0f;
            cameraRotationX = min(cameraRotationX, 90.0f);
        }
        // первый проход (3 раза)
        for (int i = 0; i < 3; i++)
        {
            glBindFramebuffer(GL_FRAMEBUFFER, sfboId + i);
            glEnable(GL_DEPTH_TEST);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glViewport(0, 0, sw, sh);
            glCullFace(GL_FRONT);
            depth->use();
            depth->setMat4("projection", lproj[i]);
            lwrld = lookAt(cameraOrigin, cameraOrigin + vec3(ry * rx * vec4(f, 1.0f)), vec3(ry * rx * vec4(u, 1.0f)));
            depth->setMat4("worldview", lwrld);
            mesh->render(render);
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
        }
        // второй проход
        glBindFramebuffer(GL_FRAMEBUFFER, ppfboId);
        glEnable(GL_DEPTH_TEST);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glViewport(0, 0, w, h);
        glCullFace(GL_BACK);
        render->use();
        render->setMat4("projection", perspective(70.0f, (float)w / (float)h, 0.1f, 100.0f));
        render->setMat4("worldview", lookAt(cameraOrigin, cameraOrigin + cameraFront, cross(cameraBack, cameraRight)));
        render->setMat4("lprojection0", lproj[0]);
        render->setMat4("lprojection1", lproj[1]);
        render->setMat4("lprojection2", lproj[2]);
        render->setMat4("lworldview", lwrld);
        render->setVec3("origin", cameraOrigin);
        render->setVec3("sunDir", -vec3(ry * rx * vec4(f, 1.0f)));
        render->setInt("shadowMap0", 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, stexId);
        render->setInt("shadowMap1", 1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, stexId + 1);
        render->setInt("shadowMap2", 2);
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, stexId + 2);
        mesh->render(render);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        // третий проход
        glDisable(GL_DEPTH_TEST);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glViewport(0, 0, w, h);
        pp->use();
        pp->setInt("frame", 0);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, pptexId);
        plane->render(render);
        

        SDL_GL_SwapWindow(window);
        now = getTime();
        dtime = now - last;
        last = now;
        time += dtime;
        fps++;
        if (time > 1.0)
        {
            time = 0.0;
            printf("fps %i\n", fps);
            fps = 0;
        }
    }
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Ответы

Ответов пока нет.