OpenGL shader version error - c++

I am using Visual Studio 2013 but running under Visual Studio 2010 compiler.
I am running Windows 8 in bootcamp on a Macbook Pro with intel iris pro 5200 graphics.
I have a very simple vertex and fragment shader, I am just displaying simple primitives in a window but I am getting warnings in console stating..
OpenGL Debug Output: Source(Shader Comiler), type(Other), Priority(Medium), GLSL compile warning(s) for shader 3, "": WARNING: -1:65535: #version : version number deprecated in OGL 3.0 forward compatible context driver
Anyone have any idea how to get rid of these annoying errors..?
Vertex Shader Code:
#version 330 core
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projMatrix;
in vec3 position;
in vec2 texCoord;
in vec4 colour;
out Vertex {
vec2 texCoord;
vec4 colour;
} OUT;
void main(void) {
gl_Position = (projMatrix * viewMatrix * modelMatrix) * vec4(position, 1.0);
OUT.texCoord = texCoord;
OUT.colour = colour;
}
Frag Shader code
#version 330 core
in Vertex {
vec2 texCoord;
vec4 colour;
} IN;
out vec4 color;
void main() {
color= IN.colour;
//color= vec4(1,1,1,1);
}

I always knew Intel drivers were bad, but this is ridiculous. The #version directive is NOT deprecated in GL 3.0. In fact it is more important than ever beginning with GL 3.2, because in addition to the number you can also specify core (default) or compatibility.
Nevertheless, that is not an actual error. It is an invalid warning, and having OpenGL debug output setup is why you keep seeing it. You can ignore it. AMD seems to be the only vendor that uses debug output in a useful way. NV almost never outputs anything, opting instead to crash... and Intel appears to be spouting nonsense.
It is possible that what the driver is really trying to tell you is that you have an OpenGL 3.0 context and you are using a GLSL 3.30 shader. If that is the case, this has got to be the stupidest way I have ever seen of doing that.
Have you tried #version 130 instead? If you do this, the interface blocks (e.g. in Vertex { ...) should generate parse errors, but it would at least rule out the only interpretation of this warning that makes any sense.
There is another possibility, that makes a lot more sense in the end. The debug output mentions this is related to shader object #3. While there is no guarantee that shader names are assigned sequentially beginning with 0, this is usually the case. You have only shown a total of 2 shaders here, #3 would imply the 4th shader your software loaded.
Are you certain that these are the shaders causing the problem?

Related

Can't load texture uniform with glUniform1i function

I try to follow the tutorial on YT on 'The Cherno' channel about OpenGL (you can find my code here). I have two uniforms u_Color and u_Texture that I load using glUniform1i function called from Shader.cpp file. For u_Color everything's alright but when I try to load u_Texture I obtain error code
0x502 (GL_INVALID_OPERATION; Qt debugging stops printing out "Illegal operation" error).
I tried to remove unused calls to "u_Color" uniform in shader AND cpp code, I've tried to use the function outside of GLCall macro and some other stuff but it simply doesn't want to work. I am sure location of the texture is alright (unsigned int) and I think my code looks exactly the same as the one from tutorial that actually works!
I work on Linux system (18.04), with Intel graphic card, and I'm using Qt Creator (Qt Creator 4.11.2 based on Qt 5.14.2) with g++ compiler (7.5.0).
If somebody could check it out I'd really appreciate it.
That's the problematic part of the code from "Shader.cpp"
GLuint uniformlocation = static_cast<GLuint>(glGetUniformLocation(m_rendererID, "u_Texture"));
glUniform1f(uniformLocation, value);
And here's fragment shader that uses u_Texture
#version 330 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
uniform vec4 u_Color;
uniform sampler2D u_Texture;
void main()
{
vec4 texColor = texture2D(u_Texture, v_TexCoord);
color = texColor;
}
glUniform1f sets a value of a uniform of the currently installed program, thus the program has to be installed by glUseProgram, before:
GLuint uniformlocation = static_cast<GLuint>(glGetUniformLocation(m_rendererID, "u_Texture"));
glUseProgram(m_rendererID);
glUniform1f(uniformLocation, value);
respectively:
shader.bind();
shader.setUniform1i("u_Texture", 0);
The GL_INVALID_OPERATION is caused, by the fact, that there is no current program object.
Alternatively you can use glProgramUniform to specify the value of a uniform variable for a specified program object

flat shading in webGL

I'm trying to implement flat-shading in webgl,
I knew that varying keyword in vertex shader will interpolation that value and pass it to fragment shader.
I'm trying to disable interpolation, and I found that flat keyword can do this, but it seems cannot use in webgl?
flat varying vec4 fragColor;
always getting error: Illegal use of reserved word 'flat'
Check out webGL 2. Flat shading is supported.
For vertex shadder:
#version 300 es
in vec4 vPos; //vertex position from application
flat out vec4 vClr;//color sent to fragment shader
void main(){
gl_Position = vPos;
vClr = gl_Position;//for now just using the position as color
}//end main
For fragment shader
#version 300 es
precision mediump float;
flat in vec4 vClr;
out vec4 fragColor;
void main(){
fragColor = vClr;
}//end main
I think 'flat' is not supported by the version of GLSL used in WebGL. If you want flat shading, there are several options:
1) replicate the polygon's normal in each vertex. It is the simplest solution, but I find it a bit unsatisfactory to duplicate data.
2) in the vertex shader, transform the vertex in view coordinates, and in the fragment shader, compute the normal using the dFdx() and dFdy() functions that compute derivatives. These functions are supported by the extension GL_OES_standard_derivatives (you need to check whether it is supported by the GPU before using it), most GPUs, including the ones in smartphones, support the extension.
My vertex shader is as follows:
struct VSUniformState {
mat4 modelviewprojection_matrix;
mat4 modelview_matrix;
};
uniform VSUniformState GLUP_VS;
attribute vec4 vertex_in;
varying vec3 vertex_view_space;
void main() {
vertex_view_space = (GLUP_VS.modelview_matrix * vertex_in).xyz;
gl_Position = GLUP_VS.modelviewprojection_matrix * vertex_in;
}
and in the associated fragment shader:
#extension GL_OES_standard_derivatives : enable
varying vec3 vertex_view_space;
...
vec3 U = dFdx(vertex_view_space);
vec3 V = dFdy(vertex_view_space);
N = normalize(cross(U,V));
... do the lighting with N
I like this solution because it makes the setup code simpler. A drawback may be that it gives more work to the fragment shader (but with today's GPUs it should not be a problem). If performance is an issue, it may be a good idea to measure it.
3) another possibility is to have a geometry shader (if supported) that computes the normals. In general it is slower (but again, it may be a good idea to measure performance, it may depend on the specific GPU).
See also answers to this question:
How to get flat normals on a cube
My implementation is available here:
http://alice.loria.fr/software/geogram/doc/html/index.html
Some online web-GL demos are here (converted from C++ to JavaScript using emscripten):
http://homepages.loria.fr/BLevy/GEOGRAM/

gl_PointCoord compiles and links, but crashes at runtime

I successfully wrote a standard basic transform feedback particle system with point-sprites. No flickering, the particles update from one buffer into the next, which is then rendered, then output buffer becomes input buffer on next iteration. All GPU-side, standard transform feedback.
Wonderful! ONE BIG PROBLEM: It only works if I don't use gl_PointCoord. Using a flat color for my point sprites works fine. But I need gl_PointCoord to do anything meaningful. All my shaders, whether or not they use gl_PointCoord, compile and link just fine. However, at runtime, if the shader uses gl_PointCoord (whether or not gl_PointCoord is actually in the execution path), the program crashes. I explicitly glEnable(GL_POINT_SPRITE). This doesn't have any effect. Omitting gl_PointCoord, and setting glPointSize(100.0f), and using vec4(1.0,1.0,1.0,1.) the particle system renders just fine as large white blocky squares (as expected). But using gl_PointCoord in any way (as standard texture lookup coord or procedural color or anything else) will crash my shaders at runtime, after successfully compiling and linking. I simply don't understand why. It passed glShaderSource, glCompileShader,glAttachShader, glLinkProgram. I'm compiling my shaders as #version 430, and 440, and I even tried 300 es. All compile, link, and I checked the status of the compile and link. All good. I'm using a high-end microsoft surface book pro, visual studio 2015. NVIDIA GeForce GPU. I also made sure all my drivers are up to date. Unfortunately, with point sprites, I don't have billboard vertices from the vertex shader to use to interpolate into the fragment shader as texture coordinates. gl_FragCoord doesn't work either (as I would expect for point sprites). Does anyone know how to solve this or use another technique for texture coordinates for point sprites?
glBeginTransformFeedback(GL_POINTS);//if my fragment shader uses gl_PointCoord, it hard crashes here.
When replying, please understand I'm very experienced in writing shaders, Vertex Shaders, Pixel Shaders, Tessellation control, tessellation evaluation, and geometry shaders, in GLSL and HLSL. But I don't claim to know everything. I could have forgotten something simple; I just have no idea what that could be. I'm figuring it could be a state I don't have enabled. As far as transform feedback goes, I also set up the varying attribs correctly via glTransformFeedbackVaryings.
C++ :
void Render(void* pData)
{
auto pOwner = static_cast<CPointSpriteSystem*>(pData);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
glEnable(GL_POINT_SPRITE);
glEnable(GL_POINT_SMOOTH);
//glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
m_Shader.Activate();
auto num_particles = pOwner->m_NumPointSprites;
FeedbackIndex = 0;
while (true)
{
m_Shader.SetSubroutine(GL_VERTEX_SHADER, "RenderPass",
vssubroutines[FeedbackIndex],
vsprevSubLoc[FeedbackIndex],
vsupdateSub[FeedbackIndex]);
m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass",
pssubroutines[0],
psprevSubLoc[0],
psrenderSub[0]);
if (!FeedbackIndex)
{
glEnable(GL_RASTERIZER_DISCARD);
glBindVertexArray(m_vao[bufferIndex]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_Feedback[bufferIndex]);
glBeginTransformFeedback(GL_POINTS);//if feedback fragment shader uses gl_PointCoord, will always hard-crash here
glDrawArrays(GL_POINTS, 0, num_particles);
glEndTransformFeedback();
glFlush();
}
else
{
m_Shader.SetSubroutine(GL_FRAGMENT_SHADER, "RenderPixelPass",
pssubroutines[(int)pOwner->m_ParticleType],
psprevSubLoc[(int)pOwner->m_ParticleType],
psrenderSub[(int)pOwner->m_ParticleType]);
glPointSize(100.0f);
glDisable(GL_RASTERIZER_DISCARD);
glDrawTransformFeedback(GL_POINTS, m_Feedback[bufferIndex]);
bufferIndex = 1 - bufferIndex;
break;
}
FeedbackIndex = 1 - FeedbackIndex;
}
}
VS feedback:
#version 310 es
subroutine void RenderPassType();
subroutine uniform RenderPassType RenderPass;
layout(location=0) in vec3 VertexPosition;
layout(location=1) in vec3 VertexVelocity;
layout(location=2) in float VertexStartTime;
layout(location=3) in vec3 VertexInitialVelocity;
out vec3 Position;
out vec3 Velocity;
out float StartTime;
out float Transp;
uniform float g_fCurSeconds;
uniform float g_fElapsedSeconds;
uniform float Time;
uniform float H;
uniform vec3 Accel;
#ifdef USE_VIEW_BLOCK
layout(std140) uniform view_block{
mat4 g_mView,
g_mInvView,
g_mPrevView,
g_mPrevInvView,
g_mProj,
g_mInvProj;
};
uniform mat4 g_mWorld;
#endif
subroutine(RenderPassType) void UpdateSphere(){
Position=VertexPosition+VertexVelocity*g_fElapsedSeconds;
Velocity=VertexVelocity;
StartTime=VertexStartTime;
}
subroutine(RenderPassType) void Render(){
gl_Position=g_mProj*g_mInvView*vec4(VertexPosition,1.0);
}
void main(){
RenderPass();"
}
PS feedback:
#version 310 es //version 430 and 440 same results
subroutine void RenderPixelType();
subroutine uniform RenderPixelType RenderPixelPass;
uniform sampler2D tex0;
layout(location=0) out vec4 g_FragColor;
subroutine(RenderPixelType) void Basic(){
g_FragColor=vec4(1.0,1.0,1.0,1.0);
}
subroutine(RenderPixelType) void ProceduralSphere(){
#if 1
vec2 coord=gl_PointCoord;//at runtime: BOOM!
coord=coord*2.0-1.0;
float len=length(coord);
if(len>1.0) discard;
g_FragColor=vec4(1.0-len,1.0-len,1.0-len,1.0);
#else
g_FragColor=vec4(1.0,1.0,1.0,1.0);//always works
#endif
}
subroutine(RenderPixelType) void StandardImage(){
g_FragColor=texture2D(tex0,gl_PointCoord); //boom!!
g_FragColor=vec4(1.0,1.0,1.0,1.0);
}
void main(){
RenderPixelPass();
}
I solved the problem! The problem was actually that I didn't write a value to Transp (declared out float Transp;//in vs). I casually thought I didn't have to do this. But I started to trim some fat, and as soon as I wrote out a generic float (not actually being used by later shader stages: Transp=0.0f), and then compiled as #version 430, it all started to work as originally expected: little white spheres

converting GLSL #130 segment to #330

I have the following piece of shader code that works perfectly with GLSL #130, but I would like to convert it to code that works with version #330 (as somehow the #130 version doesn't work on my Ubuntu machine with a Geforce 210; the shader does nothing). After several failed attempts (I keep getting undescribed link errors) I've decided to ask for some help. The code below dynamically changes the contrast and brightness of a texture using the uniform variables Brightness and Contrast. I have implemented it in Python using PyOpenGL:
def createShader():
"""
Compile a shader that adjusts contrast and brightness of active texture
Returns
OpenGL.shader - reference to shader
dict - reference to variables that can be passed to the shader
"""
fragmentShader = shaders.compileShader("""#version 130
uniform sampler2D Texture;
uniform float Brightness;
uniform float Contrast;
uniform vec4 AverageLuminance;
void main(void)
{
vec4 texColour = texture2D(Texture, gl_TexCoord[0].st);
gl_FragColor = mix(texColour * Brightness,
mix(AverageLuminance, texColour, Contrast), 0.5);
}
""", GL_FRAGMENT_SHADER)
shader = shaders.compileProgram(fragmentShader)
uniform_locations = {
'Brightness': glGetUniformLocation( shader, 'Brightness' ),
'Contrast': glGetUniformLocation( shader, 'Contrast' ),
'AverageLuminance': glGetUniformLocation( shader, 'AverageLuminance' ),
'Texture': glGetUniformLocation( shader, 'Texture' )
}
return shader, uniform_locations
I've looked up the changes that need to made for the new GLSL version and tried changing the fragment shader code to the following, but then only get non-descriptive Link errors:
fragmentShader = shaders.compileShader("""#version 330
uniform sampler2D Texture;
uniform float Brightness;
uniform float Contrast;
uniform vec4 AverageLuminance;
in vec2 TexCoord;
out vec4 FragColor;
void main(void)
{
vec4 texColour = texture2D(Texture, TexCoord);
FragColor = mix(texColour * Brightness,
mix(AverageLuminance, texColour, Contrast), 0.5);
}
""", GL_FRAGMENT_SHADER)
Is there anyone that can help me with this conversion?
I doubt that raising the shader version profile will solve any issue. #version 330 is OpenGL-3.3 and according to the NVidia product website the maximum OpenGL version supported by the GeForce 210 is OpenGL-3.1, i.e. #version 140
I created no vertex shader cause I didn't think I'd need one (I wouldn't know what I should make it do). It worked before without any vertex shader as well.
Probably only as long as you didn't use a fragment shader or before you were attempting to use a texture. The fragment shader needs input variables, coming from a vertex shader, to have something it can use as texture coordinates. TexCoord is not a built-in variable (and with higher GLSL versions any builtin variables suitable for the job have been removed), so you need to fill that with value (and sense) in a vertex shader.
the glGetString(GL_VERSION) on the NVidia machine reads out OpenGL version 3.3.0. This is Ubuntu, so it might be possible that it differs with the windows specifications?
Do you have the NVidia propriatary drivers installed? And are they actually used? Check with glxinfo or glGetString(GL_RENDERER). OpenGL-3.3 is not too far from OpenGL-3.1 and in theory OpenGL major versions map to hardware capabilities.

How does the default GLSL shaders look like? for version 330

What do the default vertex, fragment and geometry GLSL shaders look like for version #330?
I'll be using #version 330 GLSL Version 3.30 NVIDIA via Cg compiler, because that is what my graphics card supports.
With default shaders, I mean shaders that do the same exact thing as the graphics card would do when the shader program is turned off.
I can't find a good example for #version 330. Been googling all day. Not sure if the term default shader is called something else like trivial or basic and if that is why I can't find it.
Any recommendations for a book with version 330 or link to an easy beginner tutorial with version 330 would be great as well.
example of a trivial vertex shader in #version 110, does the default vertex transformation
#version 110
void main()
{
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}
example of a trivial fragment shader in #version 110, turns color into red
#version 110
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
There are no "default" shaders with OpenGL. It looks like what you want a very simple example of a shader that transforms vertices to clip space and gives them a color, so here you go:
Vertex shader:
#version 330
layout(location = 0)in vec4 vert;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main()
{
gl_Position = projection * view * model * vert;
}
Fragment shader:
#version 330
out vec4 fragColor;
void main()
{
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
The core OpenGL 3.3 profile drops support for a lot of old fixed-function things like the matrix stack. You are expected to handle your own matrices and send them to your shaders. There is no ftransform, and gl_Position is pretty much the only valid gl_* variable.
While glBindAttribLocation is not deprecated, the preferred method of defining the location of vertex attributes is through "layout(location = x)" in GLSL.
In the vertex shader, "attribute" is now "in" and "varying" is now "out". In the fragment shader, "varying" is now "in" and "gl_FragColor" is defined by an "out" variable. I believe that gl_FragColor is still valid, but now it's possible to use an out variable to define the color.
This tutorial is very good and teaches core OpenGL and GLSL 3.30, I would recommend you use it to help you learn more about GLSL. Also remember that the GLSL Reference Pages is your friend.