跨越opengl和d3d的鸿沟(三):交集?并集?

2024-05-10 12:32

本文主要是介绍跨越opengl和d3d的鸿沟(三):交集?并集?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址


转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=1290

上一篇讲到了如何填平OpenGL和D3D之间一些原本被认为位于底层的区别。本篇将剖析两个API在功能上的异同,以及直接相互访问的可能性。

功能

D3D9的功能早已被OpenGL 2.0所覆盖,网上可以找到很多资料,这里就不提了。本文注重的是新的GPU特性。下表列出了D3D10+的新功能,以及实现该功能所需要的OpenGL扩展或核心。

D3D 10的功能 OpenGL所对应的
Geomrtry shader GL_ARB_geometry_shader4或OpenGL 3
Stream output GL_EXT_transform_feedback或OpenGL 3
State对象 无,需要在上层封装GL_EXT_direct_state_access
Constant buffer GL_ARB_uniform_buffer_object或OpenGL 3
Texture array和新的资源格式 GL_EXT_texture_array
+GL_ARB_texture_compression_rgtc
+GL_ARB_texture_rg
+GL_ARB_texture_rgb10_a2ui
+GL_EXT_texture_integer或OpenGL 3
texture和sampler解偶 GL_ARB_sampler_objects或OpenGL 3
在shader里进行整数和位操作 GL_ARB_shader_bit_encoding或OpenGL 3
Multisampled alpha-to-coverage GL_NV_multisample_coverage或OpenGL 3
D3D 10.1的功能 OpenGL所对应的
读取multisample depth/stencil纹理 GL_ARB_texture_multisample或OpenGL 3
Cubemap array GL_ARB_texture_cube_map_array或OpenGL 4
gather4 GL_ARB_texture_gather或OpenGL 4
D3D 11的功能 OpenGL所对应的
Compute Shader GL_ARB_cl_event + OpenCL
Dynamic Shader Linkage GL_ARB_gpu_shader5或OpenGL 4
Multithreading
Tessellation GL_ARB_tessellation_shader或OpenGL 4

这些都是DX SDK文档里提到的功能,其他一些比较小的功能,也可以很容易找到OpenGL的对应。从上表可以看出,几乎所有D3D的功能都可以直接用相应的OpenGL功能代替,同时没有性能损失。需要重点讨论的是一些例外:

State对象

D3D 10新增了State对象,可以极大地减少由于改变渲染状态所需的系统调用次数。OpenGL中目前还没有State对象,所以只能在上层自行封装。虽然有些 性能损失,但接口可以和D3D统一起来。ARB针对OpenGL的State对象进行过旷日持久的讨论,还最终各大厂商没有达成一致。不过这是个趋势,相信不久的将来就会出个相关的扩展。到时候这个区别就能被完美地填平。

Compute Shader

D3D 11引入了compute shader,在D3D中直接提供了GPGPU的能力。OpenGL没有因此增加一种shader,而是增强和同门师弟OpenCL的互操作能力。 OpenGL和OpenCL能直接共享texture和buffer等,起到了和compute shader等价的功能。与GLSL和HLSL的关系一样,这里存在着shader语言不同的问题,而且没有Cg可以作为桥梁,目前只能写两份代码。

Multithreading

D3D 11的multithreading能力允许多个context都调用D3D11 API,每个context保存下来的API调用流可以在主context执行依次执行。OpenGL目前也没有引入该机制,需要在上层自行实现。话说回来了,目前的所有显卡 驱动都没有实现multithreading,所以所有多context都是由D3D runtime软件实现的,没有达到应有的提速效果。自己实现一个command list也能达到那样的性能。仍然希望某一天multithreading能成为OpenGL的功能 之一,简化上层的工作。

总结

所以说,OpenGL和D3D功能的交集几乎就是它们的并集,并不会因为需要兼容两者而失去很多功能。从功能上说,OpenGL和D3D之间的分歧甚至小于OpenGL和OpenGL ES。破解了第一篇说的流言4。

互操作

神奇扩展WGL_NV_DX_interop的出现,使得OpenGL可以正式与D3D进行互操作。(严格来说,互操作能力源自它的前身WGL_NVX_DX_interop,但鉴于他是个NVX实验性质的扩展,最好小心点用。)该扩展的目的是,在D3D中建立资源,而在 OpenGL中访问它。目前可以支持的是D3D9的纹理、render target和VB的读写。D3D10+的支持将在未来加入。两个API之间所需的同步也是自动完成的。

使用WGL_NV_DX_interop进行相互渲染的范例如下:

// 跟平常一样建立D3D设备和资源
d3d->CreateDevice(..., &d3dDevice);d3dDevice->CreateRenderTarget(width, height, D3DFMT_A8R8G8B8,D3DMULTISAMPLE_4_SAMPLES, 0,FALSE, &dxColorBuffer, NULL);d3dDevice->CreateDepthStencilSurface(width, height, D3DFMT_D24S8,D3DMULTISAMPLE_4_SAMPLES, 0,FALSE, &dxDepthBuffer, NULL);// 把D3D设备注册给OpenGLHANDLE gl_handleD3D = wglDXOpenDeviceNV(d3dDevice);// 把D3Drender target注册成OpenGL纹理对象GLuint names[2];
HANDLE handles[2];handles[0] = wglDXRegisterObjectNV(gl_handleD3D, dxColorBuffer,names[0], GL_TEXTURE_2D_MULTISAMPLE, WGL_ACCESS_READ_WRITE_NV);
handles[1] = wglDXRegisterObjectNV(gl_handleD3D, dxDepthBuffer,names[0], GL_TEXTURE_2D_MULTISAMPLE, WGL_ACCESS_READ_WRITE_NV);// 现在纹理就可以当成普通的OpenGL纹理来用了// D3D和OpenGL渲到同一个render targetdirect3d_render_pass(); // 和平常一样进行D3D渲染// 锁定render target,交给OpenGLwglDXLockObjectsNV(handleD3D, 2, handles);opengl_render_pass(); // 和平常一样进行OpenGL渲染wglDXUnlockObjectsNV(handleD3D, 2, handles);direct3d_swap_buffers(); // D3D present

这样两个API可以和谐共处了,但这个扩展目前仅限于NV的卡。

本篇讨论了两个API在功能上的交集和并集,以及互操作的方法。下一篇是本系列的结局,将讨论一些平台相关的问题,并进行系统性的总结。


这篇关于跨越opengl和d3d的鸿沟(三):交集?并集?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976448

相关文章

OPENGL顶点数组, glDrawArrays,glDrawElements

顶点数组, glDrawArrays,glDrawElements  前两天接触OpenGL ES的时候发现里面没有了熟悉的glBegin(), glEnd(),glVertex3f()函数,取而代之的是glDrawArrays()。有问题问google,终于找到答案:因为OpenGL ES是针对嵌入式设备这些对性能要求比较高的平台,因此把很多影响性能的函数都去掉了,上述的几个函数都被移除了。接

OpenGL ES学习总结:基础知识简介

什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库。 为桌面版本OpenGL 的一个子集。 OpenGL ES管道(Pipeline) OpenGL ES 1.x 的工序是固定的,称为Fix-Function Pipeline,可以想象一个带有很多控制开关的机器,尽管加工

OpenGL雾(fog)

使用fog步骤: 1. enable. glEnable(GL_FOG); // 使用雾气 2. 设置雾气颜色。glFogfv(GL_FOG_COLOR, fogColor); 3. 设置雾气的模式. glFogi(GL_FOG_MODE, GL_EXP); // 还可以选择GL_EXP2或GL_LINEAR 4. 设置雾的密度. glFogf(GL_FOG_DENSITY, 0

opengl纹理操作

我们在前一课中,学习了简单的像素操作,这意味着我们可以使用各种各样的BMP文件来丰富程序的显示效果,于是我们的OpenGL图形程序也不再像以前总是只显示几个多边形那样单调了。——但是这还不够。虽然我们可以将像素数据按照矩形进行缩小和放大,但是还不足以满足我们的要求。例如要将一幅世界地图绘制到一个球体表面,只使用glPixelZoom这样的函数来进行缩放显然是不够的。OpenGL纹理映射功能支持将

OpenGL ES 2.0渲染管线

http://codingnow.cn/opengles/1504.html Opengl es 2.0实现了可编程的图形管线,比起1.x的固定管线要复杂和灵活很多,由两部分规范组成:Opengl es 2.0 API规范和Opengl es着色语言规范。下图是Opengl es 2.0渲染管线,阴影部分是opengl es 2.0的可编程阶段。   1. 顶点着色器(Vert

Java8特性:分组、提取字段、去重、过滤、差集、交集

总结下自己使用过的特性 将对象集合根据某个字段分组 //根据id分组Map<String, List<Bean>> newMap = successCf.stream().collect(Collectors.groupingBy(b -> b.getId().trim())); 获取对象集合里面的某个字段的集合 List<Bean> list = new ArrayList<>

hutool 集合相关交集、差集

开发过程中会遇到集合之间的对比之类的需求,之前经常会自己写个工具类来实现,目前hutool可以帮助我们解决很多问题,接下来我们就来实践下。 相关jar包 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>RELEASE</version><scope>compile</sco

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

OpenGL——着色器画一个点

一、 绘制 在窗口中间画一个像素点: #include <GL/glew.h>#include <GLFW/glfw3.h>#include <iostream>using namespace std;#define numVAOs 1GLuint renderingProgram;GLuint vao[numVAOs];GLuintcreateShaderProgram (){c

试用GLFW并创建OpenGL和DX的环境

介绍GLFW GLFW官网:https://www.glfw.org/ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan development on the desktop. It provides a simple API for creating windows, contex