interface blocks in opengl 3.0 - opengl

Im trying to use interface blocks in opengl 3.0 (#version 130).
The code looks like following:
#version 130
#extension GL_ARB_uniform_buffer_object : require
layout(std140) uniform test{
mat4 testmat;
}
This gives me syntax error at std140. Is there an extension I'm missing to enable or it this simply not supported by version 130?

Related

Error when compiling shaders GLSL 3.30

I create context by:
new sf::Window(sf::VideoMode(800, 600), "OpenGL",
sf::Style::Default,
sf::ContextSettings(24, 8, 0, 3, 3, sf::ContextSettings::Core)));
I'm loading extensions by glLoadGen for OpenGL 3.3 Core Profile with one extension EXT_texture_compression_s3tc. When I'm compiling shader:
#version 330 core
layout (location = 0) in vec3 vertPos;
layout (location = 5) uniform mat4 modelMat;
layout (location = 6) uniform mat4 viewMat;
layout (location = 7) uniform mat4 projectionMat;
out vec4 fragColor;
void main()
{
gl_Position = projectionMat * viewMat * modelMat * vec4(vertPos, 1.0);
fragColor = vec4(0.5, 0.5, 0.5, 1.0);
}
``
#version 330 core
in vec4 fragColor;
out vec4 outColor;
void main()
{
outColor = fragColor;
}
I get error string:
ERROR: Shader compilation error at shader: "media/shaders/shader.vs.glsl"
0:7(1): error: uniform explicit location requires GL_ARB_explicit_uniform_location and either GL_ARB_explicit_attrib_location or GLSL 3.30.
0:8(1): error: uniform explicit location requires GL_ARB_explicit_uniform_location and either GL_ARB_explicit_attrib_location or GLSL 3.30.
0:9(1): error: uniform explicit location requires GL_ARB_explicit_uniform_location and either GL_ARB_explicit_attrib_location or GLSL 3.30.
but I have OpenGL 3.3 (so GLSL 3.30).
glxinfo prints:
Extended renderer info (GLX_MESA_query_renderer):
Vendor: X.Org (0x1002)
Device: AMD JUNIPER (DRM 2.43.0, LLVM 3.8.0) (0x68be)
Version: 11.2.0
Accelerated: yes
Video memory: 512MB
Unified memory: no
Preferred profile: core (0x1)
Max core profile version: 3.3
Max compat profile version: 3.0
Max GLES1 profile version: 1.1
Max GLES[23] profile version: 3.0
OpenGL vendor string: X.Org
OpenGL renderer string: Gallium 0.4 on AMD JUNIPER (DRM 2.43.0, LLVM 3.8.0)
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.2.0
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
So I should be able use GLSL 3.30.
The ability to specify uniform locations in a shader is not part of OpenGL version 3.3 or GLSL version 3.30. It's only a core feature of GL 4.3 or GLSL 4.30. The ability to specify vertex shader input and fragment shader output locations is 3.30, but uniform locations are not.
Explicit uniform location specification doesn't actually require special hardware; it's purely an interface thing. As such, pre-4.x hardware could implement it. However, if your hardware is limited to GL 3.3, then there's a very good chance that the hardware is so old that it stopped being updated by the IHV with new OpenGL features. So even though it could support it, the feature appeared after the IHV stopped updating the hardware.
While NVIDIA has kept some of their 3.3-only hardware up-to-date on recent, non-hardware features, the same cannot be said for Intel or AMD. So even if you have an NVIDIA 3.x GPU that this works on, it's likely that Intel or AMD's 3.x GPUs won't work.
In your case, "Juniper" refers to the Radeon 67xx line. These are GL 4.x parts. However, you're using the open source driver rather than AMD's actual Linux driver, so you're only able to get 3.3 from it.
It would be better to bump your required OpenGL version to match your shader. However, if you wish to keep it as a 3.30 shader and use it as an extension (since you're using the open source driver instead of AMD's driver), you will need an extension declaration below the #version declaration:
#extension GL_ARB_explicit_uniform_location : require
You could try adding the following line that enables the extension below #version 330 core:
#extension GL_ARB_explicit_uniform_location : require

Using emscripten with opengl shaders

I am having trouble getting emscripten to work with openGL shaders. The project compiles just fine with both emscripten and gcc but fails when I try to run the emscripten output.
The errors I get from compiling the vertex shader:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'layout' : syntax error
The errors I get from compiling the fragment shader:
ERROR: 0:1: 'core' : invalid version directive
ERROR: 0:3: 'in' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:3: '' : No precision specified for (float)
ERROR: 0:5: 'out' : storage qualifier supported in GLSL ES 3.00 only
ERROR: 0:5: '' : No precision specified for (float)
I'm compiling this project with the command:
em++ src/*.cpp -Iinclude/ -o test.html -std=c++11 -s USE_GLFW=3 -s FULL_ES3=1
Vertex shader source:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 in_color;
uniform mat4 model;
uniform mat4 projection;
out vec3 out_color;
void main()
{
gl_Position = projection * model * vec4(position, 1.0f);
out_color = in_color;
}
Fragment shader source:
#version 330 core
in vec3 out_color;
out vec4 color;
void main()
{
color = vec4(out_color, 1.0);
}
The shaders are loaded as char arrays from output provided by xxd -i I'm working in c++11 on linux. The program works just fine when I run it natively and I've tried running the emscripten output in both Firefox and chromium.
It seems to be a problem between different versions. Is there a way to make emscripten work with what I currently have, or do I have to write my shaders differently? And if I do have to rewrite my shaders, how should I write them?
The shader code will have to be WebGL shader code to work on the browser. I don't think emscripten converts shader code (GLSL 3.3 in this case) to a GLSL ES 1.0 that is compatible with webGL.
You'll have to use attribute instead of in in the vertex shader, varying for out/in in the vertex/fragment shaders and use gl_FragColor as the output variable of the fragment shader. layout is not supported either, and the variables need a precision definition. Check the WebGL cheat sheet here.
In current emscripten you can use WebGL2 and GLSL ES 3.00. You need to change your #version lines to
#version 300 es
You will also need to add a default precision to your fragment shaders.
If it was me I'd just wrap my code to glShaderSource to be something like
GLint shaderSourceWrapper(GLint shader, const std::string src) {
#ifdef __EMSCRIPTEN__
// replace '#version.*' with '#version 300 es'
// if it's a fragment shader add 'precision highp float'
// do anything else relevant like warn if there are
// unsupported #extension directives
#endif
glShaderSource(shader, ... )
Or even do that at the JavaScript level like this

Qt5 OpenGL GLSL version error

I'm starting out on using OpenGL with Qt, and with Shaders (I have OpenGL experience, but not with shaders yet)
I'm following this tutorial: http://releases.qt-project.org/learning/developerguides/qtopengltutorial/OpenGLTutorial.pdf (the official Qt5 OpenGL tutorial).
The problem is, that when I try to run my program, I get a black screen and the following error messages:
QGLShader::compile(Vertex): ERROR: 0:1: '' : version '130' is not supported
QGLShader::compile(Fragment): ERROR: 0:1: '' : version '130' is not supported
My program is based on a QGLWidget
With some browsing on the interwebs I found out that I need to use an OpenGL 3.2 context, but that Qt likes to use OpenGL 2.x
My computer:
MacBook pro retina '15, late 2012
Intel HD 4000
NVidia GeForce 650M
So, how can I make this work?
EDIT:
My version is 3.2 (set through QGLFormat), without a specified format it uses 2.0
fragmentShader.frag:
#version 130
uniform vec4 color;
out vec4 fragColor;
void main(void)
{
fragColor = color;
}
vertexShader.vert:
#version 130
uniform mat4 mvpMatrix;
in vec4 vertex;
void main(void)
{
gl_Position = mvpMatrix * vertex;
}
Errors (with format, OpenGL 3.2):
QGLShaderProgram: shader programs are not supported
QGLShaderProgram::uniformLocation( mvpMatrix ): shader program is not linked
The program has unexpectedly finished.
Errors (without format, OpenGL 2.0):
QGLShader::compile(Vertex): ERROR: 0:1: '' : version '130' is not supported
QGLShader::compile(Fragment): ERROR: 0:1: '' : version '130' is not supported
Newer QOpenGLWidget doesn't support any constructor with QGLFormat. Instead, in your main.cpp, specify the default QSurfaceFormat for all QOpenGLWidget and QOpenGLContext as following:
// main.cpp
QSurfaceFormat glFormat;
glFormat.setVersion(3, 3);
glFormat.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(glFormat);
Now you should be able to use something like #version 330 core in your shader.
You should create an QGLFormat object and pass it to the QGLWidget as a constructor parameter. The QGLFormat object should be created as showed in the code below.
QGLFormat glFormat;
glFormat.setVersion( 3, 2 );
glFormat.setProfile( QGLFormat::CoreProfile );
I've got the same error on my macbook (early 2011), and this answer helps me. Basically you deprecate to version120.

Shader link error after installing latest NVidia Quadro driver (311.35)

I just installed the latest NVidia driver for Quadro 4000 cards.From this moment any of my shaders linking fails with shader link error.
It is worth noting I am using OpenGL 4.2 with separate shader objects.My OS is Windows7 64bit .
Before the update I had 309.x version of the driver and everything worked fine.
Now I rolled back to the version 295.x and it works again.
Anyone knows something about it?Can it be a driver bug? If yes, what can be done about it?
Here is a simple pass through vertex shader that fails:
#version 420 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 uvs;
layout(location = 2) in vec3 normal;
smooth out vec2 uvsOut;
void main()
{
uvsOut=uvs;
gl_Position = position;
}
Another question ,is it possible that NVIdia tightened shader version semantics rules? I mean ,I am using OpenGL compatibility profile but in GLSL mark #version 420 core.Can it be the problem?
Update:
Some more info from Program Info Log:
error C7592: ARB_separate_shader_objects requrires built-in block gl_PerVertex to be redeclared before accesing its members.
Yeah , also the driver writer has typos "accesing " ;)
Now , I actually solved the linking error by adding this :
out gl_PerVertex
{
vec4 gl_Position;
};
It is strange that previous drivers didn't enforce redefinition of gl_PerVertex block.Now ,while this addon solved the issue with the linking, it opened another one where some varying uniforms don't work.For example I have in vertex shader:
out vec4 diffuseOut;
And in fragment shader:
in vec4 diffuseOut;
Then
OUTPUT = diffuseOut;/// returns black while red is expected.
Update 2 :
Ok , now it becomes clear - the new drivers are stricter on shaders input/output variables.With the older driver I could define several "outs" in a vertex shader but without defining also their "in" match in the fragment shader.It worked.Now it seems I am forced to have the exact match between declared "ins" and "outs" in vert and frag program.Strange that no errors are being thrown but the result is that the defined "ins" become empty in the destination.

OpenGLSL error while compiling fragment shader using UBOs

I am trying to get UBOs working, however I get a compilation error in the fragment shader:
ERROR 0:5:"(": synrax error.
Fragment Shader:
layout(std140) uniform Colors
{
vec3 SCol;
vec3 WCol;
float DCool;
float DWarm;
}colors;
Where am I going wrong?
At the begining of your fragment shader source file (the very first line) put this:
#version 140
This means that you are telling the GLSL compiler that you use the version 1.40 of the shading language (you can, of course, use a higher version - see Wikipedia for details).
Alternatively, if your OpenGL driver (and/or hardware) doesn't support GLSL 1.40 fully (which is part of OpenGL 3.1), but only GLSL 1.30 (OpenGL 3.0), you can try the following:
#version 130
#extension GL_ARB_uniform_buffer_object : require
However, this one will work only if your OpenGL 3.0 driver supports the GL_ARB_uniform_buffer_object extension.
Hope this helps.