Bridge the gap between OpenGL and d3d (1): Opening

Source: Internet
Author: User
Reprinted please indicate the source for the klayge game engine, this article address for http://www.klayge.org/2011/07/15/%e8%b7%a8%e8%b6%8aopengl%e5%92%8cd3d%e7%9a%84%e9%b8%bf%e6%b2%9f%ef%bc%88%e4%b8%80%ef%bc%89%ef%bc%9a%e5%bc%80%e7%af%87/

Over the years, we have continuously seen posts and articles comparing OpenGL and d3d on forums and websites. They often make a lot of puzzles, so that beginners and some practitioners have a variety of rumors about OpenGL and d3d.

  1. Some people say that OpenGL is directly adjusted to the driver, and its performance is higher than that of d3d.
  2. Some people say that shader has to write two sets, which is very troublesome.
  3. Some people say that OpenGL and d3d have many differences at the underlying layer and cannot be set.
  4. Some people say that if the graphics engine needs to be compatible with the two, it can only take the intersection of its functions. In the end, it is not as good as any API.

Really?

This article tries:

  • Find out what modern OpenGL and d3d have in common
  • How to make the API as transparent as possible to the upper-Layer Code

This article does not want:

  • Describes the correspondence between functions.
  • How to choose between OpenGL and d3d
  • Belittle one party and raise the other

Next we will first discuss how to bridge the gap between the two APIs from several basic aspects.

Architecture

The architecture of OpenGL and d3d is basically like this:



 

In terms of architecture, there is actually no difference between the two, but the runtime of d3d is in the OS, which is the same for different hardware. While OpenGL's runtime is directly integrated with the driver. However, this does not cause performance differences. It cracked rumor 1.

Shader

The native shading language of OpenGL is glsl and that of d3d is HLSL. The two have similar syntaxes, but the details are different. Fortunately, NVIDIA's CG is very similar to HLSL, and can compile glsl. Therefore, the CG compiler serves as a bridge between the two Shader types. Of course, a lot of work is required to be practical. For example, the geometry shader of CG is somewhat different from that of HLSL 10 +, which must be separated by # ifdef. In addition, the glsl generated by the CG compiler requires some adjustments to work on the ATI driver. Therefore, an extra conversion is required. Fortunately, these tasks can be completed automatically through the program, and the speed is very fast. For details, refer to klayge's oglshaderobject: converttoglsl. In fact, all shader of klayge only writes one copy (the syntax uses HLSL 11 ), different APIs can be automatically compiled into Native shader for use (compilers with OpenGL and OpenGL ES, and those with d3d9 ). In this way, there is no tedious re-writing, and the runtime overhead is not increased. The rumor 2 is cracked.

Of course, there is another better option to convert the bytecode generated by the HLSL compiler into glsl. Ue3 and other engines use mojoshader to complete this task. The advantage is that it does not need to be compiled multiple times, but does not support sm4 +.

Coordinate System

Beginners often say that OpenGL uses the right-hand coordinate system, while d3d uses the left-hand coordinate system. In the cropped space, the Z of OpenGL is [-1, 1], while d3d is [0, 1]. irreconcilable. In fact, it is no problem to directly give the left-hand vertex and matrix to OpenGL. After all, if MUL (v, matrix) is executed in Vs, the same result will be obtained. It may cause trouble, but it is the Z of viewport. Assume that the coordinates of a vertex after clip are (X, Y, Z, W), then on OpenGL, the Z of the vertex after viewport transformation is (z/W + 1) /2, and z/W on d3d. This does not affect depth test, but the values in depth buffer are different. So we need to make some adjustments to the Project Matrix so that the values written to the depth buffer are the same. Specifically, if you want the OpenGL assembly line to accept the d3d Project Matrix, You need to multiply

It is equivalent to performing the z = z * 2-1 operation on the vertex Z of the project space, so it will be consistent after the viewport transformation. D3d to OpenGL matrices can also be pushed accordingly. Therefore, in the coordinate system, it is easy for both to accept the same input without increasing the runtime overhead.

This article describes how to use input data to eliminate the differences between OpenGL and d3d without changing the API. The next article explains how to use the extensions and new functions provided by modern OpenGL to eliminate problems that cannot be solved by the upper layer and continue to crack various rumors.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.