How to get a Picture from Array of ModelInstance in Libgdx - java

i would like to know, how i could get a rendered Picture of an ModelInstance-ArrayList.
public void modelBufferIcon(int i){
for(int j = 0; j < i; j++){
frameBuffer = new FrameBuffer(Format.RGB565, Hangar.WindowWidth , Hangar.WindowHeight, false);
lights = new Lights();
lights.ambientLight.set(ambientLight);
lights.add(new PointLight().set(pointLightBack, 0f, -1f, -5f,pointLightBack_INTENSITY));
lights.add(new PointLight().set(pointLightFront, 0f, -5f, 10f, pointLightFront_INTENSITY));
perspectiveCamera.lookAt(roboterVector);
perspectiveCamera.update();
frameBuffer.begin();
Gdx.graphics.getGL20().glViewport(0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
Gdx.graphics.getGL20().glClearColor(0f, 0f, 0f, 1);
Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.graphics.getGL20().glEnable(GL20.GL_TEXTURE_2D);
modelBatch.begin(perspectiveCamera);
modelBatch.render(physique.reBuildModel(Controller.getUser().getPets().get(j)),lights);
modelBatch.end();
frameBuffer.end();
texture = frameBuffer.getColorBufferTexture();
TextureRegion textureRegion = new TextureRegion(texture);
textureRegion.flip(false, true);
image_pet = new Image(textureRegion);
imageClickHandler(image_pet, j);
window.add(image_pet).row();
window.pack();
perspectiveCamera.lookAt(cameraVector);
perspectiveCamera.update();
}
}
On the left side u see the rendered Model, on the right side the picture:
Picture
With (physique.reBuildModel(Controller.getUser().getPets().get(j)),lights) the render-method get a Modelinstance of five 3d Models (Head, Arms,... ).

Related

Accessing A Specific Cell's Tile In LibGDX

I have started to create a 2D game in LibGDX using a map(32x32 8 pixel tiles) from tiled map editor. In the method generateMushrooms, I want to access the cell(1,2) in layer 1 and set its tile to another tile in my tileset sprites.png with the id of 8. How would I achieve this? Right now I am getting a null pointer exception.
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, 256, 256);
camera.update();
tiledMap = new TmxMapLoader().load("custom.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);
generateMushrooms();
Gdx.input.setInputProcessor(this);
sb = new SpriteBatch();
texture = new Texture(Gdx.files.internal("badlogic.jpg"));
sprite = new Sprite(texture, 50, 50);
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
sb.setProjectionMatrix(camera.combined);
sb.begin();
//sprite.draw(sb);
sb.end();
}
public void generateMushrooms() {
//Get first layer
TiledMapTileLayer layer = (TiledMapTileLayer) tiledMap.getLayers().get(1);
// Get cell at row 1 column 2
TiledMapTileLayer.Cell cell = layer.getCell(1, 2);
// Get Tileset
TiledMapTileSet tileSet = tiledMap.getTileSets().getTileSet("sprites.png");
//Set tile of id 8 for the cell
cell.setTile(tileSet.getTile(8));
//Set the cell back in the layer at their x and y positions
layer.setCell(8, 16, cell);
}
Solved my problem! I have a traversing for loop go through the tiles and replace certain tiles like this (note that cur is a layer in the map).
for(int i=0; i < row; i++)
{
for(int j=0; j < column; j++)
{
cell = cur.getCell(i, j);
cur.setCell(i * 8, j * 8, cell);
cell.setTile(new StaticTiledMapTile("Some type of TextureRegion/Texture");
}
}

Trying to draw a model with Gouraud shading in jogl for desktop, but is flat

I already have a drawn model, but it has flat shading (for what I understand it should be smooth by default...)
This is the initial config:
private void SetLightningAndMaterials(){
//float[] lightPos = {1, 1, 1, 0};
float[] lightPos = {0, 0, 1, 0};
float[] lightColorDiffuse = {1, 1, 1, 1};
float[] lightColorAmbient = {0.2f, 0.2f, 0.2f, 1};
gl.glShadeModel(GL.GL_SMOOTH);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPos, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, lightColorDiffuse, 0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightColorAmbient, 0);
gl.glEnable(GL.GL_LIGHT1);
gl.glEnable(GL.GL_LIGHTING);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, ambientColour, 0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mesh.colour, 0);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL.GL_LIGHT0);
float[] noAmbient =
{ 0.1f, 0.1f, 0.1f, 1f }; // low ambient light
float[] spec =
{ 1f, 0.6f, 0f, 1f }; // low ambient light
float[] diffuse =
{ 0.5f, 0.5f, 0.5f, 1f };
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, noAmbient, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, spec, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[]{0,0,10,1}, 0);
}
And this is how I draw the model:
public void Draw(GL gl, GLU glu){
Vec3d normal;
MassPoint vertex1, vertex2, vertex3;
int faceIndex=0;
Face surfaceFace;
for (faceIndex=0; faceIndex<surfaceFaces.size();faceIndex++){
surfaceFace = surfaceFaces.get(faceIndex);
surfaceFace.recalculateNormal();
vertex1 = surfaceFace.vertex1;
vertex2 = surfaceFace.vertex2;
vertex3 = surfaceFace.vertex3;
normal = surfaceFace.normal;
gl.glBegin(gl.GL_TRIANGLES);
gl.glNormal3d(normal.x, normal.y, normal.z);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, colour, 0);
gl.glVertex3d(vertex1.position.x, vertex1.position.y, vertex1.position.z);
gl.glVertex3d(vertex2.position.x, vertex2.position.y, vertex2.position.z);
gl.glVertex3d(vertex3.position.x, vertex3.position.y, vertex3.position.z);
gl.glEnd();
}
}
I want to believe there's an easy way of solving this without having to create a shader (I don't have any idea how to set these in Java).
I'm using JOGL 1 by the way, and is probably an old version (the imports are like javax.media.opengl.*).
I managed to solve the problem. For smoothness to work, the drawing expects 3 normals (one per vertex), I was only passing 1 normal (one per face).
Here's the new code for the drawing:
public void Draw(GL gl, GLU glu) {
Vec3d[] normalsPerVertex = new Vec3d[3];
MassPoint vertex1, vertex2, vertex3;
int faceIndex=0;
Face surfaceFace;
for (faceIndex=0; faceIndex<surfaceFaces.size();faceIndex++){
surfaceFace = surfaceFaces.get(faceIndex);
vertex1=surfaceFace.vertex1;
normalsPerVertex[0] = vertex1.CalcNormal();
vertex2=surfaceFace.vertex2;
normalsPerVertex[1] = vertex2.CalcNormal();
vertex3=surfaceFace.vertex3;
normalsPerVertex[2] = vertex3.CalcNormal();
gl.glBegin(GL.GL_TRIANGLES);
gl.glNormal3d(normalsPerVertex[0].x, normalsPerVertex[0].y, normalsPerVertex[0].z);
gl.glVertex3d(vertex1.position.x, vertex1.position.y, vertex1.position.z);
gl.glNormal3d(normalsPerVertex[1].x, normalsPerVertex[1].y, normalsPerVertex[1].z);
gl.glVertex3d(vertex2.position.x, vertex2.position.y, vertex2.position.z);
gl.glNormal3d(normalsPerVertex[2].x, normalsPerVertex[2].y, normalsPerVertex[2].z);
gl.glVertex3d(vertex3.position.x, vertex3.position.y, vertex3.position.z);
gl.glEnd();
}
}
The calculated normal for each vertex is the media of all the faces connected to that vertex. Here's the code for that:
public Vec3d CalcNormal() {
Vec3d normalMedia = new Vec3d();
for (Face face : facesRelated) {
face.recalculateNormal();
normalMedia.add(face.normal);
}
normalMedia.mul(1d/facesRelated.size());
return normalMedia;
}
Hope this helps someone else.

flickering android screen once drawing using a loop libgdx

im drawing a basic grid using a nested for loop (libgdx) but when i test it on android it keeps on flickering i have tried many different ways but still cant get it to stop the flickering.. here is my code
public void create() {
rend = new ShapeRenderer();
screenH = Gdx.graphics.getHeight();
screenH = (int) (screenH*(0.32));
System.out.println(screenH);
screenW = Gdx.graphics.getWidth();
screenW = (int) (screenW*(0.322));
System.out.println(screenW);
batch = new SpriteBatch();
dots = new Rectangle();
storeV();
render method
public void render() {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
//Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
rend.begin(ShapeType.Filled);
batch.setColor(Color.WHITE);
rend.rect(100, 100, 200, 200);
for (int i=0; i<4; i++){
for (int j=0;j<4;j++){
//batch.draw(dot, posx, posy);
rend.setColor(Color.WHITE);
rend.rect(posx, posy, 16, 16);
posx+=screenW;
}
posx=0;
rend.rect(posx, posy, 16, 16);
// batch.draw(dot, posx, posy);
posy+=screenH;
}
rend.end();
batch.begin();
batch.end();
}
as you see i have tried drawing a rectangle and using a texture but both happen to flicker. the rectangle drawn outside the loop dosent flicker.
and here is my storeV()
public void storeV(){
for (int i=0; i<4; i++){
Xpoints[i]+=screenW*i;
}
for (int i=0; i<4; i++){
Ypoints[i]+=screenH*i;
}

Animating Multiple sprites in Android OpenGL ES 2.0

I've spent days searching, trying tutorials, and not actually getting results in this, so here I am.
I'm trying, simply put, to animate a collection of objects (Android Studio) on the screen, in a 2D format, with each independent movements and rotations. However, when I try this, I'm either not getting the object rendered, or its rendering skewed (as if rotated through the vertical Y-axis)
I know the importance of the order in which objects are drawn too (to give correct Z-ordering appearance) however, I'm at a bit of a loss with the matrix manipulation.
Here is what I have so far:
Main Activity - standard stuff
private GLSurfaceView mGLSurfaceView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurfaceView = new GLSurfaceView(this);
//check if device supports ES 2.0
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
if (supportsEs2) {
//Get the ES2 compatible context
mGLSurfaceView.setEGLContextClientVersion(2);
//set renderer to my renderer below
mGLSurfaceView.setRenderer(new MyGL20Renderer(this));
} else {
//no support
return;
}
//setContentView(R.layout.activity_main);
setContentView(mGLSurfaceView);
}
GL20Renderer class - Notice I'm now just manually adding 2 objects to my collection to render
public class MyGL20Renderer implements GLSurfaceView.Renderer
{
private final Context mActivityContext;
//Matrix Initializations
private final float[] mMVPMatrix = new float[16];
private final float[] mProjMatrix = new float[16];
private final float[] mVMatrix = new float[16];
private float[] mRotationMatrix = new float[16];
private final float[] mRotateMatrix = new float[16];
private final float[] mMoveMatrix = new float[16];
private final float[] mTempMatrix = new float[16];
private final float[] mModelMatrix = new float[16];
private int numObjects = 2;
private ArrayList<Sprite> spriteList = new ArrayList<Sprite>();
//Declare as volatile because we are updating it from another thread
public volatile float mAngle;
//private Triangle triangle;
//private Sprite sprite;
public MyGL20Renderer(final Context activityContext)
{
mActivityContext = activityContext;
}
public void onSurfaceCreated(GL10 unused, EGLConfig config)
{
//Set the background frame color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//Set the camera position (View Matrix) //mtx, offset, eyex,y,z, centrex,y,z, upx,y,z
Matrix.setLookAtM(mVMatrix, 0,
0, 0, -1.5f, //Eye XYZ - position eye behind the origin
0f, 0f, -5.0f, //Look XYZ - We are looking toward the distance
0f, 1.0f, 0.0f); //Up XYZ - Up vector - where head would be pointing if holding the camera
//Initialize Shapes
//triangle = new Triangle();
//sprite = new Sprite(mActivityContext);
//Sprite newSprite;
float xMax = 2.0f;
float yMax = 2.0f;
//rand = 0->1
float newX = (new Random().nextFloat() * xMax * 2) - xMax; //2.0f; //-2 -> +2
float newY = (new Random().nextFloat() * yMax * 2) - yMax; //-3 -> +3
float newZ = 0f;
//for (int i=0; i<numObjects; i++) {
//newSprite = new Sprite(mActivityContext);
//spriteList.add(new Sprite(mActivityContext, newX, newY, newZ));
//}
spriteList.add(new Sprite(mActivityContext, -0.0f, -0.0f, 0.0f));
spriteList.add(new Sprite(mActivityContext, +0.5f, -0.5f, 0.0f));
//spriteList.add(new Sprite(mActivityContext, -1.0f, +1.0f, 0.0f));
//spriteList.add(new Sprite(mActivityContext, +1.0f, +1.0f, 0.0f));
}
public void onDrawFrame(GL10 unused)
{
//init
Sprite currSprite;
//Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//timing
float jFactor = 0.1f;
long time = SystemClock.uptimeMillis() % 10000L;
float angleInDegrees = (360.0f / 1000.0f) * ((int) time) * jFactor;
/*
//number 1
//Matrix.setIdentityM(mModelMatrix, 0);
//currSprite = spriteList.get(0);
//Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
//currSprite.Draw(mModelMatrix);
//number 2
Matrix.setIdentityM(mModelMatrix, 0);
currSprite = spriteList.get(1);
Matrix.translateM(mModelMatrix, 0, 0.0f, -0.1f, 0.0f);
//Matrix.rotateM(mModelMatrix, 0, 90.0f, 1.0f, 0.0f, 0.0f);
Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
currSprite.Draw(mModelMatrix);
//Matrix.translateM(mModelMatrix, 0, 0, 0, 4.0f);
*/
//Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
//zoom out a bit?
Matrix.translateM(mMVPMatrix, 0, 0, 0, 4.0f);
//number 1
//currSprite = spriteList.get(0);
//Matrix.setIdentityM(mMVPMatrix, 0);
//Matrix.rotateM(mMVPMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
//Matrix.translateM(mMVPMatrix, 0, currSprite.coordX, 0.0f, 0.0f);
//currSprite.coordX += 0.01f;
//currSprite.Draw(mMVPMatrix);
//number 2
currSprite = spriteList.get(0);
Matrix.setIdentityM(mMVPMatrix, 0);
Matrix.translateM(mMVPMatrix, 0, 0.0f, 0.0f, 0.0f);
Matrix.rotateM(mMVPMatrix, 0, angleInDegrees, 0.0f, 0.0f, +1.0f);
//float[] mTempMatrix = new float[16];
//mTempMatrix = mModelMatrix.clone();
//Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix, 0, mRotateMatrix, 0);
//mTempMatrix = mMVPMatrix.clone();
//Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0);
//Matrix.setIdentityM(mMVPMatrix, 0);
currSprite.Draw(mMVPMatrix);
/*
//Set the camera position (View Matrix) //mtx, offset, eyex,y,z, centrex,y,z, upx,y,z
Matrix.setLookAtM(mVMatrix, 0,
0, 0, -10,
0f, 0f, 0f,
0f, 1.0f, 0.0f);
//Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
//zoom out a bit?
Matrix.translateM(mMVPMatrix, 0, 0, 0, 4.0f);
for (int i=0; i<numObjects; i++) {
//Create a rotation transformation for the triangle
//Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
Matrix.setRotateM(mRotationMatrix, 0, 0, 0, 0, -1.0f); //-1.0 = Z, for some reason need this. Grr
//Combine the rotation matrix with the projection and camera view
Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
//Draw Shape
//triangle.Draw(mMVPMatrix);
//sprite.Draw(mMVPMatrix);
currSprite = spriteList.get(i);
//Move the object to the passed initial coordinates?
//Matrix.translateM(mMVPMatrix, 0, currSprite.coordX, currSprite.coordY, currSprite.coordZ);
currSprite.Draw(mMVPMatrix);
}
*/
}
public void onSurfaceChanged(GL10 unused, int width, int height)
{
GLES20.glViewport(0, 0, width, height);
if (height == 0) {
height = 1; //incase of div 0 errors
}
float ratio = (float) width / height;
final float left = -ratio;
final float right = ratio;
final float bottom = -1.0f;
final float top = 1.0f;
final float near = 1.0f;
final float far = 10.f;
//This Projection Matrix is applied to object coordinates in the onDrawFrame() method
//Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);
}
public static int loadShader(int type, String shaderCode)
{
//Create a Vertex Shader Type Or a Fragment Shader Type (GLES20.GL_VERTEX_SHADER OR GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
//Add The Source Code and Compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
Please excuse the commented code in OnDrawFrame() where I've been experimenting, and failing.
Sprite Class
public class Sprite
{
//Reference to Activity Context
private final Context mActivityContext;
//Added for Textures
private final FloatBuffer mCubeTextureCoordinates;
private int mTextureUniformHandle;
private int mTextureCoordinateHandle;
private final int mTextureCoordinateDataSize = 2;
private int mTextureDataHandle;
private final String vertexShaderCode =
//Test
"attribute vec2 a_TexCoordinate;" +
"varying vec2 v_TexCoordinate;" +
//End Test
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition * uMVPMatrix;" +
//Test
"v_TexCoordinate = a_TexCoordinate;" +
//End Test
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
//Test
"uniform sampler2D u_Texture;" +
"varying vec2 v_TexCoordinate;" +
//End Test
"void main() {" +
//"gl_FragColor = vColor;" +
"gl_FragColor = (vColor * texture2D(u_Texture, v_TexCoordinate));" +
"}";
private final int shaderProgram;
private final FloatBuffer vertexBuffer;
private final ShortBuffer drawListBuffer;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
public float coordX;
public float coordY;
//public float coordZ;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 2;
static float spriteCoords[] = { -0.5f, 0.5f, // top left
-0.5f, -0.5f, // bottom left
0.5f, -0.5f, // bottom right
0.5f, 0.5f }; //top right
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; //Order to draw vertices
private final int vertexStride = COORDS_PER_VERTEX * 4; //Bytes per vertex
// Set color with red, green, blue and alpha (opacity) values
//float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
float color[] = { 1f, 1f, 1f, 1.0f };
public Sprite(final Context activityContext, float initX, float initY, float initZ)
{
mActivityContext = activityContext;
this.coordX = initX;
this.coordY = initY;
//this.coordZ = initZ;
//ergh - will do manually for now. Paxo n00b
//just a 2D array, no need for Z nonsense
for (int i=0; i<spriteCoords.length; i++) {
spriteCoords[i] -= (i%2==0) ? coordX : coordY; //- works better than +
}
//float newPosMatrix[] = { initX, initY, 0f };
//adjust the vector coords accordingly
//Matrix.multiplyMV(spriteCoords, 0, newPosMatrix, 0, spriteCoords, 0);
//Initialize Vertex Byte Buffer for Shape Coordinates / # of coordinate values * 4 bytes per float
ByteBuffer bb = ByteBuffer.allocateDirect(spriteCoords.length * 4);
//Use the Device's Native Byte Order
bb.order(ByteOrder.nativeOrder());
//Create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
//Add the coordinates to the FloatBuffer
vertexBuffer.put(spriteCoords);
//Set the Buffer to Read the first coordinate
vertexBuffer.position(0);
// S, T (or X, Y)
// Texture coordinate data.
// Because images have a Y axis pointing downward (values increase as you move down the image) while
// OpenGL has a Y axis pointing upward, we adjust for that here by flipping the Y axis.
// What's more is that the texture coordinates are the same for every face.
final float[] cubeTextureCoordinateData =
{
//Front face
/*0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f*/
/*-0.5f, 0.5f,
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f*/
0f, 1f,
0f, 0f,
1f, 0f,
1f, 1f
};
mCubeTextureCoordinates = ByteBuffer.allocateDirect(cubeTextureCoordinateData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeTextureCoordinates.put(cubeTextureCoordinateData).position(0);
//Initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(spriteCoords.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
//Texture Code
GLES20.glBindAttribLocation(shaderProgram, 0, "a_TexCoordinate");
GLES20.glLinkProgram(shaderProgram);
//Load the texture
mTextureDataHandle = loadTexture(mActivityContext, R.drawable.cube);
}
public void Draw(float[] mvpMatrix)
{
//Add program to OpenGL ES Environment
GLES20.glUseProgram(shaderProgram);
//Get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
//Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
//Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
//Get Handle to Fragment Shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor");
//Set the Color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//Set Texture Handles and bind Texture
mTextureUniformHandle = GLES20.glGetAttribLocation(shaderProgram, "u_Texture");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(shaderProgram, "a_TexCoordinate");
//Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
//Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
//Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
//Pass in the texture coordinate information
mCubeTextureCoordinates.position(0);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, mCubeTextureCoordinates);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
//Get Handle to Shape's Transformation Matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix");
//Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
//glTranslatef(0f, 0f, 0f);
//Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
//Disable Vertex Array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
public static int loadTexture(final Context context, final int resourceId)
{
final int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
if (textureHandle[0] != 0)
{
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false; // No pre-scaling
// Read in the resource
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);
// Bind to the texture in OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
// Recycle the bitmap, since its data has been loaded into OpenGL.
bitmap.recycle();
}
if (textureHandle[0] == 0)
{
throw new RuntimeException("Error loading texture.");
}
return textureHandle[0];
}
}
Now, I don't know if I'm going about this the right way at all, but I simply want to just animate the collection of Sprite objects in spriteList.
More specifically, have a collection of 3 objects and then respond to screen touch, and animate the objects to that location (but that will come later)
Initially, I just want to be able to correctly render these objects (with initial locations) and then rotate them on the centre point (about the Z axis).
For some reason, TranslateM is warping the texture (as if about the Y axis) and not actually moving an object along the X/Y planes
Many thanks for any help you can offer. As you can see I'm fairly new to OpenGL and have had little luck with the limited tutorials out there that support Android Studio and GLES2.0.
Kind regards,
James
I think the problem is that you have not multiplied the translation matrices into your rotation matrices. A matrix multiply is required to combine those.

LWJGL render text using slick-util

I want to render a string of text on top of my openGL application using the slick-util's tutorial: http:// lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_3_-_TrueType_Fonts_for_LWJGL
This is my init code:
private void init() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setVSyncEnabled(true);
Display.setTitle(this.windowTitle);
Display.create();
Keyboard.create();
} catch (LWJGLException e) {
Sys.alert("Error", "Initialization failed!\n\n" + e.getMessage());
System.exit(0);
}
/* OpenGL */
int width = Display.getDisplayMode().getWidth();
int height = Display.getDisplayMode().getHeight();
GL11.glViewport(0, 0, width, height); // Reset The Current Viewport
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
GL11.glLoadIdentity(); // Reset The Projection Matrix
GLU.gluPerspective(45.0f, ((float) width / (float) height), 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
GL11.glLoadIdentity(); // Reset The Modelview Matrix
GL11.glEnable(GL11.GL_TEXTURE_2D);
//GL11.glShadeModel(GL11.GL_SMOOTH); // Enables Smooth Shading
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
GL11.glClearDepth(1.0f); // Depth Buffer Setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Test To Do
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations
//GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); // Set The Blending Function For Translucency
//GL11.glEnable(GL11.GL_BLEND);
/* Set up the light */
// Ambient Light
lightAmbient.put(0, 1.0f);
lightAmbient.put(1, 1.0f);
lightAmbient.put(2, 1.0f);
lightAmbient.put(3, 1.0f);
// Diffuse Light
lightDiffuse.put(0, 1.0f);
lightDiffuse.put(1, 1.0f);
lightDiffuse.put(2, 1.0f);
lightDiffuse.put(3, 1.0f);
// Light Position
lightPosition.put(0, 25.0f);
lightPosition.put(1, 0.0f);
lightPosition.put(2, 0.0f);
lightPosition.put(3, 1.0f);
lightDir.put(0, 0.0f);
lightDir.put(1, 0.0f);
lightDir.put(2, 0.0f);
lightDir.put(3, 1.0f);
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, lightAmbient); // Setup The Ambient Light
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, lightDiffuse); // Setup The Diffuse Light
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_SPOT_DIRECTION, lightDir);
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, lightPosition); // Position The Light
GL11.glEnable(GL11.GL_LIGHT1); // Enable Light One
if (light) // Enable/Disable Lighting
GL11.glEnable(GL11.GL_LIGHTING);
else
GL11.glDisable(GL11.GL_LIGHTING);
/* Initiating loader classes */
new ColorList();
new TextureManager();
new TimersManager();
lvLoader = new LevelLoader();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TextureManager.getInstance().atlases[0].getTextureID());
/* Initiating variables */
lastFPS = getTime();
/* Setting the spawn point */
xpos = spawnPoint.x;
zpos = spawnPoint.z;
/* Loading a new level */
loadLevel("testmap");
/* Build static display lists */
buildLists();
//create the font
Font awtFont = new Font("Times New Roman", Font.BOLD, 24);
font = new TrueTypeFont(awtFont, false);
}
Render code:
private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
GL11.glLoadIdentity(); // Reset The View
GL11.glRotatef(lookupdown, 1.0f, 0, 0);
GL11.glRotatef(360.0f - yrot, 0, 1.0f, 0);
GL11.glTranslatef(-xpos, 0, -zpos);
GL11.glCallList(blocksList);
GL11.glCallList(tilesList);
GL11.glCallList(roofList);
TexCoords tc = null;
drawS();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TextureManager.getInstance().atlases[0].getTextureID());
/* RENDERING BLOCKS */
for (Block block : lvLoader.currentLevel.blocks)
{
if (block.created)
{
if (!block.isStatic)
{
if (block.texturePos != null)
{
tc = getTexCoords(block.texturePos);
}
else
{
tc = new TexCoords(new Vertex(1.0f, 0.875f, 0), new Vertex(0.75f, 0.875f, 0), new Vertex(0.75f, 1.0f, 0), new Vertex(1.0f, 1.0f, 0));
}
//GL11.glColor3b(block.color.getRedByte(), block.color.getGreenByte(), block.color.getBlueByte());
GL11.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
for (int i = 0; i < 6; i++)
{
quadNormal(i);
for (int j = 0; j < 4; j++)
{
Vertex coord = tc.coords[j];
GL11.glTexCoord2d(coord.x, coord.y);
GL11.glVertex3f(block.walls[i].vertices[j].x, block.walls[i].vertices[j].y, block.walls[i].vertices[j].z);
}
}
GL11.glEnd();
}
}
}
/* RENDERING TILES */
for (Tile tile : lvLoader.currentLevel.tiles)
{
if (tile.created)
{
if (!tile.isStatic)
{
if (tile.animation != null)
{
tile.texturePos = tile.animation.frames[tile.animation.currentFrame];
tc = getTexCoords(tile.texturePos);
}
else
{
if (tile.texturePos != null)
{
tc = getTexCoords(tile.texturePos);
}
else
{
tc = new TexCoords(new Vertex(1.0f, 0.875f, 0), new Vertex(0.75f, 0.875f, 0), new Vertex(0.75f, 1.0f, 0), new Vertex(1.0f, 1.0f, 0));
}
}
GL11.glColor3b(tile.color.getRedByte(), tile.color.getGreenByte(), tile.color.getBlueByte());
//GL11.glColor4f(0, 0, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
quadNormal(5);
for (int jj = 0; jj < 4; jj++)
{
Vertex coord = tc.coords[jj];
GL11.glTexCoord2f(coord.x, coord.y);
GL11.glVertex3f(tile.surface.vertices[jj].x, tile.surface.vertices[jj].y, tile.surface.vertices[jj].z);
}
GL11.glEnd();
}
}
}
/* RENDERING ROOF */
for (Tile rTile : lvLoader.currentLevel.roof)
{
if (rTile != null)
{
if (rTile.created)
{
if (!rTile.isStatic)
{
if (rTile.texturePos != null)
{
tc = getTexCoords(rTile.texturePos);
}
else
{
tc = new TexCoords(new Vertex(1.0f, 0.875f, 0), new Vertex(0.75f, 0.875f, 0), new Vertex(0.75f, 1.0f, 0), new Vertex(1.0f, 1.0f, 0));
}
GL11.glColor3ub(rTile.color.getRedByte(), rTile.color.getGreenByte(), rTile.color.getBlueByte());
GL11.glBegin(GL11.GL_QUADS);
quadNormal(4);
for (int k = 0; k < 4; k++)
{
Vertex coord = tc.coords[k];
GL11.glTexCoord2f(coord.x, coord.y);
GL11.glVertex3f(rTile.surface.vertices[k].x, rTile.surface.vertices[k].y, rTile.surface.vertices[k].z);
}
GL11.glEnd();
}
}
}
}
}
Additional methods:
private void drawS()
{
// disable depth testing and enable orthographic view
GL11.glDisable(GL11.GL_DEPTH_TEST);
// GL11.glDepthMask(false);
enableOrthoView();
// draw the credits
GL11.glDisable(GL11.GL_LIGHTING);
font.drawString(20.0f, 20.0f, "Test string qqqqqqqqqqqqqqqqqqqq ", Color.green);
GL11.glEnable(GL11.GL_LIGHTING);
// go back to the model view
GL11.glEnable(GL11.GL_DEPTH_TEST);
// GL11.glDepthMask(true);
disableOrthoView();
}
/**
* Enables orthographic view.
*/
public static void enableOrthoView(){ // Set Up An Ortho View
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select Projection
GL11.glPushMatrix(); // Push The Matrix
GL11.glLoadIdentity(); // Reset The Matrix
GL11.glOrtho( 0, 800 , 600 , 0, -1, 1 ); // Select Ortho Mode
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select Modelview Matrix
GL11.glPushMatrix(); // Push The Matrix
GL11.glLoadIdentity(); // Reset The Matrix
}
/**
* Disables the orthographic view.
*/
public static void disableOrthoView() {
GL11.glMatrixMode( GL11.GL_PROJECTION ); // Select Projection
GL11.glPopMatrix(); // Pop The Matrix
GL11.glMatrixMode( GL11.GL_MODELVIEW ); // Select Modelview
GL11.glPopMatrix(); // Pop The Matrix
}
The output looks like this: image 1 (It seems to be textured with my water texture)
Or like this, if I disable texturing before drawing the text: image 2
What am I doing wrong?
TrueTypeFonts are depraceted. Use UnicodeFont instead.
font = new UnicodeFont(awtFont);
font.getEffects().add(new ColorEffect(java.awt.Color.white));
font.addAsciiGlyphs();
try {
font.loadGlyphs();
} catch (SlickException ex) {
// Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
this should help

Categories

Resources