I have been attempting to use JOGL in a standalone Java app. I have done work with OpenGLES on Android and just ported my code from Android OpenGL to this Java app. There have been some syntax changes but the methods and build steps are similar and in place.
I am able to draw vertex arrays of floats on the canvas and pass color data to shaders. Now I am working on the texturing. This is where my problem is. I am able to texture and even apply additional colors to the shaders via Java but now I want to be able to move the object in 3D space.
Without texturing, I am able to rotate/translate object but when I apply the texturing to the object (which does apply the texture), I can not rotate/translate the object.
If anyone can point my in the right direction of what I am overlooking. I have searched and looked at tutorials and examples but they all seem to be doing the basics of what I have.
To clarify, I am having issues moving textured object in 3D space.
this is my ExampleGL main renderer:
private GLU glu;
float xLoc = 0;
@Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
// call your draw code here
gl.glTranslatef(0, 0, xLoc);
gl.glRotatef(rotateX, 1, 0, 0);
gl.glRotatef(rotateY, 0, 1, 0);
gl.glRotatef(rotateZ, 0, 0, 1);
square.draw(gl);
// end calls for drawing
}
@Override
public void dispose(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
}
GLSquareEx square;
int mProgramShader;
@Override
public void init(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
glu = new GLU();
OpenGLInit(gl);
square = new GLSquareEx(gl, true);//boolean true = textured; false = not textured
if(square.textured()){
mProgramShader = ShaderHelper.loadAndCompileShader(gl, "texturevertexshader.txt", "texturefragmentshader.txt",
new String[]{
"vertColor",
"a_texCoord"
});
} else {
mProgramShader = ShaderHelper.loadAndCompileShader(gl, "vertexshader.txt", "fragmentshader.txt",
new String[]{
"vertColor"
});
}
square.setShaderProgram(mProgramShader);
}
@Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
int arg4) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if ( key == KeyEvent.VK_LEFT ){
rotateY -= 15;
} else if ( key == KeyEvent.VK_RIGHT ){
rotateY += 15;
} else if ( key == KeyEvent.VK_DOWN){
xLoc -= 1.0f;
rotateX += 15;
} else if ( key == KeyEvent.VK_UP ){
xLoc += 1.0f;
rotateX -= 15;
} else if ( key == KeyEvent.VK_PAGE_UP ){
rotateZ += 15;
} else if ( key == KeyEvent.VK_PAGE_DOWN ){
rotateZ -= 15;
} else if ( key == KeyEvent.VK_HOME ){
rotateX = rotateY = rotateZ = 0;
}
System.out.println(KeyEvent.getKeyText(key));
//repaint();
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
private void OpenGLInit(GL2 gl) {
// TODO Auto-generated method stub
gl.glClearColor(0.392f, 0.584f, 0.929f, 1.0f);
gl.glClearDepth(1.0f); // set clear depth value to farthest
gl.glEnable(GL2.GL_DEPTH_TEST); // enables depth testing
gl.glDepthFunc(GL2.GL_LEQUAL); // the type of depth test to do
gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST); // best perspective correction
gl.glShadeModel(GL2.GL_SMOOTH); // blends colors nicely, and smoothes out lighting
SetCameraView(gl, 30);
}
private void SetCameraView(GL2 gl, float distance) {
// TODO Auto-generated method stub
// Change to projection matrix.
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
// Perspective.
float widthHeightRatio = (float) getWidth() / (float) getHeight();
glu.gluPerspective(45.0f, widthHeightRatio, 0.1f, 100f);
glu.gluLookAt(0, 0, distance, 0, 0, 0, 0, 1, 0);
// Change back to model view matrix.
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
}
}
this is my Object I want to draw:
public class GLSquareEx {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private FloatBuffer colorBuffer; // Buffer for color-array (NEW)
private FloatBuffer texBuffer;
private boolean isTextured;
private Texture tex = null;
int mProgram;
private int mSamplerLoc;
private int mTexCoordLoc;
private int colLoc;
private float[] vertices = {
-1.0f, -1.0f, 0.0f, // 0. left-bottom
1.0f, -1.0f, 0.0f, // 1. right-bottom
-1.0f, 1.0f, 0.0f, // 2. left-top
1.0f, 1.0f, 0.0f // 3. right-top
};
private float[] texmap = {
0f, 0f,
1f, 0f,
1f, 1f,
0f, 1f
};
// Constructor - Setup the vertex buffer
public GLSquareEx(GL2 gl, boolean isTex) {
CreateVertexBuffer();
isTextured = isTex;
if(isTex){
CreateTextureBuffer();
InitializeTexture(gl);
}
}
// Render the shape
public void draw(GL2 gl) {
gl.glPushMatrix();
/*
* start drawing
*/
// Enable vertex-array and define its buffer
gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
gl.glUseProgram(mProgram);
colLoc = gl.glGetUniformLocation(mProgram, "vertColor");
gl.glUniform3f(colLoc, 0.8f, 0.0f, 0.0f);
if(isTextured){
gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
//gl.glTexCoordPointer(2, GL2.GL_FLOAT, 0, texBuffer);
//gl.glActiveTexture(GL2.GL_TEXTURE0);
tex.enable(gl);
tex.bind(gl);
mTexCoordLoc = gl.glGetAttribLocation(mProgram, "a_texCoord" );
mSamplerLoc = gl.glGetUniformLocation(mProgram, "s_texture" );
gl.glEnableVertexAttribArray ( mTexCoordLoc );
gl.glUniform1i( mSamplerLoc, 0);
gl.glVertexAttribPointer ( mTexCoordLoc, 2, GL2.GL_FLOAT, false, 0, texBuffer);
}
gl.glVertexPointer(3, GL2.GL_FLOAT, 0, getVertexBuffer());
gl.glDrawArrays(GL2.GL_TRIANGLE_STRIP, 0, getVertices().length/3);
gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
if(isTextured){
tex.disable(gl);
gl.glDisableVertexAttribArray(mTexCoordLoc);
gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY) ;
}
/*
* end drawing
*/
gl.glPopMatrix();
}
public void setShaderProgram(int prog){
mProgram = prog;
}
public boolean textured(){
return isTextured;
}
private void InitializeTexture(GL2 gl) {
// TODO Auto-generated method stub
String dir = System.getProperty("user.dir")+"\\lib\\";
try {
tex = TextureHelper.loadTexture(gl, gl.getGLProfile(), dir + "cia.jpg", TextureIO.JPG);
tex.setTexParameteri(gl, GL2.GL_TEXTURE_MIN_FILTER,
GL2.GL_LINEAR);
tex.setTexParameteri(gl, GL2.GL_TEXTURE_MAG_FILTER,
GL2.GL_LINEAR);
tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_S,
GL2.GL_CLAMP_TO_EDGE);//GL_REPEAT
tex.setTexParameteri(gl, GL2.GL_TEXTURE_WRAP_T,
GL2.GL_CLAMP_TO_EDGE);//GL_REPEAT
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void CreateTextureBuffer() {
// TODO Auto-generated method stub
texBuffer = Buffers.newDirectFloatBuffer(texmap);
texBuffer.put(texmap);
texBuffer.rewind();
}
private void CreateVertexBuffer() {
// TODO Auto-generated method stub
vertexBuffer = Buffers.newDirectFloatBuffer(vertices);
vertexBuffer.put(vertices);
vertexBuffer.rewind();
}
public float[] getVertices(){
return vertices;
}
public FloatBuffer getVertexBuffer() {
// TODO Auto-generated method stub
return vertexBuffer;
}
}
this is my TextureHelper class:
public class TextureHelper
{
public static Texture loadTexture(GL2 gl, GLProfile glProfile, String filepath, String extension)
{
try {
gl.glMatrixMode(GL2.GL_TEXTURE);
gl.glLoadIdentity();
InputStream stream = new FileInputStream(filepath);
TextureData data = TextureIO.newTextureData(glProfile, stream, false, extension);
Texture tex = TextureIO.newTexture(data);
return tex;
}
catch (IOException exc) {
exc.printStackTrace();
System.exit(1);
}
return null;
}
}
below is my vertex shader I am using when I am attempting to apply texture:
uniform vec3 vertColor;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
varying vec3 col;
void main() {
gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex;
col=vertColor;
v_texCoord = a_texCoord;
}
below is my fragment shader I am using when I am attempting to apply texture:
precision mediump float;
uniform sampler2D s_texture;
varying vec2 v_texCoord;
varying vec3 col;
void main()
{
// Pass through the color
gl_FragColor = vec4( col, 1.0 ) * texture2D(s_texture, v_texCoord);
}
Just woke up this morning and went right into the program starring at it. Then I realized I may need to set the ModelView matrix to the drawing before translation. IT WORKED!
This is the method I was missing and needed to add before loading the identitiy matrix. It must have been set to another matrix.
gl.glMatrixMode(GL2.GL_MODELVIEW);
Honestly don't understand why it works not but, when not textured, it worked.
Here It the simple change to the drawing method in my main renderer:
@Override
public void display(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
// call your draw code here
gl.glTranslatef(0, 0, xLoc);
gl.glRotatef(rotateX, 1, 0, 0);
gl.glRotatef(rotateY, 0, 1, 0);
gl.glRotatef(rotateZ, 0, 0, 1);
square.draw(gl);
// end calls for drawing
}