Transforming the camera using a Matrix4f - java

I have a 3D scene with one triangle and a camera I want to move around. I stored the camera transformation as a matrix (specificially, a Matrix4f object loaded with the identity).
Here are two examples of methods that would modify that matrix:
This one rotates it a negative amount on the y axis:
public void turnRight() {
getCameraMatrix().rotate(-ROTATION_INTERVAL, new Vector3f(0, 1, 0));
}
This one translates right:
public void right() {
getCameraMatrix().translate(new Vector3f(TRANSLATION_INTERVAL, 0, 0));
}
I set the projection matrix to orthographic (having previously called glViewport()):
public void performProjection() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getWidth(), 0, Display.getHeight(), 0, 1000);
}
And change the camera position before drawing the scene every time the camera moves:
public void performLook() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrix(
getAsFloatBuffer() //Gets the FloatBuffer from the matrix.
);
}
However, the effect of this transformation is that the triangle is translated and rotated, not the camera. As an example of how this should happen, if the right() is called, the camera should move right perpendicular to its current orientation, not down some axis.
Any tips on how to do this? (Our assignment forbids modern openGL for some reason.)
EDIT
In case it's useful, the coordinates for the triangle are: (1, 1, 1), (1, 50, 1), (50, 50, 1)
The viewport call is glViewport(0, 0, Display.getWidth(), Display.getHeight());
And finally, the Display dimensions are 640x480
If there's anything about my question that needs clarification, please let me know. Thanks.
EDIT
The camera matrix is the model view matrix in my code. I built it by creating a new Matrix4f object and loading the identity. All subsequent transforms were added to the matrix, whose data is then moved to the model view matrix when performLook() is called. I'm only drawing a single primitive right now, so I haven't yet dealt with object to world transforms.
The render steps are:
1. performProjection()
2. performLook()
3. Clear the screen
4. Draw the primitive
5. Swap the buffers.

Related

JOGL correct light and reflection in spheres

I'm trying to get the lights and reflection correct in my program. I have a big sphere, which I can move the the mouse, that should be a light source (LIGHT0), and smaller spheres bouncing around that should reflect the light. I also need a directional light that I can change the direction using the keyboard
first some colors I defined:
float whitish[] = {0.8f, 0.8f, 0.8f, 1};
float white[] = {1, 1, 1, 1};
float blackish[] = {0.2f, 0.2f, 0.2f, 1};
float black[] = {0, 0, 0, 1}
I create the directional light with
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, spot_position,0);
spot_position is initially [ 0, 0, 1, 0] but it can change by pressing the keyboard keys. a key press adds 0.05 to a specific component of the position vector, until it reaches 1, then it resets back to -1 (nothing fancy).
The light of the center sphere is:
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, white,0);
This light's position is always centered inside my big transparent sphere. w component of the position vector is 1.
I have this code to draw the picture in the back
gl.glBegin(GL_QUADS);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, white,0);
// Back Face
gl.glNormal3f(0, 0, 1);
gl.glTexCoord2f(texRight, texBottom);
gl.glVertex3f(rx2, ry1, rz1);
gl.glTexCoord2f(texRight, texTop);
gl.glVertex3f(rx2, ry2, rz1);
gl.glTexCoord2f(texLeft, texTop);
gl.glVertex3f(rx1, ry2, rz1);
gl.glTexCoord2f(texLeft, texBottom);
gl.glVertex3f(rx1, ry1, rz1);
To draw the spheres, I use the following functions:
public void drawtriangle(float[] v1, float[] v2, float[] v3) {
gl.glBegin(GL.GL_TRIANGLES);
gl.glNormal3fv(v1, 0);
gl.glVertex3fv(v1, 0);
gl.glNormal3fv(v2, 0);
gl.glVertex3fv(v2, 0);
gl.glNormal3fv(v3, 0);
gl.glVertex3fv(v3, 0);
gl.glEnd();
}
private void subdivideSphere2(float v1[], float v2[], float v3[], long depth) {
float v12[] = new float[3];
float v23[] = new float[3];
float v31[] = new float[3];
int i;
if (depth==0) {
float[] color= {v1[0]*v1[0], v2[1]*v2[1], v3[2]*v3[2], alpha};
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, blackish,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, color,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, color,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, color,0);
drawtriangle(v1, v2, v3);
return;
}
for (i = 0; i<3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
normalize(v12);
normalize(v23);
normalize(v31);
subdivideSphere2(v1, v12, v31, depth-1);
subdivideSphere2(v2, v23, v12, depth-1);
subdivideSphere2(v3, v31, v23, depth-1);
subdivideSphere2(v12, v23, v31, depth-1);
}
public void drawSphere() {
subdivideSphere2(sVdata[0], sVdata[1], sVdata[2], depth);
subdivideSphere2(sVdata[0], sVdata[2], sVdata[4], depth);
subdivideSphere2(sVdata[0], sVdata[4], sVdata[5], depth);
subdivideSphere2(sVdata[0], sVdata[5], sVdata[1], depth);
subdivideSphere2(sVdata[3], sVdata[1], sVdata[5], depth);
subdivideSphere2(sVdata[3], sVdata[5], sVdata[4], depth);
subdivideSphere2(sVdata[3], sVdata[4], sVdata[2], depth);
subdivideSphere2(sVdata[3], sVdata[2], sVdata[1], depth);
}
My problem is, the small spheres aren't reflecting light at all. They are very bright all the time. I can see a little bit of the light being reflected in the green lines of the cube when I move the big sphere closer to them, but no effect at all to the spheres. Also, I can't see any difference when I move the directional light (LIGHT1). I don't see any reflection on the lines of the cube, the big sphere, small spheres or the picture in the back. Below is screenshot of my program. How can I make my spheres not shine, and reflect both the directional light and the light from the big sphere? Any help would be greatly appreciated. Thank you.
It looks like the lightning is disabled when tracing your small spheres. I don't see the code where you call the drawSphere but it really looks like you are tracing the Big sphere with GL_LIGHTING enabled and the small spheres with GL_LIGHTING disabled.
By reflect the light do you mean that it is illuminated? Reflection involves ray tracing and is a much bigger subject.
I don't have direct experience with JOGL but I've used jME3 a fair amount and this sort of problem there is usually caused either by using an unlit material (which doesn't seem to be the case here as you say it is being lit a bit), by bad normals on the object, or by simply having the ambient light and/or the ambient color of the material turned up too high.
As far as I can tell you are not setting the normals correctly. A normal should basically point into the direction you want to reflect the light to, which is usually "90° away" from the triangle (use the cross product). OpenGL will then use that normal to calculate the actual lighting reflected by the surface. See this tutorial for further explanation.
The other problem is that you use the outdated OpenGL 2.0 functionality, which does vertex-based lighting, so effectively each triangle in your sphere is lightened to the same value. If you are looking for per-pixel lighting, which is close to impossible using the outdated functionality unless the sphere has as many vertices as it has pixels on the screen, you need to update your code and use Shaders.
This tutorial isn't Java, but it explains the basics of modern OpenGL very well, and should be easily translatable to JOGL.

opengl rotation texture off center

I wrote some code to get a plain 2d box to face the mouse. It rotated just fine around its center, and everything was working great, but when i put a texture on the box, it did not rotate around the center anymore.
The code:
float imgWidth = texture.getImageWidth()*scale;
float imgHeight = texture.getImageHeight()*scale;
glLoadIdentity();
texture.bind();
glTranslatef(x, y, 0);
glRotated(rotation - 90, 0, 0, 360);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(-imgWidth, -imgHeight);
glTexCoord2f(1, 0);
glVertex2f(imgWidth, -imgHeight);
glTexCoord2f(1,1);
glVertex2f(imgWidth, imgHeight);
glTexCoord2f(0, 1);
glVertex2f(-imgWidth, imgHeight);
glEnd();
The answer is simple but with a complicated background that has to be understood.
OpenGL always rotate something not around its center but takes as center the point (0;0).
This can be an issue because if you translate your object somewhere and then your rotate it, it will rotate not on its center but around the (0;0) point (origin) creating a big rotation, I will say as a planet around the Sun.
Also OpenGL works with matrix, that with very barbaric simplification means that the operation are executed bottom to top.
// store the current model matrix
GL11.glPushMatrix();
// bind to the appropriate texture for this image
this.texture.bind();
// translate to the right location and prepare to draw
GL11.glColor3f(1, 1, 1);
GL11.glTranslated(x + (this.texture.getImageWidth() / 2), y + (this.texture.getImageHeight() / 2), 0);
GL11.glRotated(this.angle, 0, 0, 1);
GL11.glTranslated(-this.texture.getImageWidth() / 2, -this.texture.getImageHeight() / 2, 0);
// draw a quad textured to match the sprite
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(0, this.texture.getHeight());
GL11.glVertex2f(0, this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), this.texture.getHeight());
GL11.glVertex2f(this.texture.getImageWidth(), this.texture.getImageHeight());
GL11.glTexCoord2f(this.texture.getWidth(), 0);
GL11.glVertex2f(this.texture.getImageWidth(), 0);
}
GL11.glEnd();
// restore the model view matrix to prevent contamination
GL11.glPopMatrix();
This means that first I am moving the texture to have its center positioned at (0;0) that means translating it backward half the dimensions.
Then I rotate it, and this is the crucial point, because you are using a strange way to rotate it, maybe the problem it's here, take a look to the javadoc:
SPECIFICATION
void glRotated( GLdouble angle,<br>
GLdouble x,<br>
GLdouble y,<br>
GLdouble z )<br>
void glRotatef( GLfloat angle,<br>
GLfloat x,<br>
GLfloat y,<br>
GLfloat z )<br>
PARAMETERS<br>
angle Specifies the angle of rotation, in degrees.
x, y, z<br>
Specify the x, y, and z coordinates of a vector, respectively.
DESCRIPTION<br>
glRotate produces a rotation of angle degrees around the<br>
vector (x,y,z).
First of all all x,y,z values should be between 0 and 1, if you want to rotate a 2d image then you should use the z axis, so the third param will be 1 that mean that you are rotating your image around the unit vector z.
The angle should be in degree and can be either positive or negative.
Try to change your code according to the documentation and you will have your problem solved.
Also with your quad you are drawing a 2x scaled quad, you are starting from -imageWidth to +imageWidth that means 2 times the width...

Drawing filled polygon with libGDX

I want to draw some (filled) polygons with libGDX. It shoudn't be filled with a graphic/texture. I have only the vertices of the polygon (closed path) and tried to visualize with meshes but at some point this is not the best solution, I think.
My code for an rectangle is:
private Mesh mesh;
#Override
public void create() {
if (mesh == null) {
mesh = new Mesh(
true, 4, 0,
new VertexAttribute(Usage.Position, 3, "a_position")
);
mesh.setVertices(new float[] {
-0.5f, -0.5f, 0
0.5f, -0.5f, 0,
-0.5f, 0.5f, 0,
0.5f, 0.5f, 0
});
}
}
// ...
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
mesh.render(GL10.GL_TRIANGLE_STRIP, 0, 4);
}
is there a function or something to draw filled polygons in an easier way?
Since recent updates of LibGDX, #Rus answer is using deprecated functions. However, I give him/her credits for the new updated version below:
PolygonSprite poly;
PolygonSpriteBatch polyBatch = new PolygonSpriteBatch(); // To assign at the beginning
Texture textureSolid;
// Creating the color filling (but textures would work the same way)
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(0xDEADBEFF); // DE is red, AD is green and BE is blue.
pix.fill();
textureSolid = new Texture(pix);
PolygonRegion polyReg = new PolygonRegion(new TextureRegion(textureSolid),
new float[] { // Four vertices
0, 0, // Vertex 0 3--2
100, 0, // Vertex 1 | /|
100, 100, // Vertex 2 |/ |
0, 100 // Vertex 3 0--1
}, new short[] {
0, 1, 2, // Two triangles using vertex indices.
0, 2, 3 // Take care of the counter-clockwise direction.
});
poly = new PolygonSprite(polyReg);
poly.setOrigin(a, b);
polyBatch = new PolygonSpriteBatch();
For good triangulating algorithms if your polygon is not convex, see the almost-linear earclipping algorithm from Toussaint (1991)
Efficient triangulation of simple polygons, Godfried Toussaint, 1991
Here is a libGDX example which draws a 2D concave polygon.
Define class members for PolygonSprite PolygonSpriteBatch
PolygonSprite poly;
PolygonSpriteBatch polyBatch;
Texture textureSolid;
Create instances, 1x1 size texture used with red pixel as workaround. An array of coordinates (x, y) is used for initialization of the polygon.
ctor() {
textureSolid = makeTextureBox(1, 0xFFFF0000, 0, 0);
float a = 100;
float b = 100;
PolygonRegion polyReg = new PolygonRegion(new TextureRegion(textureSolid),
new float[] {
a*0, b*0,
a*0, b*2,
a*3, b*2,
a*3, b*0,
a*2, b*0,
a*2, b*1,
a*1, b*1,
a*1, b*0,
});
poly = new PolygonSprite(polyReg);
poly.setOrigin(a, b);
polyBatch = new PolygonSpriteBatch();
}
Draw and rotate polygon
void draw() {
super.draw();
polyBatch.begin();
poly.draw(polyBatch);
polyBatch.end();
poly.rotate(1.1f);
}
I believe the ShapeRenderer class now has a polygon method for vertex defined polygons:
ShapeRenderer.polygon()
You can use the ShapeRenderer API to draw simple, solid-color shapes with Libgdx.
The code you've given is a reasonable way to draw solid color polygons too. Its much more flexible than ShapeRenderer, but is a good bit more complicated. You'll need to use glColor4f to set the color, or add a Usage.Color attribute to each vertex. See the SubMeshColorTest example for more details on the first approach and the MeshColorTexture example for details on the second approach.
Another option to think about is using sprite textures. If you're only interested in simple solid colors objects, you can use very simple 1x1 textures of a single color and let the system stretch that across the sprite. Much of Libgdx and the underlying hardware are really optimized for rendering textures, so you may find it easier to use even if you're not really taking advantage of the texture contents. (You can even use a 1x1 white texture, and then use a SpriteBatch with setColor and draw()
to draw different color rectangles easily.)
You can also mix and match the various approaches, too.
Use triangulation algorithm and then draw all triangles as GL_TRIANGLE_STRIP
http://www.personal.psu.edu/cxc11/AERSP560/DELAUNEY/13_Two_algorithms_Delauney.pdf
just wanted to share my related solution with you, namely for implementing and drawing a walkZone with scene2d. I basically had to put together the different suggestions of the others' posts:
1) The WalkZone:
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.PolygonRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.EarClippingTriangulator;
import com.badlogic.gdx.math.Polygon;
import com.mygdx.game.MyGame;
public class WalkZone extends Polygon {
private PolygonRegion polygonRegion = null;
public WalkZone(float[] vertices) {
super(vertices);
if (MyGame.DEBUG) {
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(0x00FF00AA);
pix.fill();
polygonRegion = new PolygonRegion(new TextureRegion(new Texture(pix)),
vertices, new EarClippingTriangulator().computeTriangles(vertices).toArray());
}
}
public PolygonRegion getPolygonRegion() {
return polygonRegion;
}
}
2) The Screen:
you can then add a listener in the desired Stage:
myStage.addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (walkZone.contains(x, y)) player.walkTo(x, y);
// or even directly: player.addAction(moveTo ...
return super.touchDown(event, x, y, pointer, button);
}
});
3) The implementation:
The array passed to te WZ constructor is a set of x,y,x,y... points. If you put them counter-clockwise, it works (I didn't check the other way, nor know how it exactly works); for example this generates a 100x100 square:
yourScreen.walkZone = new WalkZone(new int[]{0, 0, 100, 0, 100, 100, 0, 100});
In my project it works like a charm, even with very intricated polygons. Hope it helps!!
Most answers suggest triangulation, which is fine, but you can also do it using the stencil buffer. It handles both convex and concave polygons. This may be a better solution if your polygon changes a lot, since otherwise you'd have to do triangulation every frame. Also, this solution properly handles self intersecting polygons, which EarClippingTriangulator does not.
FloatArray vertices = ... // The polygon x,y pairs.
Color color = ... // The color to draw the polygon.
ShapeRenderer shapes = ...
ImmediateModeRenderer renderer = shapes.getRenderer();
Gdx.gl.glClearStencil(0);
Gdx.gl.glClear(GL20.GL_STENCIL_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl.glStencilFunc(GL20.GL_NEVER, 0, 1);
Gdx.gl.glStencilOp(GL20.GL_INVERT, GL20.GL_INVERT, GL20.GL_INVERT);
Gdx.gl.glColorMask(false, false, false, false);
renderer.begin(shapes.getProjectionMatrix(), GL20.GL_TRIANGLE_FAN);
renderer.vertex(vertices.get(0), vertices.get(1), 0);
for (int i = 2, n = vertices.size; i < n; i += 2)
renderer.vertex(vertices.get(i), vertices.get(i + 1), 0);
renderer.end();
Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glStencilOp(GL20.GL_ZERO, GL20.GL_ZERO, GL20.GL_ZERO);
Gdx.gl.glStencilFunc(GL20.GL_EQUAL, 1, 1);
Gdx.gl.glEnable(GL20.GL_BLEND);
shapes.setColor(color);
shapes.begin(ShapeType.Filled);
shapes.rect(-9999999, -9999999, 9999999 * 2, 9999999 * 2);
shapes.end();
Gdx.gl.glDisable(GL20.GL_STENCIL_TEST);
To use the stencil buffer, you must specify the number of bits for the stencil buffer when your app starts. For example, here is how to do that using the LWJGL2 backend:
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
config.stencil = 8;
new LwjglApplication(new YourApp(), config);
For more information on this technique, try one of these links:
http://commaexcess.com/articles/7/concave-polygon-triangulation-shortcut
http://glprogramming.com/red/chapter14.html#name13
http://what-when-how.com/opengl-programming-guide/drawing-filled-concave-polygons-using-the-stencil-buffer-opengl-programming/

OpenGL ES sphere issues

I've been following the tutorials http://www.learnopengles.com and learning more how to work with OpenGL ES but I'm having a hard time trying to get a sphere to show up.
I've went ahead and made a geodesic sphere in Blender and imported the vertices and the draw order but I whenever I call the sphere the app crashes.
I'll include a link to my full render file but I'll also point out what I think some of the key things where I think problems might be:
Here is where the buffers are created. I'm not sure if the app has issues with the way I'm buffering the sphere or the sphere's draw order points.
// Initialize the buffers.
mCubePositions = ByteBuffer.allocateDirect(cubePositionData.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubePositions.put(cubePositionData).position(0);
mSpherePositions = ByteBuffer.allocateDirect(spherePositionData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
mSpherePositions.put(spherePositionData).position(0);
ByteBuffer dlb = ByteBuffer.allocateDirect(sphereDrawOrder.length * 2).order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(sphereDrawOrder);
drawListBuffer.position(0);
mCubeColors = ByteBuffer.allocateDirect(cubeColorData.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeColors.put(cubeColorData).position(0);
mCubeNormals = ByteBuffer.allocateDirect(cubeNormalData.length * mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeNormals.put(cubeNormalData).position(0);
And here is the class that draws the sphere. I have no colors or normals for the sphere so I just removed those parts. Is that what's causing it to freak out?
private void drawSphere()
{
// Pass in the position information
mSpherePositions.position(0);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
0, mSpherePositions);
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Pass in the color information
// Pass in the normal information
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// Draw the sphere.
GLES20.glDrawElements(GLES20.GL_TRIANGLES, sphereDrawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
Whenever it crashes it tells me there's something wrong with the code after //Draw the sphere. It doesn't like the glDrawElements for some reason.
Here is the full render script for reference: http://pastebin.com/Y1WU27hz
If you have any insight to this I thank you.

Android - OpenGL - Emulator vs Actual Device

I am writing a game which uses opengles. I have created my renderer class and have a sample of my game working on the emulator, however none of the texures display on an actual device. I have read about the most common cause for this being the need for texture to be a factor of 2 however I have tried drawing a square (128x128) with a texture of the same size mapped to it and this only shows on the emulator. Further to that my actual game will be using rectangles so I'm unsure how I can map textures that are squares to rectangles..
This is my code so far (The game is 2d so I'm using ortho mode):
EDIT: I have updated my code, it is now correctly binding textures and using textures of size 128x128, still only seeing textures on the emulator..
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
byteBuffer = ByteBuffer.allocateDirect(shape.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(cardshape);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(shape.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(textureshape);
textureBuffer.position(0);
// Set the background color to black ( rgba ).
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// Enable Smooth Shading, default not really needed.
gl.glShadeModel(GL10.GL_SMOOTH);
// Depth buffer setup.
gl.glClearDepthf(1.0f);
// Enables depth testing.
gl.glEnable(GL10.GL_DEPTH_TEST);
// The type of depth testing to do.
gl.glDepthFunc(GL10.GL_LEQUAL);
// Really nice perspective calculations.
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
loadGLTexture(gl);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
gl.glPushMatrix(); // Push The Matrix
gl.glLoadIdentity(); // Reset The Matrix
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glLoadIdentity();
gl.glTranslatef(card.x, card.y, 0.0f);
gl.glBindTexture(GL10.GL_TEXTURE_2D, card.texture[0]); //activates texture to be used now
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
// Sets the current view port to the new size.
gl.glViewport(0, 0, width, height);
// Select the projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset the projection matrix
gl.glLoadIdentity();
// Calculate the aspect ratio of the window
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
100.0f);
// Select the modelview matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
// Reset the modelview matrix
gl.glLoadIdentity();
}
public int[] texture = new int[1];
public void loadGLTexture(GL10 gl) {
// loading texture
Bitmap bitmap;
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.image);
// generate one texture pointer
gl.glGenTextures(0, texture, 0); //adds texture id to texture array
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]); //activates texture to be used now
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
Is there anything I have done wrong? Or something I haven't done? It works perfectly fine in the emulator so I could only assume it was the power of 2 issue but like I said I tried that using a 128x128 texture on a square but it didn't show.. any help would be appreciated..
EDIT: I have also tried setting the minsdkversion is 3, loading the bitmap via an input stream bitmap = BitmapFactory.decodeStream(is), setting BitmapFactory.Options.inScaled to false, putting the images in the nodpi folder and then trying them in the raw folder.. any other ideas?
I'm actually looking for the solution to a similar problem right now. I think I might have a temporary fix for you, however.
The problem appears to be that on the emulator the orthographic view is flipped. To solve this, in my app we added an option in preferences to manually flip the view if nothing draws. Here's the snippet that handles this:
if (!flipped)
{
glOrthof(0, screenWidth, screenHeight, 0, -1, 1); //--Device
}
else
{
glOrthof(0, screenWidth, 0, -screenHeight, -1, 1); //--Emulator
}
Hope this helps! If anybody has a more general solution, I'd be happy to hear it!
I didn't look at your code but I have been on that road before. Developing in OpenGL is a real pain in the ass. If you are not obligated to use OpenGL, then use a graphics engine. Unity is a great one and it's free. Also your game would work on Android, iOS or other platforms. Study your choices carefully. Good luck..

Categories