WebGL differs from OpenGL preprocessor on same graphics stack - opengl-es

I just come upon an interesting effect by Chrome's use of the GLSL compiler. The statement
#define addf(index) if(weights[i+index]>0.) r+=weights[i+index]*f##index(p);
does not compile stating
preprocessor command must not be preceded by any other statement in that line
It seems that the ## syntax is unsupported.
However, on the same platform (eg. Linux 64bit, Nvidia GPU) the same shader compiles and runs fine. Why this? I thought the shader compiler is part of the GPUs driver stack and would be used in both cases. So why this different experience?

Actually WebGL is also quoted as "OpenGL ES 2.0 for the Web", so there are some differences to OpenGL.
The WebGL spec ( https://www.khronos.org/registry/webgl/specs/1.0/ ) tells us:
"A WebGL implementation must only accept shaders which conform to The OpenGL ES Shading Language, Version 1.00."
Looking into the GLSL ES 1.0 spec ( https://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf ) I found:
Section 3.4 defines the preprocessor and also states "There are no number sign based operators (no #, ##, ##, etc.), nor is there a sizeof operator."
So whatever the browser's implementation does internally, it follows the standard :)

WebGL implementations needs to conform the WebGL specifications. Many restrictions are needed for security issues. The ## issue is not, but anyway not correct by the WebGL specs.
To conform, they can either use a graphics stack that fully conform (for example by providing a wrapper to an unextended OpenGL ES profile if the driver exhibits those) or by prechecking the GLSL shader code and WebGL state itself to ensure conformity before passing the comamnds to some full OpenGL implementation.
So the WebGL behaviour may differ from the native OpenGL behaviour on the same machine.

That's because on Windows, Chrome does not use the OpenGL driver by default. It uses Direct3D, and the translation from OpenGL to Direct3D is done by the ANGLE project.
ANGLE has its own shader validator and preprocessor. And hence you can see differences between Windows and other operating systems even though you're using the same hardware. ANGLE was created because on Windows the Direct3D support is typically much better than the OpenGL support, and because it allows more control over the implementation and its conformance.

Related

Difference in opengl es programming for PowerVR and Mali GPU chipsets

I am developing a framework using OpenGL ES to create 3D applications.
I need to deploy the framework in both PowerVR and Mali GPUs chip-sets.
Is there any aspects to be taken care in programming OpenGL ES for different GPUs (PowerVR and Mali)?
The only significant difference is that the older Mali cores (Mali-300/400 series) only support mediump in the fragment shader, so algorithms relying on highp precision won't work there.
There are surely fine tuning differences, but hard to give a succinct answer to that one. Just focus on writing good clean GL and it should work well everywhere.

OpenGL es 2.0 glDrawElements Implementation

OpenGLes 2.0 does not have support for special built-in fragment shader variable called gl_PrimitiveID. I tried to simulate this variable by associating a unique attribute with each of the vertices forming a triangle. But this causes problem when there is sharing of vertices between two or more triangles. It would effectively require duplication of shared vertices for this technique to work increasing memory usage for complex scenes.
I am thinking to make changes in the openGLes library itself so as to be able to maintain gl_PrimitiveID variable internally. I am using mesa 3d library for editing the source code of openGLes 2.0. But I am not able to locate the implementation of glDrawElements to serve my purpose. This function has GL_APIENTRY flag associated with its declaration.
Any suggestions?
OpenGL or OpenGL-ES are not libraries. They're system level APIs, which implementation is buried deep within the GPU's driver. You can't make changes to them, without messing around in a GPU driver's code. And then everybody who used your program had to use that driver. Which in the case of OpenGL-ES will be impossible to carry out, because most OpenGL-ES implementations live in devices that build walled gardens around applications. Also the driver's source codes are usually kept a secret.

Windows Store apps Shader model 4_0_level_9_3 and VPOS

In order to build shaders for Windows Store apps (and Windows Phone 8) Shader model 4_0_level_9_3 you need to use the vs_4_0_level_9_3 and ps_4_0_level_9_3 . While all this sounds fine using the HLSL syntax designed for DirectX 10 and up, I'm unable to use the VPOS semantic from DirectX 9 or use SV_POSITION from DirectX 10 and up in a pixel shader, so what do I do besides making yet another semantic for outputting the vertex position in clip space ?
PS: Some shaders on 4_0_level_9_3 spit out an "internal error: blob content mismatch between level9 and d3d10 shader" which I have no idea what is about. Probably some inconsistency with the driver I suppose ( I use an Nvidia GTX 560 TI) that I see it goes away if you just compile your shaders with release flags (like optimization level 3 and avoid flow control).
Your best bet is, as you say, to pass these values as secondary semantics (i.e. pass both a "POSITION" and a "SV_POSITION" value). Note that if you place SV_POSITION at the end of the output declaration for the vertex shader, you may omit it from the input declaration for the pixel shader.
Regarding the internal error, this is typically due to the declaration of a texture or other shader input that is optimized out in one pass but not in another. Disabling optimization typically works around the issue, but you should also be able to fix it by eliminating unused (including via dead-code elimination) input declarations, and ensuring you avoid complicated code that reduces to no-op.

glPushMatrix and OpenGL ES

I have a question regarding [glPushMatrix], together with the matrix transformations, and OpenGL ES. The GLSL guide says that under OpenGL ES, the matrices have to be computed:
However, when developing applications in modern versions of OpenGL and
OpenGL ES or in WebGL, the model matrix has to be computed.
and
In some versions of OpenGL (ES), a built-in uniform variable
gl_ModelViewMatrix is available in the vertex shader
As I understood, gl_ModelViewMatrix is not available under all OpenGL ES specifications. So, are the functions like glMatrixMode, glRotate, ..., still valid there? Can I use them to calculate the model matrix? If not, how to handle those transformation matrices?
First: You shouldn't use the matrix manipulation functions in regular OpenGL as well. In old versions they're just to inflexible and also redundant, and in newer versions they've been removed entirely.
Second: The source you're mentioning is a Wikibook which means it's not a authorative source. In the case of this Wikibook it's been written to accomodate for all versions of GLSL, and some of them, mainly for OpenGL-2.1 have those variables.
You deal with those matrices by calculating them yourself (no, this is not slower, OpenGL's matrix stuff was not GPU accelerated) and pass them to OpenGL either by glLoadMatrix/glMultMatrix (old versions of OpenGL) or a shader uniform.
If you're planning on doing this in Android, then take a look at this.
http://developer.android.com/reference/android/opengl/Matrix.html
It has functions to setup view, frustum, transformation matrices as well as some matrix operations.

Is ARB_texture_multisample available for OpenGL ES 2.0?

Basically, what is needed to perform multisampled deferred shading.
To expand a bit: I'm not actually all that interested in Deferred shading per se, but what is of key importance is allowing the storage and retrieval of sub-pixel sample data for antialiasing purposes: I need to be able to control the resolve, or at least do some operations before resolving multisampled buffers.
All the major extensions for OpenGL ES are listed here: http://www.khronos.org/registry/gles/
And as far as I know currently no major OpenGL ES implmentations does not provide individual sample resolving using OpenGL ES. Only thing you can do is to copy multisampled texture to normal one, and the access "normal" samples.

Resources