Related
I have a tetrahedron object created in openGL ES 2.0. What I'm trying to achieve is to show the actual wireframe of the polygon over its base color. Is there a method for achieving this effect?
Also, my tetrahedron is pink. How can I change its color?
1: First draw your object as usual, then draw it again (with a different shader, or it will be the same color as the object and thus invisible), using GLES20.GL_LINES, GL_LINE_LOOP or GL_LINE_STRIP.
You might want to scale the object up slightly when drawing the lines so that the depth-testing don't decides that the lines are behind the object and ignores them.
2: This is done in your shader, set gl_FragColor to a vec4 containing your wanted rgba-values for a solid color.
In addition to what Jave said. Instead of enlarging the whole object (whose optimal amount always depends on the object and the current view) to prevent z-fighting artefacts, you can also use the polygon offset (using glPolygonOffset), whose major application are indeed wireframe overlays.
It basically works by slightly adjusting the depth values of the resulting fragments, which you cannot achieve differently in ES, since you cannot write to the depth buffer (which I guess is the reason they didn't drop it from ES, like they did in desktop GL 3+). So you basically render your solid object and your line-version of the object using the same vertices, but using a polygon offset configuration for the solid object that slightly increases the resulting fragments' depth values (pushes them away from the viewer), thus placing the triangles always behind the lines in view space (or window space actually). See here for further information.
Though the case of a tetrahedron might make some problems because of its very sharp edges.
Although this has been here a little while (over a year now), this may also help: Note that you may not need to use another shader to achieve the desired result. You can disable the vertex attribute array then specify and load the constant vertex attribute data (the wireframe line color) to draw the wire frame. For example:
float coloredcube[] = { 2, 2, 2, 1, 0, 0, -2, 2, 2, 0, 1, 0, -2, -2, 2, 0,
0, 1, 2, -2, 2, 1, 1, 0, 2, 2, -2, 1, 0, 1, -2, 2, -2, 0, 1, 1, -2,
-2, -2, 1, 1, 1, 2, -2, -2, 0, 0, 0
};
short indices[] = { 0, 1, 2, 0, 2, 3, //back
0, 4, 7, //right
0, 7, 3,
7, 6, 2, //bottom
7, 2, 3,
4, 5, 6, //front
4, 6, 7,
5, 1, 2, //left
5, 2, 6,
0, 1, 5, 0, 5, 4 //top
};
short lineindices[] = { 0, 1, 1, 2, 0, 2, 2, 3,
0, 4, 4, 7, 0, 7, 7, 3,
7, 6, 6, 2, 7, 2, 4, 5,
5, 6, 4, 6, 5, 2, 1, 5, 0, 5, 0, 3 };
glVertexAttribPointer(iPosition, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube);
glEnableVertexAttribArray(iPosition);
glVertexAttribPointer(iColor, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),coloredcube + 3);
glEnableVertexAttribArray(iColor);
// offset the filled object to avoid the stitching that can arise when the wireframe lines are drawn
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(2.0f, 2.0f);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, indices);
glDisable(GL_POLYGON_OFFSET_FILL);
//Then disable the vertex colors and draw the wire frame with one constant color
glDisableVertexAttribArray(iColor);
glLineWidth(1.0f);
GLfloat color[4] = { 1.0f, 0.0f, 0.0f, 0.5f };
glVertexAttrib4fv(iColor, color);
glDrawElements(GL_LINES, 36, GL_UNSIGNED_SHORT, lineindices);
A similar example can be found in "The OpenGL ES 2.0 programming guide" pp 109,110.
I'm rendering simple scene with library GLESv1_CM on Android with NDK.
void render(Rect viewport)
{
glViewport(viewport.left, viewport.top, viewport.Width(), viewport.Height());
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(viewport.left, viewport.right, viewport.top, viewport.bottom, -1, 1);
GLfloat points[] = { 5, 50, 1, 1, 1, 1,
7, 50, 1, 1, 1, 1,
7, 50, 1, 0, 0, 1,
7, 52, 1, 0, 0, 1,
8, 50, 0, 1, 0, 1,
10, 50, 0, 1, 0, 1};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2,GL_FLOAT,sizeof(GLfloat)*6,&points);
glColorPointer(4,GL_FLOAT,sizeof(GLfloat)*6,&points[2]);
glDrawArrays(GL_LINES,0,6);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
I wish to have 3 crossed lines, but when I run it on device with android 2.2 or 3.2 i have this:
Even more, on Android emulator with Android 4 (update: same on emulator with 2.3) i have this:
Is it possible to make it looks like on this picture on all devices with all Android versions without using opengl2?
Thank you
According to the OpenGL FAQ for this type of projection:
If exact pixelization is required, you might want to put a small
translation in the ModelView matrix, as shown below:
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glTranslatef (0.375, 0.375, 0.);
I imagine this reduces the likelihood of rounding issues.
I've searched the web for help and although it looked like a solution it turned out to not work so good. For starters I'd like to say I've just jumped into android programming (this is my first day) I really learn by trial and error I'd like it that if you could help me you'd give me hints rather than paste the code in front of me.
my tileset
http://img217.imageshack.us/img217/4654/tileseth.png
the result
http://img199.imageshack.us/img199/7913/resultx.png
the issues I'm having is 1. it is obviously not splitting the image in 32 by 32 bits. is what I'm trying to achieve is take my big image and split it into 9* smaller images of 32 by 32 portions. Secondary the image quality gets distorted and I can't work out why.
*I don't want to use a 9 patch as there will be more then 9 images soon just a fluke that atm I have 9 images
my code (evidently plagiarized from the internet)
tilesetSliced = Bitmap.createScaledBitmap(bmp, 96, 96, true);
tileset[0] = Bitmap.createBitmap(tilesetSliced, 0, 0, 32, 32);
tileset[1] = Bitmap.createBitmap(tilesetSliced, 32, 0, 32, 32);
tileset[2] = Bitmap.createBitmap(tilesetSliced, 64, 0, 32, 32);
tileset[3] = Bitmap.createBitmap(tilesetSliced, 0, 32, 32, 32);
tileset[4] = Bitmap.createBitmap(tilesetSliced, 32, 32, 32, 32);
tileset[5] = Bitmap.createBitmap(tilesetSliced, 64, 32, 32, 32);
I'll make it more efficent once I got it working >.< any help would be great
the on draw
public void onDraw(Canvas canvas) {
//update();
for(int x=0; x<= mapWidth; x++){
for(int y = 0; y <= mapHeight; y++){
canvas.drawBitmap(tileset[map[x][y]], x *32, y*32, null);
}
}
}
o.k some more debugging has shead light on something 1. I removed the scaledbitmap that stopped the quality being destroyed (orginally ahd it due to bugs) however I found out that for some reason it thinks the width of my tileset is 64 when its 96 any help would be nice on this.
You may have more luck with a Bitmap Factory to generate your tilesetSliced. Within it is an Options class that allows you to set the sample size (inSampleSize) which can be used to scale down your image. It may not be precise enough for your needs, however.
Your images are likely distorted due to the scaling down process. Are you able to create these images with the right dimensions or pre-scale them?
I am trying to load a texture on to my android app display, where I am using code from this github.
I get my pixels messed up completely on the screen, And I have no idea, what's going on. The only thing I change in that code is I have memcpy, which copied uint8_t buffer into s_pixels instead of render_pixels in glbuffer.c file. My frame pixels are in rgb565 format.
Is it somekind of configuration problem or any problem with the way I copy pixels?
EDIT
Below is the code :
pictureQ is as below
pictureQ {
uint8_t *data;
int size;
}
memcpy(s_pixels,&(pictureQ[qFirst].data[0]) , 307200);
//render_pixels(s_pixels);
glClear(GL_COLOR_BUFFER_BIT);
// glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 480, 320, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, &(pictureRGBQ[qFirst].data[0]));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 480, 320, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, s_pixels);
check_gl_error("glTexSubImage2D");
glDrawTexiOES(0, 0, 0, s_w, s_h);
check_gl_error("glDrawTexiOES");
memset(s_pixels, 0, 307200);
Ok, It was my mistake, I was passing the data for the pixels instead of the data. Thanks for your response Reuben Scatton.
The Android TextView clips off my text subscripts (see image below) even when I use android:layout_height="wrap_content" for the TextView.
Is there a fix/work-around for this?
P/S: Superscripts work fine
Note: padding doesn't work.
I tried even adding a padding of 50dip but it did not help.
I can use an absolute height such as 50dip but that messes everything up when I need text to wrap around.
Sample Code:
mtTextView.setText(Html.fromHtml("HC0<sub>3</sub>"));
Most answers suggest to add paddings or to use smaller sub/superscripts. These might be serviceable workarounds, but they don't really solve the problem. Ideally, we want Android to take the sub/superscript into account when calculating line height. I think I found how to do it, and I'm sharing it for people googling this issue.
SpannableStringBuilder sb = new SpannableStringBuilder("X2");
sb.setSpan(new SuperscriptSpan(), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sb, BufferType.SPANNABLE);
The trick is in BufferType.SPANNABLE. Apparently it makes TextView pay more attention to the markup and calculate line heights properly.
This solution worked for me.
Superscripted text is usually made smaller when the browser renders it, that doesn't seem to happen here so you can replicate that (and solve this problem) by doing this:
someTextView.setText(Html.fromHtml("Some text<sup><small>1</small></sup>"));
For subscript a slight variation to the above suggestion is needed, two small tags:
textView.setText(Html.fromHtml(
"HCO<sub><small><small>3</small></small></sub>));
android:lineSpacingExtra="4dp" should solve it
this will add extra line spacing below your text, and keep subscript from getting cutoff. I haven't tried it with superscript so it might now fix that.
I had the same issue, so after reading the posts, I found this to be working.
Example : H2O
simply use :
textView.setText(Html.fromHtml("H<sub>2</sub>O"),BufferType.SPANNABLE);
BufferType.SPANNABLE is important as it will tell textview to consider the superscript span.
If you are using custom tag handler for HTML you can also use it like this:
textView.setText(Html.fromHtml(data, null, new CustomHtmlTagHandler(),BufferType.SPANNABLE);
Hope it helps someone looking for same problem.
I'm displaying fractions and mixed numbers so I'm using both super and subscripting together. The Html.fromHtml didn't work for me, it either clipped the top or the bottom.
Oddly, mixed numbers worked correctly, but fractions by themselves did not.
I ended up using a SpannableString with a SubscriptSpan or a SuperscriptSpan, then setting the font size in a TextAppearanceSpan.
Once I had done that I had to expand the height of the TextView as well.
TextView number = (TextView)findViewById(R.id.number);
String temp = "1 1/2";
SpannableString s = new SpannableString(temp);
// if the string has a fraction in it, superscript the numerator and subscript the denominator
if (temp.indexOf('/') != -1)
{
int len = temp.length();
s.setSpan(new SuperscriptSpan(), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 3, len - 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 2, len - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new SubscriptSpan(), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new TextAppearanceSpan(null, 0, fractionFontSize, null, null), len - 1, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
number.setText(s);
Then I had to expand the height:
RelativeLayout.LayoutParams parms = (RelativeLayout.LayoutParams)number.getLayoutParams();
Rect frame = CalcSize(number.getTextSize(), quantityMaxString);
parms.height = frame.height() + fractionAdjustment;
number.setLayoutParams(parms);
CalcSize returns a bounding rectangle of the largest string in the array of display elements.
fractionAdjustment is an emperically selected value that works for the selected font size adjusted for screen geometry.
Note: This is TextView is inside a ListView, so that might have some impact as well.
// calculate the field dimensions, given the font size and longest string
private static Rect CalcSize(float fontSize, String maxString)
{
Rect bounds = new Rect();
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(fontSize);
paint.getTextBounds(maxString, 0, maxString.length(), bounds);
return bounds;
}
Empirical values:
fractionAdjustment = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 14, resources.getDisplayMetrics());
fractionFontSize = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 11, resources.getDisplayMetrics());
I have faced the same issue in ICS and below android versions. I fixed the issue by a simple step
Give a minimum height to the Text View . It will fix the problem.
You can set minimum height through xml .
android:minHeight="30dp"
Or dynamically
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
tv.setMinHeight(52);
}
This worked for me along with the Small tag.
Inside the TextView add
android:paddingBottom="1dp"
Use the small Tag after the subscript
yourTextView.setText(Html.fromHtml("" +" Hey< sub >< small >2< /small > < /sub >"));
Note Please note , step 1 is important , My text was still cutting down in some case,using paddingBottom resolved it.
Don't forget to remove the spaces in sub and small tags that are present in my answer :)
The More number of <small> </small> tags in there, the smaller the subscript will get and you should be able to see it without being clipped.
Eg: H2O
Html.fromHtml("H<sub><small><small><small>2</small></small></small></sub>O");