How to add directives in OpenGL/GLES shaders? - opengl

Basically I want to create one file which contains my vertex shader as well as fragment shader.
like this.
#ifdef VERTEX
attribute vec4 a_pos;
attribute vec2 a_texCoords;
uniform mat4 combined;
varying vec2 v_texCoords;
void main(){
v_texCoords = a_texCoords;
gl_Position = combined * a_pos;
}
#endif
#ifdef FRAGMENT
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoords);
//gl_FragColor = vec4(1,0,0,1);
}
#endif
but How to pass directives while compiling the shader like make_file in c/c++?

I just prepended #define VERTEX\n to the start of the code string when using it as vertex shader source code, and #define FRAGMENT\n when using it as fragment shader source code
like this:-
void compileShader(int TYPE, String source){
switch(TYPE){
case GL20.GL_VERTEX_SHADER:
source = "#define VERTEX \n" + source;
case GL20.GL_FRAGMENT_SHADER:
source = "#define FRAGMENT \n" + source;
}
//then compile source
}

Related

Why output from vertex shader is being corrupted when an unsued output is not passed. (OpenGL/GLSL)

I'm receiving three attributes in the vertex shader and passing them to the fragment shader. If I omit one particular channel, that is not used in the frament shader at all, the fragment shader produces invalid output.
I reduced the code to the following simple examples:
A. (corrrect)
//Vertex Shader GLSL
#version 140
in vec3 a_Position;
in uvec4 a_Joint0;
in vec4 a_Weight0;
// it doesn't matter if flat is specified or not for the joint0 (apparently)
// out uvec4 o_Joint0;
flat out vec4 o_Joint0;
flat out vec4 o_Weight0;
layout (std140) uniform WorldParams
{
mat4 ModelMatrix;
};
void main()
{
o_Joint0=a_Joint0;
o_Weight0=a_Weight0;
vec4 pos = ModelMatrix * vec4(a_Position, 1.0);
gl_Position = pos;
}
//Fragment Shader GLSL
#version 140
flat in uvec4 o_Joint0;
flat in vec4 o_Weight0;
out vec4 f_FinalColor;
void main()
{
f_FinalColor=vec4(0,0,0,1);
f_FinalColor.rgb += (o_Weight0.xyz + 1.0) / 4.0+(o_Weight0.z + 1.0) / 4.0;
}
VS sends down to the FS the attributes o_Joint0 and o_Weight0, the fragment shader produces this correct output:
B. (incorrrect)
//Vertex Shader GLSL
#version 140
in vec3 a_Position;
in uvec4 a_Joint0;
in vec4 a_Weight0;
flat out vec4 o_Weight0;
layout (std140) uniform WorldParams
{
mat4 ModelMatrix;
};
void main()
{
o_Weight0=a_Weight0;
vec4 pos = ModelMatrix * vec4(a_Position, 1.0);
gl_Position = pos;
}
//Fragment Shader GLSL
#version 140
flat in vec4 o_Weight0;
out vec4 f_FinalColor;
void main()
{
f_FinalColor=vec4(0,0,0,1);
f_FinalColor.rgb += (o_Weight0.xyz + 1.0) / 4.0+(o_Weight0.z + 1.0) / 4.0;
}
VS sends down to the FS the attribute o_Weight0, as you can see the only thing omitted in both shaders was o_Joint0, the fragment shader produces this in incorrect output:
First, try completely omitting the a_Joint0 variable from the vertex shader (do not load it to the vertex shader at all, not even as a buffer).
If this does not work, try reverting your code back to before you omitted the variable and see if it works again, and then try and find out how it is actually affecting the fragment shader.

glUniform1i has no effect

I am trying to assign texture unit 0 to a sampler2D uniform but the uniform's value does not change.
My program is coloring points based on their elevation (Y coordinates). Their color is looked up in a texture.
Here is my vertex shader code :
#version 330 core
#define ELEVATION_MODE
layout (location = 0) in vec3 position;
layout (location = 1) in float intensity;
uniform mat4 vpMat;
flat out vec4 f_color;
#ifdef ELEVATION_MODE
uniform sampler2D elevationTex;
#endif
#ifdef INTENSITY_MODE
uniform sampler2D intensityTex;
#endif
// texCoords is the result of calculations done on vertex coords, I removed the calculation for clarity
vec4 elevationColor() {
return vec4(textureLod(elevationTex, elevationTexCoords, 0), 1.0);
}
vec4 intensityColor() {
return vec4(textureLod(elevationTex, intensityTexCoords, 0), 1.0);
}
int main() {
gl_Position = vpMat * vec4(position.xyz, 1.0);
#ifdef ELEVATION_MODE
f_color = elevationColor();
#endif
#ifdef COLOR_LODDEPTH
f_color = getNodeDepthColor();
#endif
}
Here is my fragment shader :
#version 330 core
out vec4 color;
flat in vec4 f_color;
void main() {
color = f_color;
}
When this shader is executed, I have 2 textures bound :
elevation texture in texture unit 0
intensity texture in texture unit 1
I am using glUniform1i to set the uniform's value :
glUniform1i(elevationTexLocation, (GLuint)0);
But when I run my program, the value of the uniform elevationTex is 1 instead of 0.
If I remove the glUniform1i call, the uniform value does not change (still 1) so I think the call is doing nothing (but generates no error).
If I change the uniform's type to float and the call from glUniform1i to :
glUniform1f(elevationYexLocation, 15.0f);
The value in the uniform is now 15.0f. So there is no problem in my program with the location from which I call glUniform1i, it just has no impact on the uniform's value.
Any idea about what I could be doing wrong ?
I could give you more code but it is not really accessible so if you know the answer without it that's great. If you need the C++ part of the code, ask, I'll try to retrieve the important parts

Translate ARB assembly to GLSL?

I'm trying to translate some old OpenGL code to modern OpenGL. This code is reading data from a texture and displaying it. The fragment shader is currently created using ARB_fragment_program commands:
static const char *gl_shader_code =
"!!ARBfp1.0\n"
"TEX result.color, fragment.texcoord, texture[0], RECT; \n"
"END";
GLuint program_id;
glGenProgramsARB(1, &program_id);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program_id);
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei) strlen(gl_shader_code ), (GLubyte *) gl_shader_code );
I'd simply like to translate this into GLSL code. I think the fragment shader should look something like this:
#version 430 core
uniform sampler2DRect s;
void main(void)
{
gl_FragColor = texture2DRect(s, ivec2(gl_FragCoord.xy), 0);
}
But I'm not sure of a couple of details:
Is this the right usage of texture2DRect?
Is this the right usage of gl_FragCoord?
The texture is being fed with a pixel buffer object using GL_PIXEL_UNPACK_BUFFER target.
I think you can just use the standard sampler2D instead of sampler2DRect (if you do not have a real need for it) since, quoting the wiki, "From a modern perspective, they (rectangle textures) seem essentially useless.".
You can then change your texture2DRect(...) to texture(...) or texelFetch(...) (to mimic your rectangle fetching).
Since you seem to be using OpenGL 4, you do not need to (should not ?) use gl_FragColor but instead declare an out variable and write to it.
Your fragment shader should look something like this in the end:
#version 430 core
uniform sampler2D s;
out vec4 out_color;
void main(void)
{
out_color = texelFecth(s, vec2i(gl_FragCoord.xy), 0);
}
#Zouch, thank you very much for your response. I took it and worked on this for a bit. My final cores were very similar to what you suggested. For the record the final vertex and fragment shaders I implemented were as follows:
Vertex Shader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
out vec2 UV;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * vec4(vertexPosition_modelspace, 1);
UV = vertexUV;
}
Fragment Shader:
#version 330 core
in vec2 UV;
out vec3 color;
uniform sampler2D myTextureSampler;
void main()
{
color = texture2D(myTextureSampler, UV).rgb;
}
That seemed to work.

GLSL - Set color of vertex

I want to darken the corners of my little quad in my program. I have the following vertex shader:
#version 130
varying vec4 v_color;
varying vec2 v_texcoord;
void main()
{
v_color = gl_Color.rgba;
v_texcoord = gl_MultiTexCoord0.xy;
gl_FrontColor = vec4(v_color.r, v_color.g, v_color.b, 1.0f);
gl_Position = ftransform();
}
And my fragment shader:
#version 130
uniform sampler2D u_texture;
varying vec4 v_color;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = v_color * texture2D(u_texture, v_texcoord);
}
I read somewhere that gl_FrontColor could be used to "color" vertices, but no matter what I change the values to, it always seems to stay the same.
My question is, what function can I use to set the color of my vertices? I want the vertices to be slightly darker than the rest of the quad so it looks a little "nicer".
You output to both v_color (your varying), and gl_FrontColor (GLSL builtin). But, in fragment shader, you only use v_color, so anything that is in gl_FrontColor is being ignored.
You should use only one of these. Either
// vertex
#version 130
#define SCALE_FACTOR 0.5
varying vec4 v_color;
varying vec2 v_texcoord;
void main()
{
v_color = vec4(gl_Color.rgb * SCALE_FACTOR, 1.0);
v_texcoord = gl_MultiTexCoord0.xy;
gl_Position = ftransform();
}
// fragment
#version 130
uniform sampler2D u_texture;
varying vec4 v_color;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = v_color * texture2D(u_texture, v_texcoord);
}
Or use gl_FrontColor in vertex and gl_Color in fragment shader, instead of your v_color (and remove this varying as it no longer needed).
Of course vertex gl_Color attribute comes from glColorPointer, - if you changed that colors, it would be changed in shader too.

boost spirit parsing GLSL varyings

Boost::spirit seems to contain so much template magic that I can't understand the docs..
I would like to parse GLSL (OpenGL Shader source) and extract in and out attribute names and their types from the source. I'm restricting GL API version to GL 3.3 so usingsimply GL_ARB_interface_query is no option and I need to read the strings directly from the shader source.
Here is the GLSL source from what I try extract "in vec2 ks_Vertex;" "flat out int SpriteTexID;" parts. Tricky part is that some of the out varyings are in interface block like this:
out VertexData {
smooth vec4 Color;
smooth vec2 TexCoord;
};
I need to extract the "VertexData", "vec4 Color" and "vec2 TexCoord" strings.
The full source:
#version 150
uniform isamplerBuffer ks_MaterialIDBuffer;
in vec2 ks_Vertex;
in vec4 ks_Color;
in vec2 ks_TexCoord;
layout(shared) uniform Camera {
vec2 Position;
vec4 Viewport;
mat4 ModelviewProjMatrix;
mat4 ModelviewMatrix;
mat4 ProjectionMatrix;
};
out VertexData {
smooth vec4 Color;
smooth vec2 TexCoord;
} Out;
flat out int SpriteTexID;
flat out int SpriteMaterialID;
void main()
{
int sprid = gl_VertexID / 4;
ivec4 material = texelFetch(ks_MaterialIDBuffer, sprid);
Out.Color = ks_Color;
Out.TexCoord = ks_TexCoord;
gl_Position = ModelviewProjMatrix * vec4(ks_Vertex, 0.0f, 1.0f);
SpriteTexID = material.r;
SpriteMaterialID = material.g;
}
I especially need the out varying names, but I have no idea how to construct such parser with boost::spirit. I barely made a lexer that counts words.. How do I define such parser with boost::spirit?