Java JOGL纹理对象未翻译

时间:2015-09-30 16:38:43

标签: java jogl texture-mapping texture2d opengl-2.0

我一直在尝试在独立的Java应用程序中使用JOGL。我已经在Android上使用OpenGLES,只是将我的代码从Android OpenGL移植到这个Java应用程序。已经有一些语法更改,但方法和构建步骤是相似和适当的。

我能够在画布上绘制浮点数的顶点数组,并将颜色数据传递给着色器。现在我正在研究纹理。这就是我的问题所在。我能够通过Java对着色器进行纹理甚至应用其他颜色,但现在我希望能够在3D空间中移动对象。

没有纹理,我可以旋转/平移对象,但是当我将纹理应用到对象(它确实应用纹理)时,我无法旋转/翻译对象。

如果有人能指出我正在俯瞰的正确方向。我搜索并查看了教程和示例,但他们似乎都在做我所拥有的基础知识。

为了澄清,我在3D空间中移动纹理对象时遇到了问题。

这是我的ExampleGL主渲染器:

    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();
}

}

这是我要绘制的对象:

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;
 }

}

这是我的TextureHelper类:

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;
}

}
下面的

是我在尝试应用纹理时使用的顶点着色器:

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;
}
下面的

是我在尝试应用纹理时使用的片段着色器:

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);                                         
}

1 个答案:

答案 0 :(得分:1)

今天早上醒来,直接进入主演的节目。然后我意识到我可能需要在翻译之前将ModelView矩阵设置为绘图。它工作了!

这是我缺少的方法,需要在加载identitiy矩阵之前添加。它必须设置为另一个矩阵。

gl.glMatrixMode(GL2.GL_MODELVIEW);

老实说,不明白为什么它不起作用,但是,当没有纹理时,它起作用。

这是我在主渲染器中对绘图方法的简单更改:

@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 

}