Drawing text (open gl es, android) - android

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.

Related

In openCV, using HOGDescriptor's setSVMDetector functionality with an input array

I am having some trouble with the HOGDescriptor.setSVMDetector functionality in OpenCV4Android.
Android requires a passed Mat() for the HOGDescriptor.setSVMDetector() method. Note that this differs from the C++ specification, where the function is declared as setSVMDetector(const vector<float>& detector). The question is how to input a linear SVM model in - that is, how do you turn an array of floating point values into an OpenCV4Android Mat such that a HOGDescriptor object will accept it as input to the setSVMDetector method?
I have tried analyzing the output of HOGDescriptor.getDefaultPeopleDetector(). This gives a Mat with 3781 rows, 1 column, and type CV_32F. When recreating this, and for that matter when trying any variation (e.g. transposition, 1x1 Mat with a single array entry, etc), the output is:
error: checkDetectorSize() in function virtual void cv::HOGDescriptor::setSVMDetector(cv::InputArray)
Any advice on how to set up an SVM detector this way in Android would be hugely appreciated!

What are reasons for a OpenGL program to become invalid?

I'm currently searching for a bug which is based on a OpenGL program being invalid. But it is difficult to find the source of the problem without knowing where it might come from.
When I create the program it is valid. Furthermore I don't use glDeleteProgram().
To determine wether my program is valid or not I use glIsProgram().
Generally in OpenGL, objects are not created until they are first bound.
glGenTextures (...) for instance, reserves and returns one or more names for texture objects but those names do not become actual textures until bound to something like glBindTexture (GL_TEXUTRE_2D, ...). In other words, the names are reserved but what they reference is not instantiated/initialized yet.
What glIs* (...) actually returns is whether the name you pass it is the name of a created object. Thus, if you never bind an object it is never created, and this function will return GL_FALSE.
glUseProgram (...) is the function that OpenGL uses to bind GLSL program objects. Even though GLSL program and shader objects work differently from all other types of OpenGL objects it is very likely that glIsProgram (...) is not going to return GL_TRUE until sometime after you have called glUseProgram (...) on it at least once.
Incidentally, to validate a program I would suggest you use glValidateProgram (...) instead.
Here is some C pseudo-code that demonstrates how to use glValidateProgram:
GLint valid = GL_FALSE;
glValidateProgram (program);
glGetProgramiv (program, GL_VALIDATE_STATUS, &valid);
If valid is GL_TRUE after this, your program is valid (e.g. it was successfully linked).

Texture Program - OpenGL ES 2.0 Android

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

How to customize parameters used on renderscript root function?

Background
I'm new to renderscript, and I would like to try some experiments with it (but small ones and not the complex ones we find in the SDK), so I thought of an exercise to try out, which is based on a previous question of mine (using NDK).
What I want to do
In short, I would like to pass a bitmap data to renderscript, and then I would like it to copy the data to another bitmap that has the dimensions opposite to the previous one, so that the second bitmap would be a rotation of the first one.
For illustration:
From this bitmap (width:2 , height:4):
01
23
45
67
I would like it to rotate (counter clock-wise of 90 degrees) to:
1357
0246
The problem
I've noticed that when I try to change the signature of the root function, Eclipse gives me errors about it.
Even making new functions creates new errors. I've even tried the same code written on Google's blog (here ), but I couldn't find out how he got to create the functions he used, and how come I can't change the filter function to have the input and output bitmap arrays.
What can I do in order to customize the parameters I send to renderscript, and use the data inside it?
Is it ok not to use "filter" or "root" functions (API 11 and above)? What can I do in order to have more flexibility about what I can do there?
You are asking a bunch of separate questions here, so I will answer them in order.
1) You want to rotate a non-square bitmap. Unfortunately, the bitmap model for Renderscript won't allow you to do this easily. The reason for this is that that input and output allocations must have the same shape (i.e. same number of dimensions and values of those dimensions, even if the Types are different). In order to get the effect you want, you should use a root function that only has an output allocation of the new shape (i.e. input columns X input rows). You can create an rs_allocation global variable for holding your input bitmap (which you can then create/bind on the Java side). The kernel then merely needs to set the output cell to the result of rsGetElementAt(globalInAlloc, y, x).
2) If you are using API 11, you can't adjust the signature of the root() function (you can pass NULL allocations as input, output on the Java side if you are not using them). You also can't create more than 1 kernel per source file on these older API levels, so you are forced to only have a single "root()" function. If you want to use more kernels per source file, consider targeting a higher API level.

Using a global vertex cache and still take advantage of glRotate?

I have a simple Android OpenGL-ES app, and as all the models are very simple (<10 vertices!) I have implemented a global "world" class that tracks all the vertices, and performs a single pair of GL commands on the frame rendering.
Each model object adds it's vertices to the global buffers, and these these are 'sent' to GL in one operation:
gl.glVertexBuffer(...);
gl.glDrawElements(...);
My question (perhaps an obvious answer, but I want to be sure) is, does this mean I have to do all my own rotations manually?
My base objects just define a bunch of vertices that get added to the cache, for example a triangle, a square, a pentagram, etc. My World object then takes the big array of vertices, and dumps them out to GL. If I want to rotate all those, am I correct in thinking I have to perform my own vertex coordinate manipulations (trigonometry!)?
I guess it's not the end of the world to have to create some utility functions to rotate all the vertices in my models, but I'd rather not if it's not necessary.
Yes, unfortunately that is the price to pay for performing a single draw callfor multiple models. The calculations are really quite simple, if you use the standard Scale-Rotate-Translate order.
For every vertex:
Determine the distance to the center: Xrel = X-Xcenter and Yrel = Y-Ycenter
Multiply that by the scale for x and y. Xscaled = scalex*Xrel and Yscaled = scalex*Yrel.
Determine the new positions relative to the center after rotation: Xrot = Xscaled*cos(d)-Yscaled*sin(d) and Ynew = Xscaled*sin(d)+Yscaled*cos(d).
Move the vertices with the translation: Xnew = Xrot + translatex and Ynew = Yrot+translatey.
Easy! Cheers, Aert.
No, using glRotate will work fine with vertex arrays.

Categories

Resources