Cant enable GLSL 1.40 in my Qt application - c++

I want to porting demo project of Box2D from VS2013 in Qt. But i have one unusual problem. When i run demo project in VS i get message with info about my openGL configuration.
I replaced code on Qt and changed initialization of shaders and calls of opengl funcitons with QOpeGL wrappers.
Firstly, i change default surface format like this:
QSurfaceFormat format;
format.setVersion(3, 1);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
But when i debug program is format of my surface stay on 3.0.
And when i try to create shaders i get error message like this:
QOpenGLShader::compile(Vertex): ERROR: 0:1: '140' : version number not supported
ERROR: 0:2: 'layout' : syntax error
*** Problematic Vertex shader source code ***
#version 140
#line 1
uniform mat4 projectionMatrix;
layout(location = 0) in vec2 v_position;
layout(location = 1) in vec4 v_color;
layout(location = 2) in float v_size;
out vec4 f_color;
void main(void)
{
f_color = v_color;
gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);
gl_PointSize = v_size;
}
Why VS can create shaders and work with OpenGL 3.1/GLSL 1.40, but Qt doesn't do this?
Initialize of GL (m_functions - QOpenGLExtraFunctions)
void MainOpenGLWidget::initializeGL()
{
makeCurrent();
qDebug() << "OPENGL " << QSurfaceFormat::defaultFormat().majorVersion() <<
"." << QSurfaceFormat::defaultFormat().minorVersion();
m_functions.initializeOpenGLFunctions();
m_functions.glClearColor(0, 0, 0, 0);
g_camera.m_width = 1024;
g_camera.m_height = 640;
g_debugDraw.Create(&m_functions);
}
function g_debugDraw.Create(...):
void Create(QOpenGLExtraFunctions *functions)
{
const char *vs = \
"#version 140\n"
"uniform mat4 projectionMatrix;\n"
"layout(location = 0) in vec2 v_position;\n"
"layout(location = 1) in vec4 v_color;\n"
"layout(location = 2) in float v_size;\n"
"out vec4 f_color;\n"
"void main(void)\n"
"{\n"
" f_color = v_color;\n"
" gl_Position = projectionMatrix * vec4(v_position, 0.0f, 1.0f);\n"
" gl_PointSize = v_size;\n"
"}\n";
...
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vs);
...
m_functions = *functions;
m_functions.glGenVertexArrays(1, &m_vaoId);
m_functions.glGenBuffers(3, m_vboIds);
m_functions.glBindVertexArray(m_vaoId);
m_functions.glEnableVertexAttribArray(m_vertexAttribute);
m_functions.glEnableVertexAttribArray(m_colorAttribute);
m_functions.glEnableVertexAttribArray(m_sizeAttribute);
...
}
I get error when call m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vs);

If you really want to stick to GLSL #version 140, then replace the following lines
layout(location = 0) in vec2 v_position;
layout(location = 1) in vec4 v_color;
layout(location = 2) in float v_size;
by
in vec2 v_position;
in vec4 v_color;
in float v_size;
Explicit attribute location is not part of GLSL until #version 330.
Be careful after that to query your shader's attribute location before enabling it in your C++ code. The shader compiler may or may not order them in the order of declaration.
const int POS_LOCATION = glGetAttribLocation(program_id, "v_position");
if(-1 != POS_LOCATION)
{
glEnableVertexAttribArray(POS_LOCATION);
...
glVertexAttribPointer(POS_LOCATION, ... );
...
}
I've found no mention of layout(location = x) in documentation of GLSL #version 140.
https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.40.pdf
Not mentioned until #version 330 at page 35.
https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.3.30.pdf
In your case the shader compiler error message is a little misleading. Maybe if you update you graphic card driver you'll get a better shader compiler.

I didn't took into account that GLSL for desktop is not the same that GLSL from OpenGL ES. This topic little helped me. I change all in to attribute or varying and all out to varying and also set precision on float. After change my shader was compile. Finally my shader code looks like this:
precision lowp float;
uniform mat4 projectionMatrix;
attribute vec2 v_position;
attribute vec4 v_color;
attribute float v_size;
varying vec4 f_color;
void main(void)
{
f_color = v_color;
gl_Position = projectionMatrix * vec4(v_position, 0.0, 1.0);
gl_PointSize = v_size;
}
Thank Octo for support!

Related

OpenGL Alpha Blending not working Despite using glEnable(GL_BLEND) and glBlendFunc()

I am Having an issue where the blending to get transparency in OpenGL isn't working. The alpha channel is effectively just turning the color to black(might be the same color as my clear color). I have enabled blending and the blendfunc. I also have tested that I am submitting my color data correctly as the transparency isn't showing up even if I hard code it in. The geometry is just overriding all color behind it. Any tips on how to debug?
// Blending function for Alpha channels
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Allows for depth testing between z-values
glEnable(GL_DEPTH_TEST);
#type vertex
#version 330 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
layout(location = 2) in vec2 a_TexCoord;
layout(location = 3) in float a_TexIndex;
uniform mat4 u_VPMatrix;
out vec4 v_Color;
out vec2 v_TexCoord;
out float v_TexIndex;
void main() {
v_Color = a_Color;
v_TexCoord = a_TexCoord;
v_TexIndex = a_TexIndex;
gl_Position = u_VPMatrix * vec4(a_Position, 1.0);
}
#type fragment
#version 330 core
in vec4 v_Color;
in vec2 v_TexCoord;
in float v_TexIndex;
uniform sampler2D u_Textures[32];
//uniform float u_TilingFactor;
void main() {
gl_FragColor = texture(u_Textures[int(v_TexIndex)], v_TexCoord) * v_Color;
}

Qt and OpenGL: Fragment shader won't compile when using addShaderFromSourceFile instead of addShaderFromSourceCode

I am using QOpenGLWidget to render some CAD meshes. I started with an example that had the shader source code written directly into the code in the following way:
Vertex shader
static const char *vertexShaderSourceCore =
"#version 330\n"
"in vec4 vertex;\n"
"in vec3 normal;\n"
"out vec3 vert;\n"
"out vec3 vertNormal;\n"
"uniform mat4 projMatrix;\n"
"uniform mat4 mvMatrix;\n"
"uniform mat3 normalMatrix;\n"
"void main() {\n"
" vert = vertex.xyz;\n"
" vertNormal = normalMatrix * normal;\n"
" gl_Position = projMatrix * mvMatrix * vertex;\n"
"}\n";
Fragment shader
static const char *fragmentShaderSourceCore =
"#version 330\n"
"in highp vec3 vert;\n"
"in highp vec3 vertNormal;\n"
"out highp vec4 fragColor;\n"
"uniform highp vec3 lightPos;\n"
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(0.39, 0.4, 0.0);\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" fragColor = vec4(col, 1.0);\n"
"}\n";
I load this code into my QOpenGLShaderProgram with the function addShaderFromSourceCode. With this, everything works as expected.
Now I wanted to move the shader source code to a separate file in order to make the code cleaner. I created a .qrc file and put in the shaders in the following way:
Vertex Shader
#version 330
in vec4 vertex;
in vec3 normal;
out vec3 vert;
out vec3 vertNormal;
uniform mat4 projMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
void main()
{
vert = vertex.xyz;
vertNormal = normalMatrix * normal;
gl_Position = projMatrix * mvMatrix * vertex;
}
Fragment shader
in highp vec3 vert;
in highp vec3 vertNormal;
out highp vec4 fragColor;
uniform highp vec3 lightPos;
void main() {
highp vec3 L = normalize(lightPos - vert);
highp float NL = max(dot(normalize(vertNormal), L), 0.0);
highp vec3 color = vec3(0.39, 0.4, 0.0);
highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);
fragColor = vec4(col, 1.0);
}
I then wanted to use QOpenGLShaderProgram::addShaderFromSourceFile to load the shader code from these files.
The vertex shader loads without issues, but when importing the fragment shader I get the following error message:
QOpenGLShader::compile(Fragment): ERROR: 4:1: ':' : syntax error syntax error
*** Problematic Fragment shader source code ***
#version 110
#ifdef GL_KHR_blend_equation_advanced
#extension GL_ARB_fragment_coord_conventions : enable
#extension GL_KHR_blend_equation_advanced : enable
#endif
#define lowp
#define mediump
#define highp
#line 1
:/globalCore.frag
***
which I do not understand. I don't think its a compatibility issue since I have two additional shaders if core mode is not enabled.
Can someone help me understand where this ominous "syntax error" is coming from? I don't have a colon in my shader code so I am at a loss here.

error C1105: cannot call a non-function

I used a shader which worked in another program (in the same environment afaik) which can't compile now for some reason:
// Vertex Shader
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
out vec2 fragmentUV;
uniform mat4 ortho_matrix;
void main()
{
gl_Position = ortho_matrix * vec4(vertexPosition_modelspace, 1);
fragmentUV = vertexUV;
}
// Fragment Shader
#version 330 core
in vec2 fragmentUV;
uniform sampler2D texture;
out vec4 color;
void main()
{
color.rgba = texture(texture, fragmentUV).rgba;
}
It's a super basic shader and now it starts to throw errors all of the sudden.
Windows 8.1
Nvidia GeForce 1080 (this one is new maybe that's the problem?)
This is whats being output by Visual Studio:
uniform sampler2D texture;
out vec4 color;
void main()
{
color.rgba = texture(texture, fragmentUV).rgba;
}
I'm amazed this compiled at all in a different setting. You've named your texture the same as the function used to make texture lookups. You need to rename uniform sampler2D texture; to something else.

uniform sampler2D in Vertex Shader

I tried to realize height map with GLSL.
For it, i need to sent my picture to VertexShader and get grey component.
glActiveTexture(GL_TEXTURE0);
Texture.bind();
glUniform1i(mShader.getUniformLocation("heightmap"), 0);
mShader.getUniformLocation uses glGetUniformLocation and work good for other uniforms values, that used in Fragment, Vertex Shaders. But for heightmap return -1...
VertexShader code:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normal;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
out vec4 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D heightmap;
void main()
{
float bias = 0.25;
float h = 0.0;
float scale = 5.0;
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
vec3 hnormal = vec3(normal.x*h, normal.y*h, normal.z*h);
vec3 position1 = position * hnormal;
gl_Position = projection * view * model * vec4(position1, 1.0f);
FragPos = vec3(model * vec4(position, 1.0f));
Normal = mat3(transpose(inverse(model))) * normal;
ourColor = color;
TexCoords = texCoords;
}
may be algorithm of getting height is bad, but error with getting uniformlocation stops my work..
What is wrong? Any ideas?
UPD: texCoords (not TexCoords) of course is using in
h = scale * ((texture2D(heightmap, texCoords).r) - bias);
my mistake, but it doesn't solve the problem. Having same error..
My bet is your variable has been optimized out by driver or the shader did not compile/link properly. After trying to compile your shader (on my nVidia) I got this in the logs:
0(9) : warning C7050: "TexCoords" might be used before being initialized
You should always check the GLSL compile/link logs ? see
How to debug GLSL Fragment shader
especially how the glGetShaderInfoLog is used.
In line
h = scale * ((texture2D(heightmap, TexCoords).r) - bias);
You are using TexCoords which is output variable and not yet set so the behavior is undefined and most likely your gfx driver throw that line away (and may be others) removing the TexCoords from shader completely but that is just my assumption.
What driver and gfx card you got?
What returns the logs on your setup?

GLSL compilation error when using QGLShaderProgram

I'm currently trying out some of the opengl components in Qt 5, I'm compiling on Mac OSX 10.8 with QtCreator 2.6.2, clang 4.2
I've written a very basic GLSL shader that compiles and links well in OpenGl Shader Builder, but when I try to load it using a QGLShader, it fails to compile and the log function returns no error message.
Vertex Shader:
attribute vec4 in_position;
attribute vec3 in_normal;
attribute vec3 in_color;
attribute vec2 in_tex;
uniform vec4 lightPosition;
varying vec2 texCoords;
varying vec3 normal;
varying vec3 vertToLightDir;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * in_position;
vec4 worldVert = gl_ModelViewMatrix * in_position;
vertToLightDir = normalize(vec3(lightPosition - worldVert));
normal = gl_NormalMatrix * in_normal;
texCoords = in_tex;
}
Fragment Shader:
uniform sampler2D texture0;
uniform vec4 lightColor;
varying vec2 texCoords;
varying vec3 normal;
varying vec3 vertToLightDir;
void main(void)
{
float lightIntensity = clamp(dot(normal, vertToLightDir), 0.0, 1.0);
gl_FragColor = (texture2D(texture0, texCoords) + (lightColor * lightIntensity)) * 0.5;
}
The code that loads the shaders:
QGLShader fragShader(QGLShader::Fragment);
bool success = fragShader.compileSourceFile("Fragment.glsl");
qDebug() << fragShader.log();
I used the debugger to see that the compileSourceFile function returns false, I also used access("Fragment.glsl", F_OK) to see if the program manages to find the file and it does, the same goes for the vertex shader file, I can't seem to find the reason they won't compile. Is there something I'm doing wrong ?
After some debugging I realized I was trying to compile the shaders before a valid context was created. My bad.