原来是悟净 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 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解