问题描述
嗨,我是Android和OpenGLES开发的新手。我正在尝试使用OpenGL开发一个简单的Android游戏。我游戏的背景图像是一个平铺,我想使用纹理映射环绕将其设置为“ 0”。在我的Samsung galaxy S和平台3.0的仿真器中,它运行良好。问题出在我的Samsung 10.1 galaxy Tab上,我无法使其重复纹理。它始终使用纹理夹边缘。我找到了一个纹理教程,当我修改纹理映射并包装本教程的参数时,纹理会按预期重复,因此我知道它不是数位板中的数位板错误。问题是我的代码有什么问题,而这仅仅是平板电脑的问题?
我正在实现
GLSurfaceView.Renderer
的类中进行所有纹理设置。这有问题吗?
package com.droidev.games.bubbilliards;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.glutils;
import android.util.Log;
public class BBglrenderer implements GLSurfaceView.Renderer {
private BBGame game;
private int width;
private int height;
private float ratio_w_h;
private ShortBuffer indicesBuffer;
private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
private FloatBuffer backgroundVertexBuffer;
private FloatBuffer backgroundTextureBuffer;
private Context context;
private BBGLSurfaceView glSurfaceView;
private int ball_textures[];
private int hole_open_textures[];
private int hole_closed_textures[];
private int background_textures[];
private float length;
private boolean texture_set;
private Bitmap green_ball;
private Bitmap orange_ball;
private Bitmap purple_ball;
private Bitmap green_hole_open;
private Bitmap orange_hole_open;
private Bitmap purple_hole_open;
private Bitmap green_hole_closed;
private Bitmap orange_hole_closed;
private Bitmap purple_hole_closed;
private Bitmap background;
public BBglrenderer(Context context_,BBGLSurfaceView sv){
super();
context = context_;
glSurfaceView = sv;
game = new BBGame(sv);
texture_set = false;
}
public void onSurfaceCreated(GL10 gl,EGLConfig config){
gl.glClearColor(0.0f,0.0f,1.0f);
gl.glEnable(GL10.GL_BLEND);
gl.gldisable(GL10.GL_DEPTH_TEST);
gl.glBlendFunc(GL10.GL_ONE,GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D);
// reading images from resources
green_ball = BitmapFactory.decodeResource(context.getResources(),R.drawable.green_ball);
orange_ball = BitmapFactory.decodeResource(context.getResources(),R.drawable.orange_ball);
purple_ball = BitmapFactory.decodeResource(context.getResources(),R.drawable.purple_ball);
green_hole_open = BitmapFactory.decodeResource(context.getResources(),R.drawable.green_hole_open);
orange_hole_open = BitmapFactory.decodeResource(context.getResources(),R.drawable.orange_hole_open);
purple_hole_open = BitmapFactory.decodeResource(context.getResources(),R.drawable.purple_hole_open);
green_hole_closed = BitmapFactory.decodeResource(context.getResources(),R.drawable.green_hole_closed);
orange_hole_closed = BitmapFactory.decodeResource(context.getResources(),R.drawable.orange_hole_closed);
purple_hole_closed = BitmapFactory.decodeResource(context.getResources(),R.drawable.purple_hole_closed);
background = BitmapFactory.decodeResource(context.getResources(),R.drawable.tile);
// creating textures IDS
int num_colors = BBColor.values().length;
ball_textures = new int[num_colors];
hole_open_textures = new int[num_colors];
hole_closed_textures = new int[num_colors];
background_textures = new int[1];
gl.glGenTextures(num_colors,ball_textures,0);
// balls
initializeTexture(gl,green_ball,(int)BBColor.GREEN.ordinal());
initializeTexture(gl,orange_ball,(int)BBColor.ORANGE.ordinal());
initializeTexture(gl,purple_ball,(int)BBColor.PURPLE.ordinal());
gl.glGenTextures(num_colors,hole_open_textures,0);
// holes open
initializeTexture(gl,green_hole_open,orange_hole_open,purple_hole_open,hole_closed_textures,0);
// holes closed
initializeTexture(gl,green_hole_closed,orange_hole_closed,purple_hole_closed,(int)BBColor.PURPLE.ordinal());
gl.glGenTextures(1,background_textures,0);
initializeTexture(gl,background,0);
// initializeBuffers();
}
public void initializeTextures(GL10 gl){
int num_colors = BBColor.values().length;
gl.glGenTextures(num_colors,0);
gl.glGenTextures(num_colors,0);
gl.glGenTextures(1,0);
// balls
initializeTexture(gl,(int)BBColor.PURPLE.ordinal());
// holes open
initializeTexture(gl,(int)BBColor.PURPLE.ordinal());
// holes closed
initializeTexture(gl,(int)BBColor.PURPLE.ordinal());
initializeTexture(gl,0);
texture_set = true;
}
public void initializeTexture(GL10 gl,Bitmap bmp,int textures[],int color){
gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[color]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
glutils.texImage2D(GL10.GL_TEXTURE_2D,bmp,0);
// gl.glTexImage2D(GL10.GL_TEXTURE_2D,GL10.GL_RGBA,bmp.getWidth(),bmp.getHeight(),GL10.GL_,pixels)
}
public void initializeBuffers(int w,int h){
length = Math.min(ratio_w_h/(float)game.getWidth(),1.0f/(float)game.getHeight());
// Vertices Position //////////////////////////////////////////////////////////
float vertices[] = {0.0f,length,0.0f};
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = vertexByteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// indices ////////////////////////////////////////////////////////////////////
short[] indices = new short[] { 0,1,2,3,2 };
ByteBuffer indicesByteBuffer = ByteBuffer.allocateDirect(indices.length * 2);
indicesByteBuffer.order(ByteOrder.nativeOrder());
indicesBuffer = indicesByteBuffer.asShortBuffer();
indicesBuffer.put(indices);
indicesBuffer.position(0);
// Texture Coords /////////////////////////////////////////////////////////////
float coords[] = {0.0f,1.0f,0.0f};
ByteBuffer textureByteBuffer = ByteBuffer.allocateDirect(coords.length * 4);
textureByteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = textureByteBuffer.asFloatBuffer();
textureBuffer.put(coords);
textureBuffer.position(0);
//////////////////////////////////////////////////////////////////////
// Vertices Position //////////////////////////////////////////////////////////
float verticesBackground[] = {0.0f,game.getWidth()*length,game.getHeight()*length,0.0f};
ByteBuffer backgroundVertexByteBuffer = ByteBuffer.allocateDirect(verticesBackground.length * 4);
backgroundVertexByteBuffer.order(ByteOrder.nativeOrder());
backgroundVertexBuffer = backgroundVertexByteBuffer.asFloatBuffer();
backgroundVertexBuffer.put(verticesBackground);
backgroundVertexBuffer.position(0);
// Texture Coords /////////////////////////////////////////////////////////////
float coordsBackground[] = {0.0f,game.getHeight(),game.getWidth(),0.0f};
ByteBuffer backgroundTextureByteBuffer = ByteBuffer.allocateDirect(coordsBackground.length * 4);
backgroundTextureByteBuffer.order(ByteOrder.nativeOrder());
backgroundTextureBuffer = backgroundTextureByteBuffer.asFloatBuffer();
backgroundTextureBuffer.put(coordsBackground);
backgroundTextureBuffer.position(0);
//////////////////////////////////////////////////////////////////////
game.setResolution(w,h);
game.setRatio_W_H(ratio_w_h);
game.setSquareLength(length);
}
public void onSurfaceChanged(GL10 gl,int w,int h){
width = w;
height = h;
ratio_w_h = (float)width/(float)height;
gl.glViewport(0,w,h);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0.0f,ratio_w_h*1.0f,-1.0f,1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
initializeBuffers(w,h);
}
public void onDrawFrame(GL10 gl){
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2,GL10.GL_FLOAT,backgroundTextureBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D,background_textures[0]);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_REPEAT);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_REPEAT);
// if(!texture_set){
// initializeTextures(gl);
// initializeBuffers(width,height);
// }
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3,backgroundVertexBuffer);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_LINEAR);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_CLAMP_TO_EDGE);
// gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_CLAMP_TO_EDGE);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,4);
gl.glDrawElements(GL10.GL_TRIANGLES,6,GL10.GL_UNSIGNED_SHORT,indicesBuffer);
gl.glVertexPointer(3,vertexBuffer);
gl.glTexCoordPointer(2,textureBuffer);
for(BBHole h: game.getHoles()){
gl.glPushmatrix();
gl.glTranslatef(h.getX()*length,h.getY()*length,0.0f);
gl.glBindTexture(GL10.GL_TEXTURE_2D,(h.isopen())?hole_open_textures[h.getColor().ordinal()]:hole_closed_textures[h.getColor().ordinal()]);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,4);
gl.glDrawElements(GL10.GL_TRIANGLES,indicesBuffer);
gl.glPopMatrix();
}
for(BBBubble b: game.getBubbles()){
synchronized (b) {
gl.glPushmatrix();
gl.glTranslatef(b.getX()*length+b.getTx(),b.getY()*length+b.getTy(),0.0f);
gl.glBindTexture(GL10.GL_TEXTURE_2D,ball_textures[b.getColor().ordinal()]);
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,4);
gl.glDrawElements(GL10.GL_TRIANGLES,indicesBuffer);
gl.glPopMatrix();
b.notifyAll();
}
}
// gl.glColor4f(1.0f,1.0f);
gl.gldisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.gldisableClientState(GL10.GL_VERTEX_ARRAY);
gl.gldisable(GL10.GL_TEXTURE_2D);
// gl.glFlush();
// Log.i(\"GL_ERROR = \",Integer.toString( gl.glGetError()));
glSurfaceView.setDirty(false);
}
public BBGame getGame(){
return game;
}
}
所以我基本上有一个Activity
扩展extends4ѭ的类,上面介绍的实现GLSurfaceView.Renderer
的类以及具有游戏规则的类,等等。
提前致谢!
解决方法
我认为GL_REPEAT仅适用于POT(两种幂)纹理,并且drawable-xyz可能会放大或缩小为非POT大小。
, 好的,我找到了解决我问题的方法,但是对我来说这没有意义。在eclipse中创建的项目在res文件夹中仅包含drawable-hdpi,drawable-mdpi和drawable-ldpi文件夹,而没有诸如我之前提到的教程中那样的drawable文件夹。
因此,解决方案是创建此\“ drawable \”文件夹并将图像放在此处。然后GL_REPEAT“神奇地”为星系选项卡工作。由于该文件夹问题,我浪费了2天:(。
我很好奇它是否有意义,是否应该将所有纹理始终放在这些drawable文件夹中。