2013-10-24 7 views
2

Я закодировал свой собственный код наложения ARGB-изображений, и он оптимизирован так быстро, как «возможно». Однако это не так быстро, как хотелось бы. Кроме того, этот процесс называется несколько раз и использует много CPU.Как накладывать изображения, используя opengl в массив пикселей?

Я хочу использовать графический процессор для выполнения наложения изображений. Я думаю, что это потенциально может обеспечить огромный прирост скорости и минимальное использование ЦП.

Как я могу использовать графический процессор для наложения изображений? Из моих исследований я могу использовать буфер кадров для вывода экрана. Тем не менее, я не уверен на 100%, как это сделать. По сути, я передаю Bitmap от java до JNI, а затем получаю пиксели Bitmap, где мне нужно будет накладывать изображения. Количество накладываемых изображений может варьироваться от 2 до 12. Это большие изображения.

Update1:
До сих пор это то, что у меня есть. Я считаю, что это шаг в правильном направлении.

GLuint arraybuffer; 
glGenBuffers(GL_ARRAY_BUFFER, &arraybuffer); 
glBindBuffer(GL_ARRAY_BUFFER, arraybuffer); 

// draw into the array buffer the images 
... 

// read the buffer pixels from OpenGL 
glReadPixels(0, 0, outputWidth, outputHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 
+0

читайте это: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html речь идет только о самом OpenGL (не в специфическом для OpenGL ES), но вы можете иметь очень хорошее понимание того, как работает графический конвейер (GPU). –

ответ

2

Да, все, что вам нужно сделать, это настроить контекст OpenGL. Это очень просто в документации для Android. Никаких секретов!

Displaying Graphics with OpenGL ES

Затем установите ваш фреймбуфер:

Проверить эту ссылку здесь: Android OpenGL ES Framebuffer objects - rendering depth-buffer to texture

Все функции здесь довольно много то же самое, как и в GLES20 от Android. Некоторые методы имеют имена немного разные, но вы можете найти их все наверняка.

Когда вы достигнете части Drawing Shapes. Вы должны написать свои вершинные и фрагментарные шейдеры. Вершинный шейдер может быть таким же, как в примере. За исключением того, что вам нужно лечить ваш VBO (vertexBuffer в образце Android). Вы должны указать вершины (координаты, где вы рисуете), и УФ (координаты вашей текстуры), чтобы нарисовать текстуру в изображении судьбы (один VBO для вершин, а другой - УФ).

Фрагмент шейдера - это то, что вы ищите. Он будет выполнен GPU для каждого пикселя вашего процесса наложения. Это можно сделать что-то вроде этого:

пиксельный шейдер для Overlay:

precision mediump float; 
uniform float opacity;   // if you want to apply opacity 
uniform sampler2D myTexture; // the image you are drawing overlay 
uniform sampler2D myBackground; // the destiny texture ID 
varying vec2 texturePoint;  // here is a coordinate (U,V) coming from the VBO 
           // this one must come from the vertex shader. 

void main() 
{ 
    vec2 texturePointBG = gl_FragCoord.xy/textureSize(myBackground, 0); 
    vec4 A = texture2D(myTexture, texturePoint); 
    vec4 B = texture2D(myBackground, texturePointBG); 

    // this is one of the most traditional formula for overlay 
    // http://en.wikipedia.org/wiki/Blend_modes 
    gl_FragColor = vec4(
     B.x < 0.5 ? (2.0 * B.x * A.x) : (1.0 - 2.0 * (1.0 - B.x) * (1.0 - A.x)), 
     B.y < 0.5 ? (2.0 * B.y * A.y) : (1.0 - 2.0 * (1.0 - B.y) * (1.0 - A.y)), 
     B.z < 0.5 ? (2.0 * B.z * A.z) : (1.0 - 2.0 * (1.0 - B.z) * (1.0 - A.z)), 
     A.a 
    ); 

    gl_FragColor.a *= opacity; // if you want! 
} 

Вы можете узнать, как настроить единые переменные в документации Android ... так что вы можете дать то некоторые дополнительные параметры, например, opacity.

+0

Итак, вы говорите, что мне нужно зацикливать каждый пиксель x, y для вычисления наложения или это автоматически делается? Как я могу хранить наложенные изображения? Скажем, у меня есть 6 изображений, которые я хочу наложить быстрее всего. Нужно ли создавать текстуру для каждого из этих изображений? Я не уверен на 100%, я понимаю ваш код ...извините, новичок в OpenGl. – Jona

+0

Нет, вам НЕ нужно зацикливаться на каждом (x, y). Шейдер фрагмента выполняется на пиксель. Это похоже на то, что OpenGL делает цикл для вас, но он фактически распараллеливает его, выполняя все циклы цикла. Вы пишете только свой шейдер фрагмента. Но на ваш вопрос нелегко ответить в быстрый ответ. Вы должны изучить OpenGL. Попробуйте это: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Table-of-Contents.html –

+0

Полностью согласен Мне нужно узнать больше OpenGL. Думал, что я могу уйти с ярлыками, но кажется, что я, возможно, не смогу. – Jona

Смежные вопросы