sphere-group / pegasus

The Pegasus API for Sphere 2.0
BSD 2-Clause "Simplified" License
1 stars 0 forks source link

Shader standard? #20

Open fatcerberus opened 9 years ago

fatcerberus commented 9 years ago

I know it was mentioned at some point by somebody (probably @FlyingJester) that shaders weren't part of the standard in order to keep them an optional feature and let the engine implement it as the developer sees fit.

However, with minisphere now supporting shaders and TurboSphere working up to it, this might be worthwhile to revisit. We can keep shader support optional but still standardize it. It would just get a separate extension designation than the core Galileo API.

I would propose that any standard for this be designed in a way such that new shader types can be added in the future without breaking backwards compatibility.

FlyingJester commented 9 years ago

My original intent was something like this:

var vertex_shader = new Shader("vertex.glsl", VERTEX_SHADER); var fragment_shader = new Shader("fragment.glsl", FRAGMENT_SHADER); var shader_program = new ShaderProgram(vertex_shader, fragment_shader);

The usage of shader_program would then be the same as how the object returned by GetDefaultShaderProgram is used.

As far as using different version of GLSL, the intent was that the constructor would throw an exception if the Shader didn't compile (for whatever reason), and the same if a ShaderProgram didn't link properly.

I had intended the order to not matter in the ShaderProgram constructor, that way you could provide them in either order, and later if/when Geometry shaders are supported you could just add them on the end.

Using an array for the input of the ShaderProgram constructor would also make sense.

Of course, this API has not been tested much (very late versions of the old graphics plugin had a similar API).

fatcerberus commented 9 years ago

For the record, this is how it is presently implemented in minisphere:

var shader = new ShaderProgram({
    fragment: 'fragment.glsl',
    vertex: 'vertex.glsl'
})

I was originally going to have separate VertexShader and FragmentShader constructors, but the way Allegro is set up, they would just have been boxed source code strings; no errors could be reported until ShaderProgram() is invoked. Allegro requires you to attach all the shader sources to the same shader object in order to compile them. From what I understand, this is because D3D HLSL shaders--which Allegro also supports--are monolithic, with pixel and vertex (and presumably whatever other types it supports) provided together in the same source. There is no linking to speak of--everything is done in a single step.

FlyingJester commented 9 years ago

That makes sense for supporting HLSL. In fact, the way Pegasus is set up, you could support HLSL instead of OpenGL.

In GL, you compile the shaders individually, and then link them into a program. In simple setups it's really no different than one step, but in larger ones it lets you reuse just the fragment or vertex shader, or one of the geometry shaders.

Can you supply OpenGL shader program names to Allegro directly? If not, it probably would just be fine to only report compilation errors on linking.

fatcerberus commented 9 years ago

I don't believe you can pass GL object names to Allegro APIs, however Allegro doesn't stop you from calling into OpenGL directly as far as I'm aware.

fatcerberus commented 8 years ago

I'm thinking we should standardize on names for the standard uniforms. Currently writing a shader for minisphere requires attribute/uniforms with names like al_tex, al_projview_matrix, etc. because that's where Allegro puts those parameters by default (this can be circumvented, I was just lazy) which of course won't work if you try to use the shader with a non-Allegro engine.

Here's what I'm thinking, we keep things simple:

Not sure whether texture coordinates should be texcoord or just uv.

Any other ideas?

FlyingJester commented 8 years ago

I think they should be namespaced a little. Maybe ss_, like how Sphere 1.x namespaces internal features, or just s_ for Sphere. Even GLSL namespaces their own variables in glsl.

I would opt for texcoord over uv, since that's how OpenGL's API actually refers to UV, and it's more obvious to beginners (coordinates on the texture) than just the letters U and V.

fatcerberus commented 8 years ago

What are the requirements for GetDefaultShaderProgram()? The shader is 2D, XY is in screen space, but what about UV? Just the OpenGL standard (+x right +y up), or something else?

FlyingJester commented 8 years ago

Yes, the UV are passed directly as Tex Coords into the shader.

The only real work the default shader does is to convert screen coords to normalized GL coordinates for positions, and to apply color masking.

fatcerberus commented 8 years ago

@FlyingJester Do you still think shader support should be an extension (i.e. optional), or would you say GPU support for shaders is ubiquitous enough now that it can be a core part of the Sphere v2 API?

FlyingJester commented 8 years ago

Well, I had two main concerns about it being core originally.

One is that I didn't like making a DirectX, Direct3D, legacy OpenGL, or whatever other API graphics plugin that wouldn't really have access to glsl that much harder to use (in the case of DirectX though, it would probably through the use of ANGLE, or just expose a 'hlsl' extension instead of 'glsl').

Two, there are a lot of different version of glsl, and I felt it would be better to deal with how to query and test for which versions are available.

I suppose at this point, being able to query the glsl version, and maybe for shading extensions would address my original concerns.