【问题标题】:OpenGL compute level of detail [closed]OpenGL计算细节级别[关闭]
【发布时间】:2021-09-07 07:10:07
【问题描述】:

我尝试将一些线条渲染到纹理,然后对它们进行 mipmap。但是当我缩小整个事情时,它并没有我想要的那么详细。如何获得较低的纹理分辨率?我尝试了一个有一点弯曲的三角形。所以当我缩小 50% 时,它看起来就像一个正常的三角形。反正有没有像这样渲染它?由于我对 OpenGL 的经验非常低,我将向您发布整个代码。 版本: 发光 2.1.0 OpenGL 4.6

代码:

    SDL_Window* window;
    SDL_Init(SDL_INIT_EVERYTHING);

    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_ALPHA_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    window = SDL_CreateWindow("BA", SDL_WINDOWPOS_CENTERED, 
    SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_OPENGL);

    SDL_GLContext glContext = SDL_GL_CreateContext(window);

    std::vector<Vertex> vertices;
    vertices.push_back(Vertex{ -0.5f,-0.5f });
    vertices.push_back(Vertex{ 0.0f,0.8f });
    vertices.push_back(Vertex{ 0.0f,0.8f });
    vertices.push_back(Vertex{ 0.0f,0.5f });
    vertices.push_back(Vertex{ 0.0f,0.5f });
    vertices.push_back(Vertex{ 0.5f, -0.5f });
    vertices.push_back(Vertex{ 0.5f, -0.5f });
    vertices.push_back(Vertex{ -0.5f,-0.5f });



    GLenum err = glewInit();

    //Framebuffer
    GLuint FramebufferName = 0;
    glGenFramebuffers(1, &FramebufferName);
    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);


    //Texture
    GLuint renderedTexture;
    glGenTextures(1, &renderedTexture);
    glBindTexture(GL_TEXTURE_2D, renderedTexture);
    

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    /*glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);*/

    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);


    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);

    // Set the list of draw buffers.
    GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
    glDrawBuffers(1, DrawBuffers);

    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
    glViewport(0, 0, 1920, 1080);


    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(struct Vertex, x));

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glViewport(0, 0, 1920, 1080);


    glScalef(0.9f, 0.9f, 1.0f);
    glTranslatef(1.0f, 1.0f, 0.0f);
    

    bool closeFlag = false;
    while (!closeFlag) {


        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_LINES, 0, vertices.size());

        SDL_GL_SwapWindow(window);

        /*GLenum error = glGetError();
        std::cout << "Error: " << error;*/

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                closeFlag = true;
            }
            if (event.key.keysym.sym == SDLK_DOWN) {
                glScalef(0.95f, 0.95f, 1.0f);

            }
            if (event.key.keysym.sym == SDLK_UP) {
                glScalef(1.05f, 1.05f, 1.0f);
            }
        }
    }

输出: Actual Output

期望的输出: Desired output

【问题讨论】:

  • this 不是想要的输出吗?
  • 您想要做的与 mipmapping 无关(至少在一般情况下)。你想要的是一些几何级别的细节,这是你必须自己实现的东西,没有神奇的 GL 函数可以自动执行你的意思。

标签: c++ opengl sdl glew


【解决方案1】:

首先阅读glGenerateMipmap的描述。
如需更深入地了解 mipmapping 及其实现方式:OpenGl Specification 8.14.3 Mipmapping

为了达到(看到)您想要的结果,您必须进一步缩小。一路走来,可能会出现缩小的图像,这是您所期望的。

纹理过滤的微调可以通过glTexParameter和不同的参数来完成,例如:

  • GL_TEXTURE_BASE_LEVEL
  • GL_TEXTURE_LOD_BIAS
  • GL_TEXTURE_MIN_FILTER
  • GL_TEXTURE_MAG_FILTER
  • GL_TEXTURE_MIN_LOD
  • GL_TEXTURE_MAX_LOD
  • GL_TEXTURE_MAX_LEVEL

您也可以通过glTexStorage2DglTexSubImage2D 自己生成mipmap,但这需要两个纹理对象和多个渲染步骤(将缩小的图像渲染到纹理A,上传到特定级别的纹理B;另见glCopyTexImage2DglCopyTexSubImage2D)。

你也可以做几何细节层次(更多here)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多