OpenGL 奇怪问题:屏幕适合 480x854 设备,裁剪图像具有 1 像素差异,怎么了?

发布于 2024-12-11 17:57:12 字数 2921 浏览 0 评论 0原文

我正在android上工作我的游戏,使用OpenGL开发2D游戏,在320x480设备上运行是工作。(没有任何损坏)

不幸的是我的motorola defy(480x854)上的问题,似乎调整UV点对象具有1-px差异(向上或向下 1 px 位置偏差)。

SurfaceChanged返回宽度320,高度569 AndroidManifest anyDensity 设置为 false

下面两张图片有两个矩形,左边一张是原始图片(w=36,h=35),没有裁剪;中间一个是uv剪辑,从px1绘制并仅裁剪宽度34px,高度33px,右边一个很长的矩形,从上到下从px0到px480绘制宽度34px,高度1px,抱歉虚拟代码,但你知道我的意思。

我之前的游戏是用 SurfaceView 编写的,可在 320x480、480x800、480x854 和 1024x768 上运行。

图片看起来像作品,宽度已填充,但底部有最大的空白。

如果我插入 w=320; h=480;在 SurfaceChanged 中的 GLUgluOrtho2D 之前,一些对象工作(不使用 UV 裁剪)

image1 http://i1105.photobucket.com/albums/h355/ch_mac/device_str5。 png

我想要的结果:

wantedresult http://i1105.photobucket.com/albums/h355/ch_mac/device_str6。 png

我的纹理绘制方法:

public void draw(int from_x,int from_y,int w,int h,int pos_x,int pos_y)
{

          bind();
          float texW=(float)mPow2Width;  
          float texH=(float)mPow2Height;

          float minU= from_x/texW;
          float maxU = (from_x+w)/texW;        
          float minV= from_y/texH;        
          float maxV = (from_y+h)/texH;
           float verticleBuffer[] = {
               x,  y,
             x+w,  y,
               x, y+h,
             x+w, y+h,
           };
           float coordBuffer[] = {
            minU, minV,
            maxU, minV,
            minU, maxV,
            maxU, maxV, 
    };

FloatBuffer     m_vertexBuffer;
    FloatBuffer     m_textureBuffer;
    ByteBuffer l_byteBuf;
    l_byteBuf = ByteBuffer.allocateDirect( verticleBuffer.length * 4 );
    l_byteBuf.order( ByteOrder.nativeOrder() );
    m_vertexBuffer = l_byteBuf.asFloatBuffer();
    m_vertexBuffer.put( verticleBuffer );
    m_vertexBuffer.position( 0 );

    l_byteBuf = ByteBuffer.allocateDirect( coordBuffer.length * 4 );
    l_byteBuf.clear();
    l_byteBuf.order( ByteOrder.nativeOrder() );
    m_textureBuffer = l_byteBuf.asFloatBuffer();
    m_textureBuffer.put( coordBuffer );
    m_textureBuffer.position( 0 );

           gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, m_textureBuffer);
           gl.glVertexPointer(2, GL10.GL_FLOAT, 0, m_vertexBuffer);     
           gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);

}

SurfaceChanged:

public void onSurfaceChanged(GL10 gl, int w, int h) 
{
    gl.glViewport(0, 0, w, h);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    float aspect_w=(float)h/(float)w;
    float aspect_h=(float)w/(float)h;       
    //w=320;
    //h=480;
    GLU.gluOrtho2D(gl, 0, w, h, 0);

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}

I am work my game on android, using OpenGL developing 2D game, running on 320x480 device was work.(no any broken)

Unfortunately issue on my motorola defy (480x854), seems like the adjust UV point object having 1-px diff(up or down 1 px position deviation).

SurfaceChanged return width 320,height 569
AndroidManifest anyDensity is setting false

Below two images have two rectangle, the left one is original image(w=36,h=35), no crop; middle one is clip by uv, draw from px1 and crop only width 34px,height 33px,right one very long rectangle, draw from top to bottom from px0 to px480 width 34px,height 1px, sorry for virtual code but you know what I means.

My previous game is written in SurfaceView, worked on 320x480, 480x800, 480x854 and 1024x768.

The picture look like work, width filled but bottom has biggest empty.

If I insert w=320; h=480; before GLUgluOrtho2D in SurfaceChanged,some object work(which not use crop by UV)

image1
http://i1105.photobucket.com/albums/h355/ch_mac/device_str5.png

The result I would like :

wantedresult
http://i1105.photobucket.com/albums/h355/ch_mac/device_str6.png

My texture drawing method :

public void draw(int from_x,int from_y,int w,int h,int pos_x,int pos_y)
{

          bind();
          float texW=(float)mPow2Width;  
          float texH=(float)mPow2Height;

          float minU= from_x/texW;
          float maxU = (from_x+w)/texW;        
          float minV= from_y/texH;        
          float maxV = (from_y+h)/texH;
           float verticleBuffer[] = {
               x,  y,
             x+w,  y,
               x, y+h,
             x+w, y+h,
           };
           float coordBuffer[] = {
            minU, minV,
            maxU, minV,
            minU, maxV,
            maxU, maxV, 
    };

FloatBuffer     m_vertexBuffer;
    FloatBuffer     m_textureBuffer;
    ByteBuffer l_byteBuf;
    l_byteBuf = ByteBuffer.allocateDirect( verticleBuffer.length * 4 );
    l_byteBuf.order( ByteOrder.nativeOrder() );
    m_vertexBuffer = l_byteBuf.asFloatBuffer();
    m_vertexBuffer.put( verticleBuffer );
    m_vertexBuffer.position( 0 );

    l_byteBuf = ByteBuffer.allocateDirect( coordBuffer.length * 4 );
    l_byteBuf.clear();
    l_byteBuf.order( ByteOrder.nativeOrder() );
    m_textureBuffer = l_byteBuf.asFloatBuffer();
    m_textureBuffer.put( coordBuffer );
    m_textureBuffer.position( 0 );

           gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, m_textureBuffer);
           gl.glVertexPointer(2, GL10.GL_FLOAT, 0, m_vertexBuffer);     
           gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);

}

SurfaceChanged :

public void onSurfaceChanged(GL10 gl, int w, int h) 
{
    gl.glViewport(0, 0, w, h);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    float aspect_w=(float)h/(float)w;
    float aspect_h=(float)w/(float)h;       
    //w=320;
    //h=480;
    GLU.gluOrtho2D(gl, 0, w, h, 0);

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

新一帅帅 2024-12-18 17:57:12

将视口和投影设置放置在绘图处理程序中。这是它们真正有意义的唯一地方(就像大多数其他 OpenGL 操作一样)。在其他地方做这些事情是一场簿记噩梦,并且不会获得任何绩效。


编辑:另一个问题:

float verticleBuffer[] = {
           x,  y,
         x+w,  y,
           x, y+h,
         x+w, y+h,
       };
float coordBuffer[] = {
        minU, minV,
        maxU, minV,
        minU, maxV,
        maxU, maxV, 
}

您确定 coordBuffer 是正确的吗?对我来说,最后两行似乎被交换了,即那一行更有意义:

float coordBuffer[] = {
        minU, minV,
        maxU, minV,
        maxU, maxV,
        minU, maxV, 
}

Place the viewport and projection setup in the drawing handler. It's the only place where they actually make sense (like most other OpenGL operation). Doing those things somewhere else is a bookkeeping nightmare and gains no performance.


EDIT: Another issue:

float verticleBuffer[] = {
           x,  y,
         x+w,  y,
           x, y+h,
         x+w, y+h,
       };
float coordBuffer[] = {
        minU, minV,
        maxU, minV,
        minU, maxV,
        maxU, maxV, 
}

Are you sure that coordBuffer is right? To me it looks like the last two lines are swappned, i.e. that one made more sense:

float coordBuffer[] = {
        minU, minV,
        maxU, minV,
        maxU, maxV,
        minU, maxV, 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文