I'm having pretty common problem by trying to texture simple Triangle with image. Here is the code:
Setup openGL:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70,(float)width/(float)height, 0.3f, view);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
Mesh Class:
public class Mesh {
protected int TextureID=0;
protected int VertID=-1,TrisID=-1,TexID=-1;
protected Vector3 position,rotation,scale;
protected ArrayList<Vector3> verts;
protected ArrayList<Vector3> tris;
protected ArrayList<Vector3> uvs;
public Mesh(Vector3 position,Vector3 rotation,Vector3 scale){
verts= new ArrayList<Vector3>();
tris= new ArrayList<Vector3>();
uvs= new ArrayList<Vector3>();
this.position = position;
this.rotation=rotation;
this.scale=scale;
}
public void draw(){
glPushMatrix();{
// Translate Submatrix
glScalef(scale.X, scale.Y, scale.Z);
glRotatef(rotation.X,1,0,0);
glRotatef(rotation.Y,0,1,0);
glRotatef(rotation.Z,0,0,1);
glTranslatef(position.X, position.Y, position.Z);
//bind and pointer buffers and textures
TextureLoader.textureList.get(TextureID).bind();
glBindTexture(GL_TEXTURE_2D,TextureID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, TexID);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VertID);
glVertexPointer(3, GL_FLOAT, 0, 0);
int mode = GL_TRIANGLES;
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, TrisID);
//draw
glDrawElements(mode,tris.size()*3, GL_UNSIGNED_INT, 0);
}glPopMatrix();
}
public Mesh generate(){
updateVertBuffer();
updateTrisBuffer();
updateUvBuffer();
return this;
}
public void updateVertBuffer(){
if(VertID==-1)VertID= GL15.glGenBuffers();
FloatBuffer buffer = BufferUtils.createFloatBuffer(verts.size()*3);
for(int i=0;i<verts.size();i++){
buffer.put(verts.get(i).X);
buffer.put(verts.get(i).Y);
buffer.put(verts.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,VertID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
public void updateTrisBuffer(){
if(TrisID==-1)TrisID = GL15.glGenBuffers();
IntBuffer buffer = BufferUtils.createIntBuffer(tris.size()*3);
for(int i=0;i<tris.size();i++){
buffer.put((int)tris.get(i).X);
buffer.put((int)tris.get(i).Y);
buffer.put((int)tris.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, TrisID);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer,GL15.GL_STATIC_DRAW);
}
public void updateUvBuffer(){
if(TexID==-1)TexID= GL15.glGenBuffers();
FloatBuffer buffer = BufferUtils.createFloatBuffer(uvs.size()*2);
for(int i=0;i<uvs.size();i++){
buffer.put(uvs.get(i).Y);
buffer.put(uvs.get(i).Z);
}
buffer.flip();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, TexID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
Drawing Meshes:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(rot.X,1,0,0);
glRotatef(rot.Y,0,1,0);
glRotatef(rot.Z,0,0,1);
glTranslatef(pos.X,pos.Y,pos.Z);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
for(Mesh a : MHandler)a.draw(); // Simply drawing all meshes
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
Display.update();
Sample Mesh that works, but without textures on it:
Mesh m = new Mesh(new Vector3(0,0,0),new Vector3(0,0,0),new Vector3(10,10,10));
m.addVert(new Vector3(0,0,0),new Vector3(0,0,0));
m.addVert(new Vector3(0,1,0),new Vector3(0,1,0));
m.addVert(new Vector3(0,1,1),new Vector3(0,1,1));
m.addTriangle(new Vector3(0,1,2));
MHandler.add(m);
I know there's a bit too much code, but I don't really know where is excactly the problem. Since I'm new with openGL, any critics about the code would be helpful.
I load Textures using Slick if thats helpful.
Related
Hello I am trying to render texture on two triangles. glGetError() does not return any error. I can render colored rectangle, but texture does not work. Shaders are compiled without errors. Why this code does not work? (Image)
class MainRenderer implements GLSurfaceView.Renderer {
int vertexBuffer;
int indexBuffer;
int shaderProgram;
int texture;
#Override
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(1, 0, 0, 1);
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
texture = textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, BitmapFactory.decodeResource(MainActivity.MainActivityHandle.getResources(), R.drawable.pes), 0);
float vertices[] = {
1, 1,
1, 0,
0, 0,
0, 1
};
int indices[] = {
0, 1, 3,
1, 2, 3
};
String vertexShaderCode = "attribute vec2 position; vec2 texturePosition; void main(){texturePosition = position;gl_Position = vec4(position,0.0, 1.0);}";
String fragmentShaderCode = "precision mediump float;uniform sampler2D texture; vec2 texturePosition; void main(){gl_FragColor = texture2D(texture, texturePosition);}";
int vertexBuffers[] = new int[1];
GLES20.glGenBuffers(1, vertexBuffers, 0);
vertexBuffer = vertexBuffers[0];
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 4 * 2 * 4, FloatBuffer.wrap(vertices), GLES20.GL_STATIC_DRAW);
int indexBuffers[] = new int[1];
GLES20.glGenBuffers(1, indexBuffers, 0);
indexBuffer = indexBuffers[0];
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 2 * 3 * 4, IntBuffer.wrap(indices), GLES20.GL_STATIC_DRAW);
int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader, vertexShaderCode);
GLES20.glCompileShader(vertexShader);
int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
GLES20.glCompileShader(fragmentShader);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
}
#Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
#Override
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(shaderProgram);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBuffer);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
int positionAttributeHandle = GLES20.glGetAttribLocation(shaderProgram, "position");
GLES20.glEnableVertexAttribArray(positionAttributeHandle);
GLES20.glVertexAttribPointer(positionAttributeHandle, 2, GLES20.GL_FLOAT, false, 2*4, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
GLES20.glDisableVertexAttribArray(positionAttributeHandle);
}
}
I can at least see that you are using (in vertex and fragment shaders) just 'vec2 texturePosition', while you should use a 'varying' for output from vertex shader to the fragment shader. Try adding 'varying' before 'vec2 ...' in shaders.
I've looked over the following program over and over and cannot find why nothing renders to the screen when I run it:
Game.java:
public class Game {
private int fbid, fbid2;
public void start(){
DisplayManager.init();
glViewport(0, 0, DisplayManager.SCR_WIDTH, DisplayManager.SCR_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 0, DisplayManager.SCR_WIDTH, DisplayManager.SCR_HEIGHT, 1, -1);
glMatrixMode(GL_MODELVIEW);
FloatBuffer fb = BufferUtils.createFloatBuffer(6);
fb.put(100).put(100).put(100).put(200).put(200).put(200);
fb.flip();
fbid = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, fbid);
glBufferData(GL_ARRAY_BUFFER, fb, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
FloatBuffer fb2 = BufferUtils.createFloatBuffer(9);
fb2.put(1).put(1).put(1).put(1).put(1).put(1).put(1).put(1).put(1);
fb2.flip();
fbid2 = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, fbid2);
glBufferData(GL_ARRAY_BUFFER, fb2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while(!DisplayManager.shouldClose()){
render();
}
DisplayManager.destroy();
}
public void render(){
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
glColor3f(1, 1, 1);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, fbid);
glVertexPointer(2, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, fbid2);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
DisplayManager.update();
}
}
DisplayManager.java:
public class DisplayManager {
public static final int SCR_WIDTH = 640;
public static final int SCR_HEIGHT = 480;
public static final int FPS = 30;
public static void init(){
try {
Display.setDisplayMode(new DisplayMode(SCR_WIDTH, SCR_HEIGHT));
Display.setTitle("StepBattler");
Display.setResizable(false);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
}
public static void update(){
Display.update();
Display.sync(FPS);
}
public static void destroy(){
Display.destroy();
System.exit(0);
}
public static boolean shouldClose(){
return Display.isCloseRequested();
}
public static boolean shouldResize(){
return Display.wasResized();
}
}
When I run the screen, I just get a window filled with black, and I cannot understand why a white triangle won't render to the window. I've messed around with glClearColor(), and changing its values does succeed in changing the window background color, but I can't make a white triangle appear in the window. Also, I tried using glBegin()...glEnd() to render in immediate mode, with none of the code having to do with buffers in there, and it still didn't render anything. I'm really confused about this, what am I missing?
The arguments in you glOrtho() call look to be in the wrong order:
glOrtho(0, 0, DisplayManager.SCR_WIDTH, DisplayManager.SCR_HEIGHT, 1, -1);
The signature of glOrtho(), based on the man page, is:
void glOrtho(GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble nearVal, GLdouble farVal);
Since you're passing 0 for both left and right, the result would be an invalid projection matrix.
The correct call for your case is:
glOrtho(0, DisplayManager.SCR_WIDTH, 0, DisplayManager.SCR_HEIGHT, 1, -1);
I am trying to draw my font texture atlas to the screen using LWJGL, but OpenGL instead draws a solid white square.
A working example using my drawing code:
import java.awt.image.*;
import java.io.*;
import java.nio.*;
import javax.imageio.*;
import org.lwjgl.*;
import org.lwjgl.opengl.*;
public class OpenGLImageTest
{
private static int textureID;
public static void main(String[] args) throws Exception
{
Display.setTitle("OpenGL Image Test");
Display.setDisplayMode(new DisplayMode(640, 480));
Display.create();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 0, 480, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
textureID = bindTextureFile("textures/font.png");
while(!Display.isCloseRequested())
{
Display.sync(60);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(0, 0, 0, 1);
GL11.glColor4f(1, 0, 0, 1);
drawFontAtlas(0, 0);
Display.update();
}
Display.destroy();
}
private static void drawFontAtlas(int x, int y)
{
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 0);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(0, 0);
GL11.glVertex2i(0, 256);
GL11.glVertex2i(256, 256);
GL11.glVertex2i(256, 0);
GL11.glEnd();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
}
private static int bindTextureFile(String file)
{
try
{
BufferedImage image = ImageIO.read(new FileInputStream(file));
int[] pixels = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());
ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);
for(int y = 0; y < image.getWidth(); y++)
{
for(int x = 0; x < image.getHeight(); x++)
{
int pixel = pixels[y * image.getWidth() + x];
buffer.put((byte)((pixel >> 16) & 0xFF));
buffer.put((byte)((pixel >> 8) & 0xFF));
buffer.put((byte)(pixel & 0xFF));
buffer.put((byte)((pixel >> 24) & 0xFF));
}
}
buffer.flip();
int textureID = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
return textureID;
}
catch(Exception e)
{
e.printStackTrace();
}
return -1;
}
}
Can anyone tell me what I am doing wrong and how to fix it?
Edit: font.png is white on transparent white. It's the default Minecraft font for testing purposes.
Your problem can be fixed by adding texture coordinates:
{
GL11.glTexCoord2f(0, 1); // added texture coordinate
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(0, 0); // added texture coordinate
GL11.glVertex2i(0, 256);
GL11.glTexCoord2f(1, 0); // added texture coordinate
GL11.glVertex2i(256, 256);
GL11.glTexCoord2f(1, 1); // added texture coordinate
GL11.glVertex2i(256, 0);
}
I actually used slick-util.jar to load your texture, but it will work with your code just the same... you can find a working example of my code bellow... slick-util.jar can be found here
In order to get actual transparency, you also need to change this line in your code: GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB8, image.getWidth(), image.getHeight(), 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer); and what needs to be changed is GL11.GL_RGB8 into GL11.GL_RGBA
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
public class OpenGLImageTest {
private static Texture tex; //private static int textureID;
public static void main(String[] args) throws Exception {
Display.setTitle("OpenGL Image Test");
Display.setDisplayMode(new DisplayMode(640, 480));
Display.create();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 0, 480, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
tex = loadTexture("textures/font.png"); //textureID = bindTextureFile("textures/font.png");
while (!Display.isCloseRequested()) {
Display.sync(60);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(0, 0, 0, 1);
GL11.glColor4f(1, 1, 1, 1);
drawFontAtlas(0, 0);
Display.update();
}
Display.destroy();
}
private static void drawFontAtlas(int x, int y) {
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 0);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
tex.bind(); //GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glBegin(GL11.GL_QUADS);
{
GL11.glTexCoord2f(0, 1); // added texture coordinate
GL11.glVertex2i(0, 0);
GL11.glTexCoord2f(0, 0); // added texture coordinate
GL11.glVertex2i(0, 256);
GL11.glTexCoord2f(1, 0); // added texture coordinate
GL11.glVertex2i(256, 256);
GL11.glTexCoord2f(1, 1); // added texture coordinate
GL11.glVertex2i(256, 0);
}
GL11.glEnd();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
}
public static Texture loadTexture(String texturePath) {
try {
return TextureLoader.getTexture("png", new FileInputStream(new File(texturePath)));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
I have a class file called MarkerCustom. MarkerCustom has a constructor that takes three variables of different types.
public MarkerCustom(int myInt, String, myString, BitmapData myBitmap) {
From my main Main activity i want to load a GLSurface view that will take an ArrayList of every instance of MarkerCustom that i will want to load into the GLSurface along with the data that will be passed into each instance of MarkerCustom's constructor.
Lets call the Array List myMarkers;
i need myMarkers to look like this:
myMarkers[0] = [1, "hello", bitMapData1]
myMarkers[1] = [66, "johnHandy", bitmapData2]
i am fairly new to java and its casting ect confuses me a bit having come from AS3
EDIT
So following AKhill's answer below i have edited my GLSurfaceView to accept an ArrayList as shown below. But the MarkerCustom Class needs to be created from each listed in that ArrayList in the constructor in a manner that its is accessible in the onSurfaceCreate and the onDrawFrame method of the GLSurfaceView
Please see those methods and the for loops/comments in this class below:
public class GLLayer extends GLSurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback, Renderer {
private Context context;
ArrayList <MarkerCustom> locationTags;
private PhoneOrientation phoneOri;
public GLLayer(Context context, int orientation, ArrayList<MarkerCustom> custMarkers) {
super(context);
locationTags = custMarkers;
this.context = context;
phoneOri=new PhoneOrientation(context); // sensor manager and interpreter
for(int i =0; i<locationTags.size(); i++){
//Need to create a an instance of each MarkerCustom
// something like MarkerCustom locationTags[i]; = new MarkerCustom (its params);
}
this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
this.setRenderer(this);
phoneOri.start(context, orientation);
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
GLU.gluLookAt(gl,0, 0, 0, 0, 0, 0, 0, 0, 0);
float floatMat[]=phoneOri.getMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadMatrixf(floatMat, 0);
for(int i=0;i<loacationTags.size();i++){
gl.glPushMatrix();
//locationTags[i].draw(gl);
gl.glLoadMatrixf(floatMat,0);
}
gl.glPushMatrix();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) {
height = 1;
}
float ratio = (float) width / height;
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 35.0f, (float)width / (float)height, 5.0f, 200.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 1.0f, 5.0f, 0, 0, 0, 0, 1.0f, 0);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
for(int i=0;i<locationTags.size();i++){
//call each MarkerCustom's loadGLTexture Method
//locationTags[i].loadGLTexture(gl, this.context);
}
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_SMOOTH);
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
}
And Just for reference here is my MarkerCustom class
public class MarkerCustom {
public float xPos;
public float yPos;
public float zPos;
public float yaw;
public float pitch;
public Bitmap tagImage;
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
0.0f, -10.0f, -10.0f, // V1 - bottom left
0.0f, -10.0f, 10.0f, // V2 - top left
0.0f, 10.0f, -10.0f, // V3 - bottom right
0.0f, 10.0f, 10.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
public MarkerCustom(float x, float y, float z, float yawAngle, float pitchAngle, Bitmap bitmap) {
xPos = x;
yPos = y;
zPos = z;
yaw = yawAngle;
pitch = pitchAngle;
tagImage = bitmap;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/** The texture pointer */
private int[] textures = new int[1];
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
// Enable blending using premultiplied alpha.
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// 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, tagImage, 0);
// Clean up
tagImage.recycle();
}
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
Try this.
List<MarkerCustom> myList=new ArrayList<MarkerCustom>();
MarkerCustom entry1=new MarkerCustom(myInt, myString, myBitmap);
MarkerCustom entry2=new MarkerCustom(myInt, myString, myBitmap);
myList.add(entry1);
myList.add(entry2);
Shorthand:
List<MarkerCustom> markerList = Arrays.asList(
new MarkerCustom(1, "hello", bitMapData1),
new MarkerCustom(66, "johnHandy", bitMapData2))
};
In this case I think it's easier to create a class Marker (for instance) that has three attributes.
For example:
class Marker {
int var1;
String var2;
BitmapData var3; }
This way, you are able to store an ArrayList of Markers (ArrayList), and you can access all the information you need.
I'm just starting to learn Open GL and I've hit a road block. For some reason rotating objects even with pushed and popped matrices seems to transform the lighting. Does anyone know what I'm doing wrong?
Here's my code:
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class DisplayExample {
int cube;
private FloatBuffer pos;
private int cube2;
public void start() {
int width=800;
int height=600;
try {
Display.setDisplayMode(new DisplayMode(width, height));
Display.setTitle("Abarrow");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
//setup colors
FloatBuffer red= BufferUtils.createFloatBuffer(4).put(new float[] { 1, 0, 0, 1});
FloatBuffer green = BufferUtils.createFloatBuffer(4).put(new float[] { 0, 1, 0, 1});
FloatBuffer blue= BufferUtils.createFloatBuffer(4).put(new float[] { 0, 0, 1, 1});
FloatBuffer yellow= BufferUtils.createFloatBuffer(4).put(new float[] { 1, 1, 0, 1});
red.flip();
green.flip();
blue.flip();
yellow.flip();
//setup positions
pos = BufferUtils.createFloatBuffer(4).put(new float[] { 5.0f, 5.0f, 10.0f, 0.0f});
pos.flip();
//projection
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glFrustum(-4, 4, -3, 3, 5, 60);
//model view
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(0, 0, -10);
//light source
GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, pos);
//lighting
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_LIGHT0);
//other
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_NORMALIZE);
cube=GL11.glGenLists(1);
GL11.glNewList(cube, GL11.GL_COMPILE);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_AMBIENT_AND_DIFFUSE, green);
createCube();
GL11.glEndList();
cube2=GL11.glGenLists(1);
GL11.glNewList(cube2, GL11.GL_COMPILE);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_AMBIENT_AND_DIFFUSE, red);
createCube();
GL11.glEndList();
loop();
}
private void createCube() {
GL11.glBegin(GL11.GL_QUADS);
//front
GL11.glVertex3f(-1,-1,-1);
GL11.glVertex3f(-1,1,-1);
GL11.glVertex3f(1,1,-1);
GL11.glVertex3f(1,-1,-1);
//back
GL11.glVertex3f(-1,-1,1);
GL11.glVertex3f(-1,1,1);
GL11.glVertex3f(1,1,1);
GL11.glVertex3f(1,-1,1);
//left
GL11.glVertex3f(-1,-1,-1);
GL11.glVertex3f(-1,1,-1);
GL11.glVertex3f(-1,1,1);
GL11.glVertex3f(-1,-1,1);
//right
GL11.glVertex3f(1,-1,-1);
GL11.glVertex3f(1,1,-1);
GL11.glVertex3f(1,1,1);
GL11.glVertex3f(1,-1,1);
GL11.glEnd();
}
private void loop() {
float spot=0;
while (!Display.isCloseRequested()) {
spot+=1;
// Clear the screen and depth buffer
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
//reset model view
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glTranslatef(0, 0, -10);
GL11.glLight(GL11.GL_LIGHT0, GL11.GL_POSITION, pos);
//cube
GL11.glPushMatrix();
GL11.glTranslatef(-2, 0, 0);
GL11.glRotatef(spot, 0, 1, 0);
//render cube
GL11.glCallList(cube);
//undo transform
GL11.glPopMatrix();
//cube2
GL11.glPushMatrix();
GL11.glTranslatef(2, 0, 0);
GL11.glRotatef(-spot, 0, 1, 0);
//render cube
GL11.glCallList(cube2);
//undo transform
GL11.glPopMatrix();
//render the graphics
Display.update();
//cap at 60 fps
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] argv) {
DisplayExample displayExample = new DisplayExample();
displayExample.start();
}
}
Try adding some polygon normals via glNormal3f().
I think you're seeing the default normal of (0, 0, 1).