如何使用glDrawTexfoes缩放平铺位图?

时间:2012-10-31 17:19:24

标签: android opengl-es

我有一个游戏专门用于图形的glDrawTexfoes()。当然是2d。到目前为止,我在绘制它时没有拉伸图形:我有2套,一套小的不同设备。这种方法达到了极限(坦率地说,我不应该使用它 - 但那是2年前)。

所以现在我正在尝试使用一组图像并使用glDrawTexfoes来缩放它们以填满显示。除了我平铺图像之外,它大部分都在工作。我已经包含了显示结果的图像。垂直线不应该在那里。

button problem

我尽可能多地使用纹理参数,但我无法摆脱这个问题,所以我转向了SO。以下是一些细节:图像不是2的幂。它没有使用精灵表,每个精灵都有自己的位图。

我使用此代码

创建纹理
    bitmap.prepareTexture(_glMaxTextureSize);

    gl.glGenTextures(1, mTextureNameWorkspace, 0);

    int error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
        Log.d("Texture Load 1", "GLError: " + error + " (" + GLU.gluErrorString(error) + "): " + bitmap.toString() );
    }

    assert error == GL10.GL_NO_ERROR;

    bitmap.textureName = mTextureNameWorkspace[0];

    gl.glBindTexture(GL10.GL_TEXTURE_2D, bitmap.textureName);

    error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
        Log.d("Texture Load 2", "GLError: " + error + " (" + GLU.gluErrorString(error) + "): " + bitmap.toString());
    }

    assert error == GL10.GL_NO_ERROR;

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); //GL10.GL_REPLACE);

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

    error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
        Log.d("Texture Load 3", "GLError: " + error + " (" + GLU.gluErrorString(error) + "): " + bitmap.toString());
    }

    bitmap.releaseTextureBitmap();

    assert error == GL10.GL_NO_ERROR;

    mCropWorkspace[0] = 0;
    mCropWorkspace[1] = bitmap.getHeight();
    mCropWorkspace[2] = bitmap.getWidth();
    mCropWorkspace[3] = -bitmap.getHeight();

    ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);

    error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR) {
        Log.d("Texture Load 4", "GLError: " + error + " (" + GLU.gluErrorString(error) + "): " + bitmap.toString());
    }

    assert error == GL10.GL_NO_ERROR;

使用以下代码

创建opengl上下文
       /*
    * Some one-time OpenGL initialization can be made here probably based
    * on features of this particular context
    */
   gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

   gl.glClearColor(0.0f, 0.0f, 0.0f, 1);
   gl.glShadeModel(GL10.GL_FLAT);
   gl.glDisable(GL10.GL_DEPTH_TEST);
   gl.glEnable(GL10.GL_TEXTURE_2D);
   /*
    * By default, OpenGL enables features that improve quality but reduce
    * performance. One might want to tweak that especially on software
    * renderer.
    */
   gl.glDisable(GL10.GL_DITHER);
   gl.glDisable(GL10.GL_LIGHTING);

   gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

   gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

视口以下列方式设置

      float scaleX = (float)w / _screenWidth;
  float scaleY =  (float)h / _screenHeight;
  final int viewportWidth = (int)(_screenWidth * scaleX);
  final int viewportHeight = (int)(_screenHeight * scaleY);
  gl.glViewport(0, 0, viewportWidth, viewportHeight);
  mScaleX = scaleX;
  mScaleY = scaleY;

  /*
   * Set our projection matrix. This doesn't have to be done each time we
   * draw, but usually a new projection needs to be set when the viewport
   * is resized.
   */
  float ratio = (float) _screenWidth / _screenHeight;
  gl.glMatrixMode(GL10.GL_PROJECTION);
  gl.glLoadIdentity();
  gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

最后,请原谅代码墙,图纸是用

完成的
 gl.glShadeModel(GL10.GL_FLAT);
   gl.glEnable(GL10.GL_BLEND);
   gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
   gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);

   gl.glViewport(0, 0, (int)viewWidth, (int)viewHeight);
   gl.glMatrixMode(GL10.GL_PROJECTION);
   gl.glLoadIdentity();
   gl.glOrthof(0, viewWidth, viewHeight, 0.0f, 0.0f, 1.0f);
   gl.glMatrixMode(GL10.GL_MODELVIEW);
   gl.glLoadIdentity();

   gl.glEnable(GL10.GL_TEXTURE_2D);

   [loop over sprites]
           final float screenScale = 800/600f; // hardcoded to test stuff out
           final float snappedX = ((x  + transX)*screenScale); //+ e.speedX * interpolation;
           final float snappedY = _screenHeight - (y + height + transY ) * screenScale;//+ e.speedY * interpolation);
           final int texName = ob.textureName;

           gl.glBindTexture(GL10.GL_TEXTURE_2D, texName);

           _cropWorkspace[0] = left;
           _cropWorkspace[1] = top + height;
           _cropWorkspace[2] = width;
           _cropWorkspace[3] = -height;

           if( operation == Drawer.MIRROR_X )
           {
              _cropWorkspace[0] = left + width;
              _cropWorkspace[2] = -width;
           }

           ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, _cropWorkspace, 0);
           ((GL11Ext) gl).glDrawTexfOES(snappedX, snappedY, 1, width * screenScale, height * screenScale );   

1 个答案:

答案 0 :(得分:0)

我发现了问题:由于缩放和过采样,我需要在位图的裁剪空间周围添加边框/填充以避免黑线。

_cropWorkspace[0] = left + padding;
_cropWorkspace[1] = top + height - padding;
_cropWorkspace[2] = width - padding * 2;
_cropWorkspace[3] = -(height-padding*2);