跨越opengl和d3d的鸿沟(一):开篇

2024-05-10 12:32
文章标签 开篇 opengl d3d 鸿沟 跨越

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

原文地址


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

多年来,在论坛和各个网站上不断能看到拿OpenGL和D3D进行比较的帖子和文章。他们经常制造很多谜思,使得初学者和一些从业人员对OpenGL和D3D产生了各种各样的流言。

  1. 有人说,OpenGL直接调到驱动,性能高于D3D。
  2. 有人说,Shader都得写两套,很麻烦。
  3. 有人说,OpenGL和D3D在底层有很多区别,而且不可设置。
  4. 有人说,图形引擎如果要兼容两者,就只能取其功能的交集,最后还不如任何一种API。

真的么?

本文试图:

  • 找出现代OpenGL和D3D的共通之处
  • 归纳如何让API对上层代码尽量透明

本文不希望:

  • 讲解函数间的对应关系
  • 如何在OpenGL和D3D之间作选择
  • 贬低一方,抬高另一方

下面先从几个比较基本的方面来探讨如何跨越两个API的鸿沟。

架构

OpenGL和D3D的架构基本上是这个样子的:

The architecture of OGL and D3D

在架构上其实两者没有什么区别,只是D3D的runtime是在OS里,对于不同硬件来说都是一样的。而OpenGL的runtime直接是和驱动合为一体的。但这并不会造成性能有所差别,破解了流言1。

Shader

OpenGL 的原生shading language是GLSL,D3D的是HLSL。两者语法相似,但细节上天差地别。好在,NVIDIA的Cg在很大程度上类似于HLSL,而且可以编译 出GLSL来。所以,Cg编译器成了跨越这两种shader的桥梁。当然,要真正实用起来,还需要不少工作。比如Cg的Geometry Shader和HLSL 10+的有些许不同,需要通过#ifdef来分开。另外,Cg编译器生成的GLSL需要一些调整才能在ATI的驱动上工作,所以还需要多一次转换。好在这 些事情都可以通过程序自动完成,而且速度很快。具体可以参考KlayGE的OGLShaderObject::ConvertToGLSL。实际上,KlayGE的所有shader都只写了一份(语法用HLSL 11的),在不同API上可以自动编译成原生的shader使用(有OpenGL和OpenGL ES的编译器,曾经还有D3D9的)。这样就没有重写的繁琐,也没有增加runtime开销,破解了流言2。

当然,这里还有另一种更好的选择,把HLSL编译器生成的bytecode转换成GLSL。UE3等引擎用了MojoShader来完成这件事情。优点是不需要多次编译,缺点是不支持SM4+。

坐标系

初学者经常 说,OpenGL用右手坐标系,而D3D用左手;裁剪空间里OpenGL的z是[-1, 1],而D3D是[0, 1];不可调和。实际上,直接把左手的顶点和矩阵给OpenGL也是没有问题的。毕竟如果在VS里执行的都是mul(v, matrix),得到的会是同样的结果。可能会造成麻烦的反而是viewport的z。假设一个经过clip之后的顶点坐标为(x, y, z, w),那么在OpenGL上,该顶点经过viewport变换的z是(z/w + 1) / 2,而在D3D上则是z/w而已。这对于depth test不影响,但depth buffer里的值就不同了。所以需要对project matrix做一些调整,才能让他们写到depth buffer中的数值相同。具体来说,如果要让OpenGL流水线接受D3D的project matrix,就需要乘上

相当于把project space的顶点z都作了z = z * 2 – 1的操作,所以经过viewport变换就一致了。D3D到OpenGL的矩阵也可以依此类推。所以,在坐标系上,很容易就能使两者接受同样的输入,同时也没有增加runtime开销。

本篇讲的都是可以在不改变API的情况下,通过输入数据来消除OpenGL和D3D之区别。下一篇将讲解如何利用现代OpenGL提供的扩展和新功能,消除一些无法在上层解决的问题,继续破解各种流言。


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



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

相关文章

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

开篇: 为什么要做这个项目?

背景 最近工作中遇到一个需求需要实现一版在线的Web编辑器,类似 Vue Playground 的效果,但是Vue playground 整体体验下来不是很好,和本地 VSCode 编辑器开发体验差距较大(虽然理解在线编辑器没必要完全照着本地开发体验来)。 经过多方体验调研,发现目前的业界方案主要两种: 基于Monaco / Codemirror 实现,也是大多数场景使用的方案,但是效果却是参

浏览器工作原理(1)-开篇

本系列博客为学习《浏览器工作原理及实践》所笔记 开篇 浏览器的发展历程中的三个进化路线: 应用程序web化:B/S架构,视频、音频、游戏往web场景切换 web应用移动化:存在问题有渲染流程复杂,性能不够好,离线时用户无法使用,无法接受消息推送,不过PWA方案可以整合Web和本地程序的优势 Web操作系统化:两层含义:1 利用web技术构建一个纯粹的操作系统(ChromeOS);2

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