ОбзораИзменение непрозрачности отдельных элементов в OpenGL ES 2.0 Quad Batch
В моем приложении (это игра), я использую группирование элементов, чтобы уменьшить количество вызовов отрисовки. Итак, я создам, например, объект Java под названием платформы, который для всех платформ в игре. Все враги собраны вместе, как и все предметы коллекционирования и т. Д.
Это работает очень хорошо. В настоящее время я могу сортировать и размещать отдельные элементы в партии независимо друг от друга, однако я пришел к тому моменту, когда мне действительно нужно изменить непрозрачность отдельных элементов. В настоящее время я могу изменить только непрозрачность всей партии.
Дозирование
я отправляю вершины для всех элементов внутри партии, которые должны быть отображены (я могу включить отдельные элементы, если бы я не хочу им быть обращено), а затем, как только они все сделано, я просто рисую их одним звонком.
Ниже приводится представление о том, что я делаю - я понимаю, что это может не скомпилировать, это просто дать идею для цели вопроса.
public void draw(){
//Upload vertices
for (count = 0;count<numOfSpritesInBatch;count+=1){
vertices[x] = xLeft;
vertices[(x+1)] = yPTop;
vertices[(x+2)] = 0;
vertices[(x+3)] = textureLeft;
vertices[(x+4)] = 0;
vertices[(x+5)] = xPRight;
vertices[(x+6)] = yTop;
vertices[(x+7)] = 0;
vertices[(x+8)] = textureRight;
vertices[x+9] = 0;
vertices[x+10] = xLeft;
vertices[x+11] = yBottom;
vertices[x+12] = 0;
vertices[x+13] = textureLeft;
vertices[x+14] = 1;
vertices[x+15] = xRight;
vertices[x+16] = yTop;
vertices[x+17] = 0;
vertices[x+18] = textureRight;
vertices[x+19] = 0;
vertices[x+20] = xLeft;
vertices[x+21] = yBottom;
vertices[x+22] = 0;
vertices[x+23] = textureLeft;
vertices[x+24] = 1;
vertices[x+25] = xRight;
vertices[x+26] = yBottom;
vertices[x+27] = 0;
vertices[x+28] = textureRight;
vertices[x+29] = 1;
x+=30;
}
vertexBuf.rewind();
vertexBuf.put(vertices).position(0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texID);
GLES20.glUseProgram(iProgId);
Matrix.multiplyMM(mvpMatrix2, 0, mvpMatrix, 0, mRotationMatrix, 0);
mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix2, 0);
vertexBuf.position(0);
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
GLES20.glEnableVertexAttribArray(iPosition);
vertexBuf.position(3);
GLES20.glVertexAttribPointer(iTexCoords, 2, GLES20.GL_FLOAT, false, 5 * 4, vertexBuf);
GLES20.glEnableVertexAttribArray(iTexCoords);
//Enable Alpha blending and set blending function
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//Draw it
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6 * numOfSpritesInBatch);
//Disable Alpha blending
GLES20.glDisable(GLES20.GL_BLEND);
}
шейдеры
String strVShader =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 a_position;\n"+
"attribute vec2 a_texCoords;" +
"varying vec2 v_texCoords;" +
"void main()\n" +
"{\n" +
"gl_Position = uMVPMatrix * a_position;\n"+
"v_texCoords = a_texCoords;" +
"}";
String strFShader =
"precision mediump float;" +
"uniform float opValue;"+
"varying vec2 v_texCoords;" +
"uniform sampler2D u_baseMap;" +
"void main()" +
"{" +
"gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
"gl_FragColor *= opValue;"+
"}";
В настоящее время у меня есть метод в моем классе Sprite, который позволяет мне изменить opacty. Например, примерно следующее:
spriteBatch.setOpacity(0.5f); //Half opacity
Это работает, но меняет всю партию - не то, что мне нужно.
Применение
мне это нужно, потому что я хочу обратить небольшие индикаторы, когда игрок уничтожает враг - которые показывают счет, полученный от этого действия. (Тип вещи, которая случается во многих играх) - Я хочу, чтобы эти маленькие индикаторы оценки исчезли после их появления. Разумеется, все индикаторы будут созданы как партия, чтобы все они могли быть нарисованы с помощью одного вызова.
Единственные другие альтернативы:
- Создание 10 текстур на разных уровнях непрозрачности и просто переключаться между ними, чтобы создать эффект замирания. На самом деле вариант не слишком расточительный.
- Создайте каждый из этих объектов отдельно и нарисуйте каждый со своим собственным призывом рисования. Будет работать, но с максимальным количеством из 10 этих объектов на экране я могу потенциально рисовать, используя 10 призывов рисования только для этих предметов - в то время как игра в целом в настоящее время использует только 20 призывов рисования, чтобы нарисовать сотни предметов.
Мне нужно посмотреть на будущие использования этого также в системах частиц и т. Д., Поэтому я хотел бы попытаться выяснить, как это сделать (уметь отдельно регулировать непрозрачность каждого предмета). Если мне нужно сделать это в шейдере, я был бы признателен, если бы вы могли показать, как это работает. Альтернативно, возможно ли это сделать за пределами шейдера?
Несомненно, это может быть сделано так или иначе? Все предложения приветствуются ....
Как насчет использования атрибута вершины для непрозрачности? Измените '' '' '' '' '' '' '' '' 'на' атрибут' в вершинном шейдере и передайте в perle-вершины, как и другие атрибуты вершин, которые у вас уже есть. –
Я был в этом весь день @RetoKoradi, я изменил свой opValue на атрибут, как было предложено, но я не могу понять, как отправить эту информацию в шейдер - любые подсказки? На данный момент я устанавливаю свою непрозрачность перед рендерингом с этим: mOpacityHandle = GLES20.glGetUniformLocation (iProgId, «opValue»); а затем GLES20.glUniform1f (mOpacityHandle, op); \t Благодарен за некоторые рекомендации, спасибо – Zippy
Вы уже используете атрибуты для координат положения и текстуры. Просто следуйте тому же, что вы сделали для них. –