Difference between "attribute" and "layout(location=x) in" in opengl - glsl

They both can transfer vertex data, but what is the difference between them?
Do them work in a similar way?

attribute is a qualifier for input variables.
From the OpenGL Wiki page:
The attribute qualifier is effectively equivalent to an input qualifier in vertex shaders.
In other words, they're equivalent (in is the input qualifier), but do note that this applies to attribute:
The following qualifiers are deprecated as of GLSL 1.30 (OpenGL 3.0) and removed from GLSL 1.40 and above.
The layout qualifier lets you specify the variable's locations directly, avoiding the need to use glBindAttribLocation, or these can be used to match variables from (e.g.) vertex shader to fragment shader instead of using name matching, among other uses.

Related

GL_SHADING_LANGUAGE_VERSION returns a single language

when using glGetString on the enum GL_SHADING_LANGUAGE_VERSION I get only one value for return, while I was expecting space separated values as with glGetString(GL_EXTENSIONS).
what is even more confusing is that when I use glGetIntegerv(GL_NUM_SHADING_LANGUAGE_VERSIONS, *); I get a number bigger than one, and when I use glGetStringi(GL_SHADING_LANGUAGE_VERSION, i), and iterate over them I can get all the values. So, why don't I get all the values with glGetString(GL_SHADING_LANGUAGE_VERSION). I just get one value
It is this way because that's how the feature was originally defined. All GLSL versions are backwards compatible with prior ones, so the expectation was that if you had a 1.10 shader, you could feed it to any implementation that accepted 1.10 or higher.
But with the break between core and compatibility, that become untenable. Making core implementations tacitly support GLSL shaders that included removed constructs made no sense. So there had to be a way for an implementation to specify exactly which GLSL versions it supported. But they couldn't change the existing version string's definition, so they (eventually) just added a new, indexed-based query.

What does the suffix on the end of glGetProgramiv signify?

glGetProgramiv is referenced inside the documentation as glGetProgram but no mention is made of there being multiple versions - and I see no indication through google of there being other versions such as glGetProgrammiii or glGetProgramii. Is the iv prefix roman numerals related to some type of internal versioning during the specifications process or does it hold some other significance?
Those suffixes are used to distinguish "overloaded" methods with same names and different parameters. iv means this version operates on vector of integers. It's the only version of glGetProgram at the moment.

Where do glsl interpolation qualifiers go?

GLSL interpolation qualifiers can be used in various places: https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)#Interpolation_qualifiers
But it isn't really explained whether they have to match (e.g. vertex out and fragment in) resp. what happens if they don't. The compiler does not seem to complain.
How interpolation qualifiers work with regard to interface matching has shifted in OpenGL over the various versions.
Pre-GL 4.3, interpolation qualifiers on inputs must match the corresponding output variable's interpolation qualifier from the preceding stage. Post-4.3, matching is unnecessary.
In both cases, it's reasonable to say that the only qualifiers the compiler will care about are the ones specified by the fragment shader's input variables. After all, in the pre-GL 4.3 case that requires exact matching, if the shader providing data to the FS uses a qualifier, the FS must use the same qualifier. And 4.3+, the standard explicitly says that only the fragment shader's qualifiers matter.
So if you want to know how a value will be interpolated, look at the fragment shader.
The wiki may be incomplete.
If you read the GLSL 4.6 Specification, item 4.5, "Interpolation Qualifiers" you see:
It is a link-time error if, within the same stage, the interpolation
qualifiers of variables of the same name do not match.
EDIT:
As #NicolBolas pointed out, "within the same stage" is not the case.
Again in the GLSL spec, item 4.3.4 "Input Variables" we can read:
The fragment shader inputs form an interface with the last
active shader in the vertex processing pipeline. For this
interface, the last active shader stage output variables and fragment
shader input variables of the same name must match in type and
qualification, with a few exceptions: The storage qualifiers must,
of course, differ (one is in and one is out). Also, interpolation
qualification (e.g. flat) and auxiliary qualification (e.g.
centroid) may differ. These mismatches are allowed between any
pair of stages. When interpolation or auxiliary qualifiers do not
match, those provided in the fragment shader supersede those
provided in previous stages. If any such qualifiers
are completely missing in the fragment shaders, then the default is
used, rather than any qualifiers that may have been declared in
previous stages. That is, what matters is what is declared
in the fragment shaders, not what is declared in shaders in previous stages.

GLSL extension to support the ?: ternary operator?

I'm porting WebGL GLSL shaders to OpenGL GLSL desktop using #version 120.
Is there any extension that would add support for the ?: ternary operator?
like:
#extension GL_EXT_***: enable
No extension needed, it's right in the base specification:
OpenGL Shading Language 1.20 Specification, section 5.9 "Expressions", page 38, 6th bullet:
The ternary selection operator (?:). It operates on three expressions (exp1 ? exp2 : exp3). This operator evaluates the first expression, which must result in a scalar Boolean. If the result is true, it selects to evaluate the second expression, otherwise it selects to evaluate the third expression. Only one of the second and third expressions is evaluated. The second and third expressions can be any type, as long their types match, or there is a conversion in Section 4.1.10 “Implicit Conversions” that can be applied to one of the expressions to make their types match. This resulting matching type is the type of the entire expression.

Embedding other language in Flex/Bison

The bottom line:
If you would like to add one, very small feature into C++ using Flex/Bison, how would you do that? For example, ability to declare void xxx() functions with syntax: foo%%: xxx?
The whole story:
Once I have coded a custom shader processing program that built ready-to-use Cg/GLSL pixel and vertex shaders from a number of blocks. I've added few features, mostly related to static compilation (something like a "better preprocessor").
For example, something that would look like
#if LIGHT_TYPE == POINT
float lightStrength = dot(N, normalize(pos - lightPos));
#elif LIGHT_TYPE == DIRECTIONAL
float lightStrength = dot(N, lightDir);
#endif
with pure macros, looks like
[LightType = Point]
[Require: pos, lightPos]
float LightStrength()
{
!let %N Normal
return dot(%N, normalize(pos - lightPos));
}
in my "language". As you can see, "functions" can be provided for variable light/material types. There is also a possibility to "call" other function and to mark what uniform/varying attributes are required for specific shader.
Why all this effort? Because (especially in early cards like SM 2.0) there were numerous limitations of attributes, and my "compiler" produced ready-to-use shader with list of required attributes/variables, managed parameters between pixel and vertex shaders, optimized some static stuff (just for readability, as Cg compiler would optimize it later anyway).
OK, but I am not writing all of this to praise myself or something.
I've written this "compiler" in C# and it initially was a very small program. But as time passed, many features were added and now the program is a complete mess with no options of refactoring. Also, being coded in C# means I cannot embed this compiler directly in C++ game, forcing me to spawn processes to compile shaders (this takes a lot of time).
I would like to rewrite my language/compiler using C++ and Flex/Bison toolkit. I've already coded efficient math parser in Flex/Bison so I am somewhat experienced in this matter. However there is one thing that I cannot resolve myself and this is a very topic of my question.
How can I possibly embed GLSL into my language? In C# compiler, I've just went line-by-line and checked if line starts with special characters (like % or [) and later did many tricks&hacks using string_replace and/or regexes.
Now I would like to write down a clean Bison grammar and do it properly. But including whole syntax of GLSL scares me. It is quite a big and complicated language, constantly evolving. And most I would do would be to pass-through all this GLSL code anyway.
If you are not experienced with GLSL/Cg/graphics programming at all, this is not quite important. The question can be rewritten into the "bottom line".
So, if you would like to add one, very small feature into C++ using Flex/Bison, how would you do that? For example, ability to declare void xxx() functions with syntax: foo%%: xxx?
I added multithreading mechanisms to pascal for a school project once, so I've had to deal with this. What I did was I found a BNF definition of pascal and copied that, mainly making my tokens equal to the text in 99% of the cases, and adding the new intermediate language code in the 1% of new tokens I added. Pascal is simple, so the BNF definition is relatively simple. C++, not so much.
The C++ Programming Language by Stroustroup has the language grammar that is practically parser-ready, but that's a lot of code to copy by hand. Maybe a certain website can help you find a bison/lex set for "standard" C++, and then you can modify that.
EDIT:
I found my yacc files, so here's a small example from my pascal code
procheader: PROCEDURE ID paramslist ';'{thread::inLocalDecl=true; $$="procedure "+$2+$3+";\n";}
| FUNCTION ID paramslist ':' ID ';'{thread::inLocalDecl=true; $$="function "+$2+$3+":"+$5+";\n";}
| THREAD {thread::inThreadDecl=true;
thread::inArgDecl=true;}
ID {thread::curName=$3;} paramslist { thread::inArgDecl=false;} ';'
{
/*a lot of code to transform this custom construct into standard pascal*/
}
the first two elements were just standard pascal: I copied the input tokens into the output strings verbatim (ie I didn't actually modify anything from the input file).
the third element(my THREAD keyword) was, obviously, not standard pascal. So I transformed the output into something that I could actually compile in standard pascal.
Basically to compile my "threaded" pascal, I had to take my source file, pass it through my parser, then compile the output.