After a lot of reading I was able to understand the steps needed to load a texture in OpenGL ES 2.0, but some question are still not answered:
What's the code below is actually doing?
glUniform1i(sampler2DLocation, 0);
If I erase this line from my code, nothing changes. Some books describe it as "Tell the texture uniform sampler to use this texture in the shader by telling it to read from texture unit 0"
This is called after the line:
glActiveTexture(GL_TEXTURE0);
But as stated in khronos.org the default active texture is GL_TEXTURE0, so I guess the line "glActiveTexture(GL_TEXTURE0);" code is just written as a good practice?
One last thing, when I call:
glBindTexture(GL_TEXTURE_2D, genTextures[0]);
I'm saying that future calls that affect "GL_TEXTURE_2D" will affect the texture unit stored in genTextures[0], due the binding. But there is any relation between "GL_TEXTURE_2D" and the active texture unit? I mean, there is an intrinsic chain between the 03 "components"?
genTextures[0] <---> GL_TEXTURE_2D <---> the active texture unit
Thank you,
The reason why the code continues to work even if you remove the instruction "glUniform1i(sampler2DLocation, 0);" is due, possibly to the default value assigned by the driver when the uniform is not provided.
To better understand it I would need an example of the shared code and the way the uniform ID is taken but I am pretty sure that the instruction is there to say to the GPU through the shader to use the texture unit 0.
The effect of calling "glUniform1i(sampler2DLocation, 0);" says take texture unit 0.
The effect of not calling it, sets anyway the sampler uniform to 0 and therefore, even if not formally correct, has the same behavior.
According to OpenGL standard, you activate a texture unit with the glActivateTexture which requires the number of the texture unit and then you bind the texture with glbindtexture to that specific current texture unit.
In other words, first you set the texture unit you want to work on and then you tell to the driver which texture needs to be bound in it.
I hope this helps.
Maurizio
Related
I thought you could modify a Uniform variable and then use this method to get the variable after draw but it throws a cannot modify uniform exception when building the shader.
glGetUniformfv(PROGRAM_INT, UNIFORM_INT, PARAMS, 0);
I want the shader to modify a variable and return that variable?
Is there a way to modify a shaders variable, and a use a GL method to get that variable?
No. Uniform variables are read-only in the shader code. They are used to pass values from your Java/C++ client code to the shader code, and not the other way.
In ES 2.0, the only way I can think of to get values that were produced by the shader back into the client code is to produce them as color values in the fragment shader output. They will then be part of the framebuffer content, which you can read back with glReadPixels().
In newer versions of OpenGL ES, as well as in recent versions of full OpenGL, there are additional options. For example, ES 3.1 introduces Shader Storage Buffers, which are also available in OpenGL 4.3 and later. They allow shaders to write values to buffers, which you could read back from client code.
looking at the code in Texture2dProgram.java I cannot find the where the uniform for sTexture is defined. Others like aPosition are defined in the constructor.
Being a novice in opengl it looks like the fragment shader uses the current texture unit and a texture is bound to that texture unit so is sTexture a default pre defined name.
There is nothing magic about sTexture. It's a sampler2D, which has a default value of 0 (or GL_TEXTURE0), which is what we want. There's no need to change its value, hence no need to get the uniform address.
I'm developing an app for Android devices using OpenGL ES 2.0 and am having trouble understanding how to move my camera - (ultimately, I'm attempting to produce a 'screen shaking' effect - so I need all currently rendered objects to move in unison).
So, at the moment, I have a SpriteBatch class which I use to batch up a load of entities and render them all in a single OpenGL call.
Within this class, I have my vertex and fragment shaders.
So, I simply create an instance of this class for my objects..... something like:
SpriteBatch tileSet1 = new SpriteBatch(100); //100 tiles
I'll then render it like this:
tileSet1.render();
Within my GLSurfaceView class (in onSurfaceChanged), I am setting up my view like this:
//offsetX, offsetY, width and height are all valid and previously declared)
GLES20.glViewport(offsetX, offsetY, width, height);
Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
Then, within my onDrawFrame() method, I simply call all of my logic and rendering like this:
logic();
render();
(Obviously, my game loop has been greatly simplified for the purpose of this question).
I really am not sure where I'm supposed to put Matrix.setLookAtM.
I've tried placing it into my 'GLSufaceView' class - again, in onSurfaceChanged, but it doesn't seem to have any effect. How does setLookAtM work in relation to the shaders? I ask because my shaders are in my 'SpriteBatch' class and belong to instances of that class (I could be misunderstanding this completely though).
If any more code is required, please ask and I will post.
Would appreciate a pointer in the right direction.
Calls like Matrix.orthoM() and Matrix.setLookAtM() do not change your OpenGL state at all. They are just utility methods to calculate matrices. They set values in the matrix passed to them as the first argument, and nothing else.
Applying those matrices to your OpenGL rendering is a separate task. The main steps you need for this in a typical use case are:
Declare a uniform variable of type mat4 in your vertex shader.
uniform mat4 ProjMat;
Use the matrix while transforming vertices in the vertex shader code:
gl_Position = ProjMat * ...;
In your Java code, get the location of the uniform variable after compiling and linking the shader:
int projMatLoc = GLES20.glGetUniformLocation(progId, "ProjMat");
Calculate the desired matrix, and use it to set the value of the uniform variable:
Matrix.orthoM(projMat, ...);
...
GLES20.glUseProgram(progId);
GLES20.glUniformMatrix4fv(projMatLoc, 1, false, projMat, 0);
Note that uniform values have shader program scope. So if you have multiple shader programs that use the matrix, and want to change it for all of them, you'll have to make the glUniformMatrix4fv() call for each of them, after making it active with glUseProgram().
I'm new to open gl in android and I need to draw some text in my GLSurfaceView. I found only one solution - to create bitmap with text and display it like texture (like this, for example; http://giantandroid.blogspot.ru/2011/03/draw-text-in-opengl-es.html). I tried to do like this, but it didn't work for me. What is textures array in this code? And is there any simplier way to display text?
openGL by itself doesn't offer any "simpler" way to render text - it even doesn't "know" anything about the way glyphs may be represented in bitmap or outline font sets.
Using some other library "knowing" how to handle different font sets and how to rasterize them to directly let them paint into an openGL texture doesn't seem so complicated that any other approach may claim to be a lot easier.
You might want to take a look at both this (see: Draw text in OpenGL ES) article here on stackoverflow as well as into the linked pages to get an overview of other methods available to choose the one that seems best to you.
Regarding your second question about the textures array in the code sample you linked the array is just used to fulfill the API requirements of the call to glGenTextures() as it expects an array as the second argument.
In fact just a single texture id is allocated in this line:
gl.glGenTextures(1, textures, 0);
Taking a look at the spec (see: http://docs.oracle.com/javame/config/cldc/opt-pkgs/api/jb/jsr239/javax/microedition/khronos/opengles/GL10.html) it turns out there is just a single texture id allocated stored at index 0 in the textures array.
Why then a (pseudo) array at all?
The seemingly complex signature of the java method
public void glGenTextures(int n, int[] textures, int offset)
is due to the fact that there are no pointers in java while the C function that gets wrappped requires a pointer as it's second argument:
void glGenTextures(GLsizei n, GLuint *textures);
As in C code allocating a single texture can be done with:
GLuint texture_id;
glGenTextures (1, &texture_id);
there is no need for a special function just returning a single texture id, so there's only a single glGenTextures() function available.
To allow for allocations that can be done with pointer arithmetic like:
GLuint textures[10];
glGenTextures (3, textures + 5);
in C the java wrapper allows for a third parameter specifying the starting index from which to assign allocated texture ids.
The corresponding method invocation in java would look like this:
int[] textures = new int[10];
glGenTextures (3, textures, 5);
Thus one more parameter in java wrapper and the requirement to use an array even if only a single id is needed.
I am trying to do some GPGPU using OpenGL ES 2.0.
It seems to me that the GL_NV_draw_buffers and the GL_OES_texture_float extensions are some of the essentials here.
This question relates to the GL_OES_texture_float extension: From the desktop world I'm used to textures being in the [0..1] range when accessed in the shader if the format is fixed point (like GL_RGBA).Consulting the respective OES extension page, it says: " ... If the internal format of the texture is fixed-point, components are clamped to [0..1]. Otherwise, values are not modified."
Now I've heard several times on the web (for example the answer here: Do OpenGL GLSL samplers always return floats from 0.0 to 1.0?) that ES 2.0 supports access to unclamped values in the fragment shader, too. But where is this functionality specified? The extension says "otherwise, values are not modified" but since the OpenGL ES specification only knows fixed-point formats it doesn't make sense to me.
Also, as I understand it, the extension only specifies that float values can be read from client memory into a texture but does not specify how (i.e. how many bits per channel) the texture is represented in graphics memory. Is there any official spec on this?
Finally I'd like to write unclamped floating point values to an FBO color attachment in my fragment shader, preferably using 32 bits per channel. Is this possible?