Текстурированный объект Java JOGL не переводится
Я пытался использовать JOGL в отдельном приложении Java. Я сделал работу с OpenGLES на Android и просто перенес свой код из Android OpenGL в это приложение Java. Произошли некоторые изменения в синтаксисе, но методы и этапы сборки похожи и на месте.
Я могу рисовать массивы с плавающей точкой на холсте и передавать данные о цвете в шейдеры. Сейчас я работаю над текстурированием. Вот где моя проблема. Я могу текстурировать и даже применять дополнительные цвета к шейдерам через Java, но теперь я хочу иметь возможность перемещать объект в трехмерном пространстве.
Без текстурирования я могу вращать / переводить объект, но когда я применяю текстурирование к объекту (который применяет текстуру), я не могу вращать / переводить объект.
Если кто-то может указать мне в правильном направлении того, что я пропускаю. Я искал и смотрел учебники и примеры, но все они, кажется, делают основы того, что у меня есть.
Чтобы уточнить, у меня есть проблемы с перемещением текстурированного объекта в трехмерном пространстве.
это мой главный рендерер 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 ответ
Просто проснулся этим утром и вошел прямо в программу, в главной роли. Затем я понял, что может потребоваться установить матрицу 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
}