开发者

Android OpenGL Textures look terrible on Sprint Samsung Galaxy s2 Epic Touch 4g

Let me preface by admitting I am an open gl novice - its nothing short of a miracle I've made it this far with the game I've been developing.

Textures look fine on the HTC Evo 3d, Droid Bionic, and the thunderbolt. I just bought the Sprint Samsung Galaxy s2 and textures look terrible - my theory is the larger screen and resulting lower dpi effects the texture mag filtering (my other theory is I don't know what I'm doing).

Screenshot #1 Galaxy S2 vs. HTC Evo 3d

Screenshot #2 Galaxy S2 vs. HTC Evo 3d

I have tried enabling / disabling dithering, using 16 bit, 24 bit and 32 bit textures, passing options to the android BitmapFactory decode method to prevent scaling, disabled everyone of my opengl settings in the snippets below , set different combinations of custom eglconfig values with setEGLConfigChooser, I'm just taking shots in the dark now.

So my question is: which opengl function could be responsible for producing the color banding (?) / poor looking textures seen in those screenshots?

Also worthy of note:

  • There are no open gl errors (i log every open gl call)
  • When I add more light sources app performance degrades considerably (whereas the htc evo 3d, bionic and thunderbolt work perfectly fine with more than one light source).
  • OpenGL ES 1.1 (no GLES20 yes in my app)
  • I use the min 3d framework
  • Screen & Resolution:
  • HTC Evo 3d: 4.3" screen 540x960 resolution
  • Samasung Sprint Galaxy s2: 4.52" screen 800x480 resolution
getWindowManager().getDefaultDisplay().getPixelFormat();
// HTC Evo 3d: 1 (PixelFormat.RGBA_8888)
// Sprint Samsung Galaxy s2: 5 (???)

I have googled furiously for the last three days to see if anyone else is having similar issues and have found nothing. Thank you for your time.

//##################        
//# setup (one time calls)
//##################

_gl.glEnable(GL11.GL_DITHER);
_gl.glEnable(GL10.GL_DEPTH_TEST);
_gl.glClearDepthf(1.0f);
_gl.glDepthFunc(GL10.GL_LESS);
_gl.glDepthRangef(0, 1f);
_gl.glDepthMask(true);
_gl.glShadeModel(GL10.GL_SMOOTH);

// Alpha enabled
_gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
_gl.glAlphaFunc(GL10.GL_GREATER, 0.1f);

// CCW frontfaces only, by default
_gl.glFrontFace(GL10.GL_CCW);
_gl.glCullFace(GL10.GL_BACK);
_gl.glEnable(GL10.GL_CULL_FACE);


//##################        
//# onSurfaceCreated
//##################

// build the lights - note this is specific to the min3d framework but 
// its pretty straightforward - if a change is made to a light source the dirty flag     is set
// and calls will be made to opengl to udpate accordingly in the onDrawFrame method
Light light1 = new Light();
light1.position.setAll(0, 10, 0);
light1.ambient= new Color4Managed(255, 255, 255, 255, light1);
light1.diffuse = new Color4Managed(255, 255, 255, 255, light1);
light1.specular = new Color4Managed(255, 255, 255, 255, light1);
light1.type(LightType.DIRECTIONAL);    
_scene.lights().add(light1);


//##################        
//# onSurfaceChanged
//##################

public void onSurfaceChanged(GL10 gl, int w, int h) {
    this.w = w;
    this.h = h;
    _surfaceAspectRatio = (float) w / (float) h;
    _gl.glViewport(0, 0, w, h);

    // all the following updates the frustum
    FrustumManaged vf = _scene.camera().frustum;
    float n = vf.shortSideLength() / 2f;
    float lt, rt, btm, top;
    lt = vf.horizontalCenter() - n * _surfaceAspectRatio;
    rt = vf.horizontalCenter() + n * _surfaceAspectRatio;
    btm = vf.verticalCenter() - n * 1;
    top = vf.verticalCenter() + n * 1;

    if (_surfaceAspectRatio > 1) {
        lt *= 1f / _surfaceAspectRatio;
        rt *= 1f / _surfaceAspectRatio;
        btm *= 1f / _surfaceAspectRatio;
        top *= 1f / _surfaceAspectRatio;
    }

    _gl.glFrustumf(lt, rt, btm, top, vf.zNear(), vf.zFar());

    Util.out("UPDATE VIEW FRUSTUM _surfaceAspectRatio: " + this._surfaceAspectRatio +     " w: " + this.w + " h: " + this.h);
    Util.out("UPDATE VIEW FRUSTUM lt: " + lt + " rt: " + rt + " btm: " + btm + " top:     " + top + " vf.zNear(): " + vf.zNear() + " vf.zFar(): " + vf.zFar());

    // sprint samsung galaxy 2s epic touch 4g
    // 09-18 23:41:31.255: INFO/System.out(14069): 2011-09-18 23:41:31> UPDATE VIEW     FRUSTUM _surfaceAspectRatio: 0.97959185 w: 480 h: 490
    // 09-18 23:41:31.255: INFO/System.out(14069): 2011-09-18 23:41:31> UPDATE VIEW     FRUSTUM lt: -0.48979592 rt: 0.48979592 btm: -0.5 top: 0.5 vf.zNear(): 1.0     vf.zFar(): 30.0

    // htc evo 3d 
    // 09-18 23:46:16.744: INFO/System.out(7958): 2011-09-18 23:46:16> UPDATE VIEW FRUSTUM _surfaceAspectRatio: 0.83076924 w: 540 h: 650
    // 09-18 23:46:16.754: INFO/System.out(7958): 2011-09-18 23:46:16> UPDATE VIEW FRUSTUM lt: -0.41538462 rt: 0.41538462 btm: -0.5 top: 0.5 vf.zNear(): 1.0 vf.zFar(): 30.0
}


//##################        
//# upload texture
//##################

int[] a = new int[1];
_gl.glGenTextures(1, a, 0); // create a 'texture name' and put it in array element 0
_gl.glBindTexture(GL10.GL_TEXTURE_2D, a[0]);

if ($generateMipMap && _gl instanceof GL11) {
    _gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
}else {
    _gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_FALSE);
}

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, $bitmap, 0);    


//##################        
//# onDrawFrame
//##################

// draw setup
_gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);        

// enable or disable lights
if(_scene.lights().isDirty()){
    for (int glIndex = 0; glIndex < NUM_GLLIGHTS; glIndex++) {
        if (_scene.lights().glIndexEnabledDirty()[glIndex] == true) {
            if (_scene.lights().glIndexEnabled()[glIndex] == true) {
                _gl.glEnable(GL10.GL_LIGHT0 + glIndex);
                    _scene.lights().getLightByGlIndex(glIndex).setAllDirty();
                } else {
                    _gl.glDisable(GL10.GL_LIGHT0 + glIndex);
                }
                _scene.lights().glIndexEnabledDirty()[glIndex] = false; //     clear dirtyflag
            }
        }
    _scene.lights().clearDirtyFlag();
}

// handle individual light settings
Light[] lights = _scene.lights().toArray();
for (int i = 0; i < lights.length; i++) {
    Light light = lights[i];
    if (light.isDirty()) // .. something has changed
    {
        int glLightId = GL10.GL_LIGHT0 + _scene.lights().getGlIndexByLight(light);

        if (light.position.isDirty()) {
            light.commitPositionAndTypeBuffer();
            _gl.glLightfv(glLightId开发者_如何转开发, GL10.GL_POSITION, light.positionAndTypeBuffer());
            light.position.clearDirtyFlag();
        }

        if (light.ambient.isDirty()) {
            light.ambient.commitToFloatBuffer();
            _gl.glLightfv(glLightId, GL10.GL_AMBIENT, ligh    t.ambient.floatBuffer());
            light.ambient.clearDirtyFlag();
        }

        if (light.diffuse.isDirty()) {
            light.diffuse.commitToFloatBuffer();
            _gl.glLightfv(glLightId, GL10.GL_DIFFUSE, light.diffuse.floatBuffer());
            light.diffuse.clearDirtyFlag();
        }

        if (light.specular.isDirty()) {
            light.specular.commitToFloatBuffer();
            _gl.glLightfv(glLightId, GL10.GL_SPECULAR, light.specular.floatBuffer());
            light.specular.clearDirtyFlag();
        }

        if (light.isVisibleBm().isDirty()) {
            if (light.isVisible()) {
                _gl.glEnable(glLightId);
            } else {
                _gl.glDisable(glLightId);
            }
            light.isVisibleBm().clearDirtyFlag();
        }

        if (light.attenuation().isDirty()) {
            _gl.glLightf(glLightId, GL10.GL_CONSTANT_ATTENUATION, light.attenuation().getX());
            _gl.glLightf(glLightId, GL10.GL_LINEAR_ATTENUATION, ligh    t.attenuation().getY());
            _gl.glLightf(glLightId, GL10.GL_QUADRATIC_ATTENUATION, light.attenuation().getZ());
        }

        light.clearDirtyFlag();
    }
}

// finally draw objects (see definition below)
foreach(Object3d $o : _scene.children()){
    drawObject($o);
}


//##################        
//# draw 3d object
//##################

_gl.glEnable(GL10.GL_LIGHTING);
_gl.glEnable(GL10.GL_TEXTURE_2D);
_gl.glEnable(GL10.GL_ALPHA_TEST);
_gl.glEnable(GL10.GL_BLEND);
_gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
_gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
_gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

$o.vertices().normals().buffer().position(0);
_gl.glNormalPointer(GL10.GL_FLOAT, 0, $o.vertices().normals().buffer());

_gl.glEnable(GL10.GL_CULL_FACE);

// draw texture function info below
drawObject_textures($o);

_gl.glTranslatef($o.position().x, $o.position().y, $o.position().z);
_gl.glRotatef(($o.rotation().x), 1, 0, 0);
_gl.glRotatef(($o.rotation().y), 0, 1, 0);
_gl.glRotatef(($o.rotation().z), 0, 0, 1);

_gl.glScalef($o.scale().x, $o.scale().y, $o.scale().z);

$o.vertices().points().buffer().position(0);
_gl.glVertexPointer(3, GL10.GL_FLOAT, 0, $o.vertices().points().buffer());

$o.faces().buffer().position(pos);

_gl.glDrawElements($o.renderTypeInt(), $o.faces().size() *    FacesBufferedList.PROPERTIES_PER_ELEMENT, GL10.GL_UNSIGNED_SHORT,$o.faces().buffer());


//##################        
//# draw texture
//##################

int minFilterType = ZoneActivity.mipmap ? GL10.GL_NEAREST_MIPMAP_NEAREST :     GL10.GL_NEAREST;

$o.vertices().uvs().buffer().position(0);

_gl.glActiveTexture(GL10.GL_TEXTURE0 );
_gl.glClientActiveTexture(GL10.GL_TEXTURE0);
_gl.glBindTexture(GL10.GL_TEXTURE_2D, $o.glTextureId);
_gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, $o.vertices().uvs().buffer());
_gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilterType);
_gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);     
_gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
_gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);    

EDIT: As it turns out it was me. What seemed like a texture issue was a side effect of passing incorrect values to the fog functions (which naturally I had omitted from my code samples).

bad

// I was not converting my rgba shorts to the expected range (0.0f, 1.0f).
// the evo 3d, bionic, etc. must compensate for people like me and translate
// this to white so i never knew there was a problem
_gl.glFogfv(GL10.GL_FOG_COLOR, [255f,255f,255f,255f]);

good

_gl.glFogfv(GL10.GL_FOG_COLOR, [1.0f, 1.0f, 1.0f, 1.0f]);

Its probably safe to close this.


This is a stab in the dark, (I haven't used GL for ages) but judging from the images you posted and the lines of code with "GL10.GL_NEAREST_MIPMAP_NEAREST" or (even worse!) "GL10.GL_NEAREST", you are going to get ugly texture filtering. Try the "LINEAR" filters instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜