原来是悟净 2022-08-09 16:10 采纳率: 100%
浏览 29
已结题

opengl边框检测不完整

opengl 用模板缓冲在做边框检测出现边框不完整的情况请问该如何进行处理?

看了 https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/02%20Stencil%20testing/
教程中说的,但是依旧没有找到解决办法。

img

代码:

  // 深度测试、模板测试
  glEnable(GL_DEPTH_TEST);
  // 当前片段值小于缓冲深度值
  glDepthFunc(GL_LESS);
  // 开启模板测试
  glEnable(GL_STENCIL_TEST);
  // 绘制箱子上模板值不为1的部分
  glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
  // 片段通过测试该如何操作
  glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

/////////////渲染循环内/////////////////////////////////////
  while (!glfwWindowShouldClose(window))
  {
    float currentFrame = static_cast<float>(glfwGetTime());
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;

    processInput(window);

    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

    shaderSingleColor.use();
    glm::mat4 model = glm::mat4(1.0f);
    glm::mat4 view = camera.GetViewMatrix();
    glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    shaderSingleColor.setMat4("view", view);
    shaderSingleColor.setMat4("projection", projection);

    shader.use();
    shader.setMat4("view", view);
    shader.setMat4("projection", projection);

    // 先将所有的都设置为0 因为我不想让所有的都产生线框(此处为对面禁用)
    glStencilMask(0x00); // 禁用写入

    glBindVertexArray(planeVAO);
    glBindTexture(GL_TEXTURE_2D, floorTexture);
    shader.setMat4("model", glm::mat4(1.0f));
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindVertexArray(0);

    // 此处让模型具有线框
    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    glStencilMask(0xFF);

    glBindVertexArray(cubeVAO);
    // 激活给定的纹理单元
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, cubeTexture);
    model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
    shader.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
    shader.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 36);

    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilMask(0xFF);

    // 禁用深度测试 不会被地板覆盖
    glDisable(GL_DEPTH_TEST);
    shaderSingleColor.use();
    float scale = 1.01f;
    // cubes
    glBindVertexArray(cubeVAO);
    glBindTexture(GL_TEXTURE_2D, cubeTexture);
    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
    model = glm::scale(model, glm::vec3(scale, scale, scale));
    shaderSingleColor.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    
    /* 不显示线框 */
    //glStencilFunc(GL_NOTEQUAL, 1, 0x00);
    //glStencilMask(0x00);

    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
    model = glm::scale(model, glm::vec3(scale, scale, scale));
    shaderSingleColor.setMat4("model", model);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

    glStencilMask(0xFF);
    glStencilFunc(GL_ALWAYS, 0, 0xFF);
    glEnable(GL_DEPTH_TEST);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  • 写回答

1条回答 默认 最新

  • 原来是悟净 2022-08-10 11:26
    关注

    已解决,上面的实现是,先一起绘制两个cube实体,在进行绘制两个边框cube,最终所产生的效果就是两个边框是链接的。要想绘制完整的边框需要,绘制一个实体在绘制一个边框,之后清除模板缓冲,这样依次绘制问题就解决了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月19日
  • 已采纳回答 8月11日
  • 创建了问题 8月9日

悬赏问题

  • ¥20 keepalive配置业务服务双机单活的方法。业务服务一定是要双机单活的方式
  • ¥50 关于多次提交POST数据后,无法获取到POST数据参数的问题
  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)
  • ¥100 在连接内网VPN时,如何同时保持互联网连接
  • ¥15 MATLAB中使用parfor,矩阵Removal的有效索引在parfor循环中受限制
  • ¥20 Win 10 LTSC 1809版本如何无损提升到20H1版本
  • ¥50 win10 LTSC 虚拟键盘不弹出
  • ¥30 微信小程序请求失败,网页能正常带锁访问
  • ¥15 Matlab求解微分方程,如何用fish2d进行预优?