Java JOGL 纹理对象未平移

Java JOGL textured object not translating

我一直在尝试在独立的 Java 应用程序中使用 JOGL。我已经在 Android 上完成了 OpenGLES 的工作,并且刚刚将我的代码从 Android OpenGL 移植到这个 Java 应用程序。有一些语法更改,但方法和构建步骤相似且到位。

我能够在 canvas 上绘制浮点数组并将颜色数据传递给着色器。现在我正在处理纹理。这就是我的问题所在。我可以通过 Java 对着色器进行纹理化甚至应用其他颜色,但现在我希望能够在 3D 中移动对象 space.

没有纹理,我可以 rotate/translate 对象,但是当我将纹理应用到对象(确实应用了纹理)时,我不能 rotate/translate 对象。

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

澄清一下,我在 3D 中移动带纹理的对象时遇到问题 space。

这是我的 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 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;
}

}

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

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

今天早上刚起床,就进入了主演的节目。然后我意识到我可能需要在翻译之前将 ModelView 矩阵设置为绘图。成功了!

这是我缺少的方法,需要在加载单位矩阵之前添加。一定是设置了别的矩阵。

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 

}