I am following a tutorial by dermetfan on shaders and although my code seems to be pretty much identical, it does not perform what is intended. No compiling error happens and no logs are written.
ShaderProgram.pedantic = false;
shader = new ShaderProgram(Gdx.files.internal("shaders/red.vsh"), Gdx.files.internal("shaders/red.fsh"));
System.out.println(shader.isCompiled() ? "Compiled shader!" : shader.getLog());
batch.setShader(shader);
and this code is the vsh
attribute vec4 a_color;
attribute vec3 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoord0;
void main(void) {
v_color = a_color;
v_texCoord0 = a_texCoord0;
gl_Position = u_projTrans * vec4(a_position, 1.);
}
and heres the .fsh
varying vec4 v_color;
varying vec2 v_texCoord0;
uniform sampler2D u_sampler2D;
void main() {
gl_FragColor = texture2D(u_sampler2D, v_texCoord0) * v_color;
gl_FragColor = vec4(1.,0.,0.,1.);
}
If i get rid of the shader my texture loads just fine, however when I run with the shader my textures seem to vanish.
EDIT
Please try to stray from looking for errors in the code, ShaderProgram.pedantic = false and I know for a fact my code is identical to the tutorial I am watching and yet his works and mine doesn't. Thank you for any help!
Related
I currently have a default sprite batch:
batch = new SpriteBatch();
I have read about using shaders to modify how the batch draws each sprite. In my game, I am try to create a 'nighttime' effect - I want every pixel on screen to be black, except for pixels that are already white. For the white pixels, I want a shade of blue. Obviously I am new to libgdx and openGL - can anyone who is familiar with blending or shaders help me out with this? What should I do to my spritebatch to achieve the effect that I am describing?
Effect which you would like to achieve could be done with something like this.
Vertex Shader
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main()
{
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
Fragment shader
precision mediump float;
varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;
bool equals(float a, float b) {
return abs(a-b) < 0.0001;
}
bool isWhiteShade(vec4 color) {
return equals(color.r, color.g) && equals(color.r, color.b);
}
void main() {
vec4 color = texture2D (u_texture, v_texCoords) * v_color;
if(isWhiteShade(color)) {
color *= vec4(0, 0, 1, 1);
}
else {
color *= vec4(0, 0, 0, 1);
}
gl_FragColor = color;
}
Add them to assets folder and then pass as arguments while creating instance of ShaderProgram and of course don't forget to apply this shader program to your SpriteBatch.
To be honest it has (almost) nothing common with SpriteBatch - all you have to do with it is just apply created shader
batch.setShader(ShaderProgram shader)
The shaders topic is very very wide (and to be honest independent of Libgdx) and there is no simple answer to your question without informations of what it should do. Also - to be honest - try at first to read something about shaders and come back on SO when you will have some troubles with this.
You can start right here:
https://github.com/libgdx/libgdx/wiki/Shaders
I would like to create a shader to simulate a pseudo 3D water surface on a 2D scene build with libgdx. The idea is to recreate the following effect:
http://forums.tigsource.com/index.php?topic=40539.msg1104986#msg1104986
But I am stuck at creating the trapezoid shape, I think I didn't understand how texture coordinate are calculated on opengl shaders. May I modify the vertex in the vertex shader or may I displace the texture on the fragment shader?
here is a test I have done but that don't work as expected.
vertex shader:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoord0;
void main()
{
v_color = a_color;
float factor = (a_texCoord0.x - 0.5) * (a_texCoord0.y);
v_texCoord0 = a_texCoord0;
v_texCoord0.x += factor;
gl_Position = u_projTrans * a_position;
}
the fragment shader is just a passthrough
varying vec4 v_color;
varying vec2 v_texCoord0;
uniform sampler2D u_texture;
void main()
{
gl_FragColor = v_color * texture2D(u_texture, v_texCoord0);
}
and the result image
I am sure that my approach is too naive.
Finally, I decided to use only the fragment shader to achieve the effect.
Fake depth calculation is done by applying X displacement in regards of the Y axis.
Here is the snipet:
// simulate 3D surface
vec2 new_coord = v_texCoord0;
// calculate the stretching factor
float factor = ((0.5 - new_coord.x) * new_coord.y);
// apply the factor and stretch the image
new_coord.x += factor;
gl_FragColor = texture2D(u_texture, new_coord);
I'm making a program with OpenGL ES 2.0. I need to render a texture on top of another, like a clock hand. The textures are both 1024 x 1024 and are transparent. The transparency is always rendering black, and this is preventing me from overlaying the clock hand texture over the clock.
simple_fragment_shader.glsl
precision mediump float;
varying vec4 v_Color;
void main()
{
gl_FragColor = v_Color;
}
simple_vertex_shader.glsl
uniform mat4 u_Matrix;
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main()
{
v_Color = a_Color;
gl_Position = u_Matrix * a_Position;
gl_PointSize = 10.0;
}
texture_fragment_shader.glsl
precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
void main()
{
gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}
texture_vertex_shader.glsl
uniform mat4 u_Matrix;
attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;
varying vec2 v_TextureCoordinates;
void main()
{
v_TextureCoordinates = a_TextureCoordinates;
gl_Position = u_Matrix * a_Position;
}
I'm kind of new at OpenGL, and I have used textures, but I don't know how to get the transparency.
Also, if this helps, I am sort of following the methods in OpenGL ES 2 for Android by Kevin Brothaler from The Pragmatic Programmers.
Alpha value might be ignored without following settings.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
I hope this help you:)
I have the following shaders:
My fragment shader:
#version 110
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
And my vertex shader:
#version 110
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
attribute vec3 vertex;
void main() {
vec4 world = modelMatrix * vec4(vertex, 1);
vec4 camera = world * viewMatrix;
gl_Position = projectionMatrix * world;
}
They both compile and link just fine. When I print out my active uniforms I get
projectionMatrix
modelMatrix
but no viewMatrix. When I try and get the Uniform with glGetUniformLocation, I can get projectionMatrix, modelMatrix, and my vertex attribute just fine, so why is viewMatrix inactive?
The problem lies in the last line of your vertex shader:
gl_Position = projectionMatrix * world;
You probably meant projectionMatrix * camera. Otherwise, the GLSL compiler sees that camera isn't being used and optimizes it away, which means that viewMatrix is no longer being used either. Unused uniforms are not considered active, which leads to your predicament.
Note: Your viewing transform is also backwards. You probably want vec4 camera = viewMatrix * world.
I try to setup my shader like this:
fog = new ShaderProgram(Gdx.files.local("shader/shad.vert"), Gdx.files.local("shader/shad.frag"));
But it gives me this exception:
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: java.lang.NullPointerException
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:113)
Caused by: java.lang.NullPointerException
at com.badlogic.gdx.graphics.glutils.ShaderProgram.loadShader(ShaderProgram.java:194)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.compileShaders(ShaderProgram.java:173)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.<init>(ShaderProgram.java:156)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.<init>(ShaderProgram.java:165)
at Comet.Avoider.CometAvoider.create(CometAvoider.java:73)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:127)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:110)
My shaders are these:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
and
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main() {
gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
}
I don't know where the error is :( i cannot fix it. i hope u can help me.
Thanks!
Here's the source to ShaderProgram's loadShader:
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/glutils/ShaderProgram.java#L196
The constructor reads the contents of the files, so since you got past that part the files are probably okay.
I suspect its this line:
GL20 gl = Gdx.graphics.getGL20();
(You can try this yourself directly in your code to see if it blows up).
The doc says getGL20() will return null if your app is not configured for OpenGL ES 2.0. By default you get 1.x support. Shaders are not supported by the 1.x versions of OpenGL ES, so you must configure your application by setting the useGL20 flag in your application configuration. See https://code.google.com/p/libgdx/wiki/ApplicationConfiguration
Debug:
Gdx.files or Gdx are null? this should be your problem.