Android OpenGL - ES Текстура кровотечения - PullRequest
5 голосов
/ 18 октября 2010

Я пишу небольшое приложение, которое в данный момент генерирует случайную карту текстур.

Я рисую эту карту в виде группы "квадов" 10 x 15, которые затрагивают все треугольные полосы. Я использую «карту», ​​чтобы взять int, который я затем беру в качестве местоположения текстуры для этого квадрата в textureAtlas. так, например, 0 - это левая нижняя «плитка». Атлас имеет размер 128 x 128 и разделен на 32 пиксельные плитки.

Однако я, кажется, получаю некоторые странные артефакты, когда текстура из одной плитки проникает в следующую плитку. Я задавался вопросом, было ли это само изображение, но насколько я могу судить, пиксели точно, где они должны быть. Затем я посмотрел на координаты текстуры, которые я указывал, но все они выглядят точно (0,0, 0,25, 0,5, 0,75, 1,0 - разделив их на 4 строки и столбца, которые я ожидаю).

Странно, если я запускаю его на эмуляторе, я не получаю никаких артефактов.

Есть ли пропущенная настройка, которая может привести к кровотечению в 1 пиксель? Кажется, он тоже только вертикальный - это может быть связано с тем, что на телефоне я «растягиваю» изображение в этом направлении, поскольку экран телефона в этом направлении больше нормального.

Я загружаю текстуру так:

//Get a new ID
    int id = newTextureID(gl);

    //We will need to flip the texture vertically
    Matrix flip = new Matrix();
    flip.postScale(1f, -1f);

    //Load up and flip the texture
    Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource);

    //Store the widths for the texturemap
    int width = temp.getWidth();
    int height = temp.getHeight();
    Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, width, height, flip, true);
    temp.recycle();

    //Bind
    gl.glBindTexture(GL10.GL_TEXTURE_2D, id);

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

    //Push onto the GPU
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

    TextureAtlas atlas = new TextureAtlas(id, width, height, tileSize);
    return atlas;

Затем я отображаю это так:

gl.glBindTexture(GL10.GL_TEXTURE_2D, currentAtlas.textureID);
    //Enable the vertices buffer for writing and to be used during our rendering
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    //Specify the location and data format of an array of vertex coordinates to use
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    //Enable the texture buffer
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);

Я бы сделал снимок, но я не уверен, как получить крышку экрана от телефона ...

Если кто-нибудь знает, как я могу захватить текущий кадр и, возможно, поместить его в файл, я сделаю это, если это поможет объяснить, что происходит!

С нетерпением ждем вашего ответа.

Редактировать: вот скриншот. Обратите внимание, что я запускаю приложение в альбомной ориентации, но крышка в портретной ориентации. Также извините за ужасные текстуры: D они были просто заполнителем / бездельничают.

ScreenCap

1 Ответ

11 голосов
/ 18 октября 2010

Ну, после разговора с другом мне удалось решить эту маленькую проблему.

Оказывается, что если вы хотите получить точные текстуры с идеальным пикселем, вам нужно указать край текстуры, который будет на полпути в пиксель.

Чтобы сделать это, я просто добавил половину пикселя или вычел половину пикселя к измерению для координат текстуры.

Вот так:

//Top Left
            textureCoords[textPlace] = xAdjust*currentAtlas.texSpaceWidth + currentAtlas.halfPixelAdjust;        textPlace++;
            textureCoords[textPlace] = (yAdjust+1)*currentAtlas.texSpaceHeight - currentAtlas.halfPixelAdjust;    textPlace++;

Это было просто вычислено при загрузке атласа текстуры:

(float)(0.5 * ((1.0f / numberOfTilesInAtlasRow) / pixelsPerTile));

Хотя, если высота отличается от ширины каждой плитки (что может произойти), вам нужно будет рассчитать их по отдельности.

Это решило все артефакты, чтобы я мог продолжить. Надеюсь, это поможет кому-то еще!

...