我一直在尝试在独立的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);
}
答案 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
}