OpenGL重叠丑陋的渲染

2024-02-27

我正在尝试使用 OpenGL 2.1 渲染场景,但重叠形状的边框很奇怪。我测试了一些 OpenGL 初始化,但没有任何改变。我将问题简化为一个简单的测试应用程序,其中有 2 个球体,但结果相同。

我尝试了一些关于 Gl_DEPTH_TEST 的事情,启用/禁用平滑但没有成功。

这是我使用 2 个 gluSphere 的结果:

当一条线足以分隔蓝色和红色的面时,我们可以看到某种锯齿......

I use SharpGL https://github.com/dwmkerr/sharpgl/tree/master/source/SharpGL/Core/SharpGL但我认为这并不重要(因为我仅将它用作 OpenGL 包装器)。这是我渲染相同内容的最简单的代码(您可以将其复制到表单中进行测试):

OpenGL gl;
IntPtr hdc;
int cpt;

private void Init()
{
    cpt = 0;
    hdc = this.Handle;

    gl = new OpenGL();
    gl.Create(SharpGL.Version.OpenGLVersion.OpenGL2_1, RenderContextType.NativeWindow, 500, 500, 32, hdc);

    gl.Enable(OpenGL.GL_DEPTH_TEST);
    gl.DepthFunc(OpenGL.GL_LEQUAL);

    gl.ClearColor(1.0F, 1.0F, 1.0F, 0);
    gl.ClearDepth(1);

    gl.MatrixMode(OpenGL.GL_PROJECTION);
    gl.Perspective(30, 1, 0.1F, 1.0E+7F);

    gl.MatrixMode(OpenGL.GL_MODELVIEW);
    gl.LookAt(0, 3000, 0, 0, 0, 0, 0, 0, 1);
}

private void Render(int angle)
{
    gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

    RenderSphere(gl, 0, 0, 0, 0, 300, Color.Red);
    RenderSphere(gl, 0, 0, 100, angle, 300, Color.Blue);

    gl.Blit(hdc);
}

private void RenderSphere(OpenGL gl, int x, int y, int z, int angle, int radius, Color col)
{
    IntPtr obj = gl.NewQuadric();

    gl.PushMatrix();
    gl.Translate(x, y, z);
    gl.Rotate(angle, 0, 0);

    gl.Color(new float[] { col.R / 255f, col.G / 255f, col.B / 255f, col.A / 255f });
    gl.QuadricDrawStyle(obj, OpenGL.GLU_FILL);
    gl.Sphere(obj, radius, 20, 10);

    gl.Color(new float[] { 0, 0, 0, 1 });
    gl.QuadricDrawStyle(obj, OpenGL.GLU_SILHOUETTE);
    gl.Sphere(obj, radius, 20, 10);

    gl.DeleteQuadric(obj);

    gl.PopMatrix();
}

预先感谢您的建议!

EDIT :

我测试了一下没有成功:

gl.Enable(OpenGL.GL_LINE_SMOOTH);
gl.Enable(OpenGL.GL_POLYGON_SMOOTH);
gl.ShadeModel(OpenGL.GL_SMOOTH);

gl.Hint(OpenGL.GL_LINE_SMOOTH_HINT, OpenGL.GL_NICEST);
gl.Hint(OpenGL.GL_POLYGON_SMOOTH_HINT, OpenGL.GL_NICEST);
gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST);

EDIT2:有更多面孔,有或没有线条的图像

它……不同……但并不令人愉快。


这个问题有2个原因。

第一个确实是一个Z-战斗 https://en.wikipedia.org/wiki/Z-fighting问题是由近平面和远平面之间的巨大距离引起的

gl.Perspective(30, 1, 0.1F, 1.0E+7F);

事实上,在透视投影中,深度不是线性的。也可以看看如何线性渲染深度... https://stackoverflow.com/questions/7777913/how-to-render-depth-linearly-in-modern-opengl-with-gl-fragcoord-z-in-fragment-sh/45710371#45710371.

这可以通过将近平面尽可能靠近几何体来改进。由于到物体的距离为 3000.0 并且球体的半径为 300,因此近平面必须小于 2700.0:

e.g.

gl.Perspective(30, 1, 2690.0F, 5000.0F);

第二个问题是由球体由三角形基元组成的事实引起的。正如您在答案中所建议的,您可以通过增加基元的数量来改进这一点。

我将通过使用剪切平面提供替代解决方案。夹住底部的红色球体和顶部的蓝色球体。正好在球体相交的平面上,以便从每个球体上切掉一个盖子。
剪裁平面可以通过以下方式设置glClipPlane https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glClipPlane.xml并通过以下方式启用glEnable.
剪裁平面的参数被解释为平面方程 http://www.songho.ca/math/plane/plane.html。 平面方程的前 3 个分量是剪切平面的法向量。第四个分量是到原点的距离。

所以红色球体的剪切平​​面方程必须是{0, 0, -1, 50}对于蓝色球体{0, 0, 1, -50}.
注意,当glClipPlane被调用,然后通过模型视图矩阵的逆来变换方程。因此,必须在模型转换(如旋转、平移和缩放)之前设置裁剪平面。

e.g.

private void Render(int angle)
{
    gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

    double[] plane1 = new double[] {0, 0, -1, 50};
    RenderSphere(gl, 0, 0, 0, 0, 300, Color.Red, plane1);

    double[] plane2 = new double[] {0, 0, 1, -50};
    RenderSphere(gl, 0, 0, 100, angle, 300, Color.Blue, plane2);

    gl.Blit(hdc);
}
private void RenderSphere(
    OpenGL gl, int x, int y, int z, int angle, int radius,
    Color col, double[] plane)
{
    IntPtr obj = gl.NewQuadric();

    gl.ClipPlane(OpenGL.GL_CLIP_PLANE0, plane);
    gl.Enable(OpenGL.GL_CLIP_PLANE0);

    gl.PushMatrix();
    gl.Translate(x, y, z);
    gl.Rotate(angle, 0, 0);

    gl.Color(new float[] { col.R / 255f, col.G / 255f, col.B / 255f, col.A / 255f });
    gl.QuadricDrawStyle(obj, OpenGL.GLU_FILL);
    gl.Sphere(obj, radius, 20, 10);

    gl.Color(new float[] { 0, 0, 0, 1 });
    gl.QuadricDrawStyle(obj, OpenGL.GLU_SILHOUETTE);
    gl.Sphere(obj, radius, 20, 10);

    gl.DeleteQuadric(obj);

    gl.PopMatrix();

    gl.Disable(OpenGL.GL_CLIP_PLANE0);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL重叠丑陋的渲染 的相关文章

  • 帧缓冲区/颜色缓冲区?

    有人可以指出我两者是否相同吗 我的意思是我一直在阅读有关它的信息 这里的红皮书说 颜色缓冲区本身可以由多个子缓冲区组成 系统上的帧缓冲区包含所有这些缓冲区 here http glprogramming com red chapter10
  • 如何在 SceneKit 中以编程方式将 png 纹理包裹在立方体周围

    我是 SceneKit 的新手 试图让一些基本的东西工作 但到目前为止还没有取得多大成功 由于某种原因 当我尝试将 png 纹理应用于 CNBox 时 我最终除了黑色之外什么也没有 这是我在 viewDidLoad 中的简单代码片段 let
  • glColor4f() - alpha 值的效果

    我正在使用 glColor4f 令人惊讶的是 更改 alpha 即第四个参数 不会导致透明度发生任何变化 代码段是 const GLfloat squareVertices 0 5 0 5 0 0 0 5 0 5 0 0 0 5 0 5 0
  • OpenGL 使用着色器将 NV12 转换为 RGB24

    我尝试编写一个应用程序来在 OpenGL 中显示 YUV 图像 我使用此代码片段在 C 中成功将 Y UV 转换为 RGB source https blog csdn net subfate article details 4730514
  • 移动/调整大小期间 opengl 窗口冻结

    我正在使用 LWJGL 开发游戏 移动窗口时 计划将来添加调整大小代码 渲染循环冻结 我希望它在移动时继续以某种方式运行 LWJGL 不包括 glutMainLoop Display属于OpenGL 而不是Java 相关代码 regular
  • OpenGL:VAO 和 VBO 对于大型多边形渲染任务是否实用?

    如果您想渲染一次在视锥体中包含数千个多边形的大型景观 并且用户的视点不断变化 那么使用 VAO 或 VBO 是否实用 我的意思是 每次玩家的位置或摄像机旋转发生变化时 您都必须重新计算顶点数据 以便正确剔除不再可见的任何顶点或场景 以保持良
  • matplotlib:渲染到缓冲区/访问像素数据

    我想使用 matplotlib 生成的图作为 OpenGL 中的纹理 到目前为止 我遇到的 matplotlib 的 OpenGL 后端要么不成熟 要么已经停止使用 所以我想避免使用它们 我当前的方法是将图形保存到临时 png 文件中 并从
  • 具有交错缓冲区的 openGL glDrawElements

    到目前为止 我只使用了 glDrawArrays 并希望转向使用索引缓冲区和索引三角形 我正在绘制一个有点复杂的对象 其中包含纹理坐标 法线和顶点坐标 所有这些数据都收集到一个交错的顶点缓冲区中 并使用类似于以下的调用进行绘制 假设所有血清
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • OpenSceneGraph 将相机设置在初始位置

    我是第一次使用 OpenSceneGraph 我有点迷失 因为文档确实不太清楚 所以 我有这段代码加载一个带有房子的 obj 文件 并且我在我想要的 人 所在的地方淹没了一个小盒子 所以现在 我不想把那个盒子放在那里 而是想把相机放在那里
  • 使用 gl_FragColor 与 vec4 颜色?

    似乎有很多不明确的地方gl FragColor被弃用 例如 它缺失在GLSL 4 40 规范 https www khronos org registry OpenGL specs gl GLSLangSpec 4 40 pdf 但它包含在
  • Windows 上的 OpenGL SDK

    我正在尝试编写一个 OpenGL 应用程序 因此我安装了 Windows 7 SDK 然而 它似乎是OpenGL 1 1 define GL VERSION 1 1 1 如何找到我安装的 OpenGL 版本 dll 以及在哪里可以找到较新的
  • 仅在发布模式下使用 glGenBuffer 时出现未处理的异常 - QT

    我在 Windows 7 上使用 Qt 4 8 发布模式编译项目时遇到了一些问题 调试时一切正常 但在发布时我收到未处理的异常 0xC0000005 访问冲突 我将范围缩小到发生这种情况的行 即生成像素缓冲区的时间 我的第一个猜测是 DLL
  • Retina 显示屏中具有 QOpenGLWIdget 的 Qt MainWindow 显示错误大小

    我有一个 Qt 应用程序MainWindow 我嵌入一个QOpenGLWidget在里面 一切正常 直到我开始使用 Apple Retina 显示屏并在高 DPI 模式下运行我的应用程序 我的QOpenGLWidget只是它应该具有的大小的
  • 无法在 Linux 的 NetBeans 中编译 C++ 和 OpenGL (GLFW) 的简单源代码

    我开始学习 OpenGL glfw 我从教程中复制源代码并尝试编译它 但出现了错误 我想我已经正确安装了所有头文件 glm glfw 等 这是我的来源 我没有在头文件中使用这些字符 include iostream include stdi
  • glTranslatef 不在 glBegin .. glEnd 中工作

    我正在尝试并排绘制不同颜色的两个方块 我的问题是我无法让 glTranslatef 将第二个方块向右移动 第二个方块只是绘制在第一个方块上 void display void glClear GL COLOR BUFFER BIT glMa
  • 如何在 R 中导入并绘制三角形网格?

    我想在 R 中绘制我的模型输出 它是格式为的三角形网格 x1 y1 z1 x2 y2 z2 x3 y3 z3 value 每行代表一个三角形 我想用以下方法绘制这些三角形value作为规模 mymesh lt structure c 0 9
  • 在 OpenGL 中设置 MVP 矩阵

    我正在尝试学习 OpenGL 的基础知识 但我在设置变换矩阵时遇到问题 我制作了模型 视图和投影矩阵 但将它们发送到我的顶点着色器时遇到问题 这是代码 Set up MVP glm mat4 model glm mat4 GLint uni
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 程序执行期间Apache-Spark出现超时异常

    我正在 MAC 中运行 Bash 脚本 该脚本多次调用用Scala语言编写的spark方法 我目前正在尝试使用 for 循环调用此 Spark 方法 100 000 次 在运行少量迭代 大约 3000 次迭代 后 代码退出并出现以下异常 o
  • 在 Jenkins 上构建多项目 Gradle

    我有一个在 Mercurial 存储库中托管的 Gradle 多项目 我想以这样的方式设置我的 Jenkins 如果我只将更改提交到 1 个子项目 那么只有该子项目将被构建并发布到我的 Nexus 存储库 有人可以给我提示吗 或者说这完全有
  • Spring MVC(或 Spring Boot)。针对安全相关异常的自定义 JSON 响应,例如 401 Unauthorized 或 403 Forbidden)

    我正在开发 REST 服务 它使用 JSON 并且必须返回一些预定义的 JSON 对象 以防出现问题 默认的 Spring 响应如下所示 timestamp 1512578593776 status 403 error Forbidden
  • 如何从java实例化在scala中定义的嵌套泛型类?

    我试图从 Java 实例化一个嵌套通用 Scala 类并遇到此编译错误 有人可以帮忙吗 谢谢 外部 scala class Outer class Inner A sctest java public class sctest public
  • HTML 标签表到文本字段 - JasperReport

    我有一个使用 html 标记语言或样式的参数输入到文本字段 但是当我放置标签时 它根本不显示 Jaspersoft 支持的 thid 标签 b b u u i i font font
  • 如何结合对称加密和非对称加密?

    在谈论非对称加密时 人们经常说 由于某些原因 您不应该对整个消息进行非对称加密 例如性能考虑 通常建议的工作流程是 创建对称加密的随机密钥 使用此随机密钥加密消息 使用非对称加密对随机密钥进行加密 将加密消息和加密密钥发送给接收者 到目前为
  • Azure 逻辑应用 - 用于部署文件系统 API 连接的 ARM 模板

    我正在尝试使用 ARM 模板部署文件系统 API 连接 我找不到此连接的parametersValue架构 因此尝试按照Azure门户上显示的参数命名它们 在 Azure 门户上编辑 API 连接屏幕截图1 https i stack im
  • 用自己的实现和信任管理器替换 SSLContext 默认值

    基于 Jcs 的回答 HttpUnit WebConversation SSL 问题 https stackoverflow com questions 4868654 httpunit webconversation ssl issues
  • 如何使用 Java 以编程方式签署二进制 MS Office 文档?

    我们如何在 Apache POI 或任何其他开源库中对旧版二进制 MS Office 文档 doc xls ppt 进行数字签名 Open XML 格式包含在如何使用 Java 以编程方式签署 MS Office XML 文档 https
  • 使用 GridLayout 搞乱计算器

    我在使布局看起来漂亮方面遇到了麻烦 为了了解基础知识 我决定创建一个简单的计算器应用程序 因此 我使用嵌套在 LinearLayout 中的 GridLayout 将按钮放置在文本字段下 这是我的布局的来源
  • UIView 上圆形层的快速遮罩

    我试图用圆形 CAShapeLayer 快速掩盖方形 UIView 我有以下内容 var snapFrame self snapButton frame var innerFrame CGRect x snapFrame minX 1 y
  • 如何使用 CompletableFuture 并行运行多个服务调用?

    我正在向用户返回以下响应 class FinalResponseDTO List
  • Pygame PNG 图像看起来已损坏

    我正在跟进本指南 http www nerdparadise com tech python pygame basics part2 尝试在 Pygame 窗口中显示基本的 PNG 图像 我的图像是一个简单的 150x150 绿球 没有透明
  • 无法反序列化 lambda

    就像一个小项目一样 我一直在尝试制作一个小东西 读取序列化的 lambda 本地或从 FTP 并调用它们的运行函数作为测试的一部分 以试验 Windows 中的文件关联 即打开某些文件类型 用某个程序打开它们 等等 但无论我尝试什么 它似乎
  • getDimension()/getDimensionPixelSize() - 乘数问题

    所以我有 android 2 3 5 设备 它是 NORMAL HDPI 我的项目中有一个dimens xml
  • 从临时服务器连接到 GitoLite 时出错 - ECONNREFUSED 部署错误

    我在尝试将以前工作的项目部署到开发服务器时遇到了一些麻烦 我没有设置系统 但我确实拥有我需要的所有凭据 我认为 在尝试 cap staging 部署之后 我到目前为止 然后它产生了一个错误 请看下面 triggering load call
  • sed 用 C++ 注释替换(单行)C 注释

    我如何使用 sed 将源文件中的所有 C 风格注释替换为 C 风格 所有这些 int main some comments to int main some comments 所有注释都是单行 并且代码之间没有像这样的注释 int f in
  • 多层神经网络不会预测负值

    我已经实现了一个多层感知器来预测输入向量的正弦 这些向量由随机选择的四个 1 0 1 组成 偏差设置为 1 网络应该预测向量内容之和的 sin 例如 输入 输出 Sin 0 1 1 0 1 我遇到的问题是网络永远不会预测负值 并且许多向量的
  • 初始化 tkinter 类的父级/主控是什么?

    Note 示例代码是一个删节版本 但可以运行基本功能 请重点关注class MainWindow tk Frame 问题 什么样的object可以起到parent or master for tkinter class初始化 我的例子 看示
  • OpenGL重叠丑陋的渲染

    我正在尝试使用 OpenGL 2 1 渲染场景 但重叠形状的边框很奇怪 我测试了一些 OpenGL 初始化 但没有任何改变 我将问题简化为一个简单的测试应用程序 其中有 2 个球体 但结果相同 我尝试了一些关于 Gl DEPTH TEST