2016-03-17 4 views
-1

Я рассмотрел this как пример того, как визуализировать обычную текстуру на холсте с помощью WebGL и успешно ее реализовать.Как реализовать прокручивающуюся текстуру в WebGL?

Теперь я пытаюсь реализовать прокручиваемое изображение, где я получаю линейные пиксельные данные с другого компьютера в той же сети через Ajax-опрос или веб-сайты и должен визуализировать то же самое с помощью WebGL на холсте.

Итак, теперь я знаю, что мы можем легко отображать 60 кадров в секунду, что означает, что если я получаю 50 строк пиксельных данных в секунду с другого компьютера в сети, я должен быть легко способен отображать их без каких-либо рывков.

Я могу выполнить пиксельную передачу с использованием CPU (javascript), где я визуализирую 1-ю строку данных и получая вторую строку данных, я перемещаю 1-ю строку данных пикселя на 2-й и обрабатываю новую строку первая строка. Это работает, но я не вижу гладкой прокрутки, я также пытался использовать gl.texSubImage2D, сохраняя все данные линии в одном массиве и пробираясь через него при получении новой строки, но также не работает должным образом.

В принципе, я ищу, что я получу 1 строку пиксельных данных от другого ПК в сети, а затем я отображу это как 1-ю строку текстуры, а затем, когда я получу вторую строку, тогда GPU должен перенести 1-ю строку данных пикселя во вторую строку, и после того, как я отображу 1-ю новую строку данных пикселя, полученных по сети, я отображу первую строку, вызвав gl.texSubImage2D и вызову gl.drawArrays, чтобы убедиться, что мы выполняем рендеринг без каких-либо рывки. Это должно произойти до конца текстуры, поэтому GPU позаботится о перемещении пикселей, а CPU позаботится о передаче новой строки данных пикселя на GPU.

Таким образом, GPU позаботится о перемещении пикселей, чтобы выполнить прокручиваемое изображение, вместо того, чтобы делать это с помощью процессора и висит браузер.

Я также прошел через what is the most efficient way of moving multiple objects (stored in VBO) in space? should I use glTranslatef or a shader? и https://www.opengl.org/discussion_boards/showthread.php/136155-Scrolling-textures

Но еще немного запутался о том, как осуществить это точно. Любые предложения?

+0

Это уже сделано [здесь] (HTTP: // StackOverflow .com/questions/10847985/glsl-shader-that-scroll-texture) в opengl, я не ac/C++ парень, поэтому кто-нибудь может это понять и объяснить мне в терминах webgl javascript – subhfyu546754

+0

Ум ответ, который вы упомянули в своем комментарии, не использовать любой c/C++ и может быть реализован с 1 по 1 в WebGL, что именно вы не понимаете? –

ответ

0

Вы уже задали этот вопрос уже 4 раза. Here, here, here, и here.

Рабочий ответ уже указан here.

В основном это показало, что, хотя вы можете визуализировать со скоростью 60 кадров в секунду, вы вряд ли сможете получать данные со скоростью 60 кадров в секунду. Он также показал, что НЕ ПРИЧИНА ДАННЫХ. Зачем создавать больше работы для себя?

Вы, по-видимому, хотите бесконечно прокручивающийся дисплей. Во-первых, как я уже указывал, нет никакой гарантии, что ваши данные поступят достаточно быстро. Пользователь может находиться на медленном соединении или может использовать соединение для чего-то другого (netflix, youtube, torrents).

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

Вот the same answer I gave you before слегка модифицирован для бесконечных данных

Примечания: Это предполагает, 1 столбец добавляется в текстуру для каждого кадра. Все, что он делает, это продолжать писать столбцы в текстуру. Итак, представьте, что в текстуре всего 8 столбцов.Первый кадр текстура выглядит следующим образом только 1 столбец данных

[1.......] 

Затем он рисует это с помощью 2 вызовов отрисовки для одной и той же текстуры рисунка только первый столбец справа, а остальную часть текстуры слева ,

[.......][1] 

Следующий кадр текстура выглядит, как это с 2 колонками данных

[12......] 

И рисует эти 2 части

[......][12] 

Когда 9-й столбец данных приходит (наш текстура составляет всего 8 столбцов), мы заменяем первый столбец так, чтобы текстура выглядела так:

[92345678] 

тогда Проведем это с 2 ничьи звонки

[2345678][9] 

Повторите это навсегда, и он будет выглядеть бесконечной прокрутки текстуры.

Код притворяется, что он получает бесконечный набор данных, вызывая getNextLineData. getNextLineData просто генерирует новый столбец данных. Эта функция должна быть заменена на то, что получает данные из сети.

Если вы действительно хотите, чтобы это работало, хотя вам придется иметь дело с сетевыми проблемами. Вам нужно будет решить, что делать, когда сеть работает медленно. Вы перестали прокручивать? Продолжаете ли вы прокручивать пустые данные? Повторяя одни и те же данные? Какие?

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

Вы упомянули ЭКГ. Если вам нужны данные, чтобы жить, вы не захотите кэшировать данные, вы бы хотели показать столько, сколько вы получили каждый кадр. Самый простой способ - позвонить getNextLineData, пока не закончите данные.

Также обратите внимание, что ничего подобного в этом примере не требует WebGL. Вы можете так же легко сделать это с помощью холста 2d. Создайте один холст как «текстуру». Обновление столбца для каждого кадра с помощью ctx.putImageData затем вызвать ctx2.drawImage в отдельный холст называет похож на 2 drawImage вызовов в этом WebGL примере

var m4 = twgl.m4; 
 
var gl = twgl.getWebGLContext(document.getElementById("c")); 
 
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]); 
 

 
// a unit quad 
 
var arrays = { 
 
    position: { 
 
    numComponents: 2, 
 
    data: [ 
 
     0, 0, 
 
     1, 0, 
 
     0, 1, 
 
     0, 1, 
 
     1, 0, 
 
     1, 1, 
 
    ], 
 
    }, 
 
}; 
 
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); 
 
     
 
// make the texture the same size as the canvas just to make it easy 
 
var texWidth = gl.canvas.width; 
 
var texHeight = gl.canvas.height; 
 
     
 
// we're only using 1 texture so just make and bind it now 
 
var tex = gl.createTexture(); 
 
gl.bindTexture(gl.TEXTURE_2D, tex); 
 
gl.texImage2D(
 
     gl.TEXTURE_2D, 0, gl.LUMINANCE, texWidth, texHeight, 0, 
 
     gl.LUMINANCE, gl.UNSIGNED_BYTE, null); 
 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 
 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 
 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
 
     
 
var destColumn = 0; 
 
     
 
// We're using 1 byte wide texture pieces so we need to 
 
// set UNPACK_ALIGNMENT to 1 as it defaults to 4 
 
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); 
 
      
 
function addLineToTexture(lineData) { 
 
    gl.texSubImage2D(gl.TEXTURE_2D, 0, destColumn, 0, 1, texHeight, 
 
        gl.LUMINANCE, gl.UNSIGNED_BYTE, lineData); 
 
     
 
    // advance column and wrap back to 0 
 
    destColumn = (destColumn + 1) % texWidth; 
 
} 
 

 
// we pass in texWidth and texHeight because unlike images 
 
// we can't look up the width and height of a texture 
 

 
// we pass in targetWidth and targetHeight to tell it 
 
// the size of the thing we're drawing too. We could look 
 
// up the size of the canvas with gl.canvas.width and 
 
// gl.canvas.height but maybe we want to draw to a framebuffer 
 
// etc.. so might as well pass those in. 
 

 
// srcX, srcY, srcWidth, srcHeight are in pixels 
 
// computed from texWidth and texHeight 
 

 
// dstX, dstY, dstWidth, dstHeight are in pixels 
 
// computed from targetWidth and targetHeight 
 
function drawImage(
 
    tex, texWidth, texHeight, 
 
    srcX, srcY, srcWidth, srcHeight, 
 
    dstX, dstY, dstWidth, dstHeight, 
 
    targetWidth, targetHeight) { 
 
    var mat = m4.identity(); 
 
    var tmat = m4.identity(); 
 
    
 
    var uniforms = { 
 
    matrix: mat, 
 
    textureMatrix: tmat, 
 
    texture: tex, 
 
    }; 
 

 
    // these adjust the unit quad to generate texture coordinates 
 
    // to select part of the src texture 
 

 
    // NOTE: no check is done that srcX + srcWidth go outside of the 
 
    // texture or are in range in any way. Same for srcY + srcHeight 
 

 
    m4.translate(tmat, [srcX/texWidth, srcY/texHeight, 0], tmat); 
 
    m4.scale(tmat, [srcWidth/texWidth, srcHeight/texHeight, 1], tmat); 
 

 
    // these convert from pixels to clip space 
 
    m4.ortho(0, targetWidth, targetHeight, 0, -1, 1, mat) 
 

 
    // these move and scale the unit quad into the size we want 
 
    // in the target as pixels 
 
    m4.translate(mat, [dstX, dstY, 0], mat); 
 
    m4.scale(mat, [dstWidth, dstHeight, 1], mat); 
 

 
    gl.useProgram(programInfo.program); 
 
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo); 
 
    twgl.setUniforms(programInfo, uniforms); 
 
    twgl.drawBufferInfo(gl, gl.TRIANGLES, bufferInfo); 
 
    
 
} 
 

 
// Scroll constantly 
 
    
 
function render() { 
 
    addLineToTexture(getNextLineData()); 
 
    
 
    function drawFirstPart() { 
 
    var srcX = 0; 
 
    var srcY = 0; 
 
    var srcWidth = destColumn; 
 
    var srcHeight = texHeight; 
 

 
    var dstX = texWidth - destColumn; 
 
    var dstY = 0; 
 
    var dstWidth = destColumn; 
 
    var dstHeight = texHeight; 
 

 
    var targetWidth = gl.canvas.width; 
 
    var targetHeight = gl.canvas.height; 
 

 
    drawImage(
 
     tex, texWidth, texHeight, 
 
     srcX, srcY, srcWidth, srcHeight, 
 
     dstX, dstY, dstWidth, dstHeight, 
 
     targetWidth, targetHeight); 
 
    } 
 

 
    function drawSecondPart() { 
 
    var srcX = destColumn; 
 
    var srcY = 0; 
 
    var srcWidth = texWidth - destColumn + 1; 
 
    var srcHeight = texHeight; 
 

 
    var dstX = 0; 
 
    var dstY = 0; 
 
    var dstWidth = texWidth - destColumn + 1; 
 
    var dstHeight = texHeight; 
 

 
    var targetWidth = gl.canvas.width; 
 
    var targetHeight = gl.canvas.height; 
 

 
    drawImage(
 
     tex, texWidth, texHeight, 
 
     srcX, srcY, srcWidth, srcHeight, 
 
     dstX, dstY, dstWidth, dstHeight, 
 
     targetWidth, targetHeight); 
 
    } 
 

 
    drawFirstPart(); 
 
    drawSecondPart(); 
 
    
 
    requestAnimationFrame(render); 
 
} 
 
render(); 
 
    
 
    
 
// ===================================================================== 
 
// Everything below this line represents stuff from the server. 
 
// so it's mostly irrelevant to the answer 
 
// this code just generates endless data 
 

 
var count = 0; 
 
var data; 
 

 
function getNextLineData() { 
 
    if (!data) { 
 
    data = new Uint8Array(texHeight); 
 
    } 
 
    
 
    ++count; 
 
    for (var ii = 0; ii < data.length; ++ii) { 
 
    data[ii] = 0; 
 
    } 
 
    addPoint(count, 0.010, 255, data); 
 
    addPoint(count, 0.031, 240, data); 
 
    addPoint(count, 0.023, 220, data); 
 
    addPoint(count, 0.013, 200, data); 
 
    
 
    return data; 
 
} 
 

 
function addPoint(count, mult, value, data) { 
 
    var s = Math.floor((Math.sin(count * mult) * 0.5 + 0.5) * (data.length - 1)); 
 
    data[s] = value; 
 
}
canvas { border: 1px solid red; }
<script src="https://twgljs.org/dist/twgl-full.min.js"></script> 
 
<script id="vs" type="not-js"> 
 
// we will always pass a 0 to 1 unit quad 
 
// and then use matrices to manipulate it 
 
attribute vec4 position; 
 

 
uniform mat4 matrix; 
 
uniform mat4 textureMatrix; 
 

 
varying vec2 texcoord; 
 

 
void main() { 
 
    gl_Position = matrix * position; 
 
    
 
    texcoord = (textureMatrix * position).xy; 
 
} 
 
</script> 
 
<script id="fs" type="not-js"> 
 
precision mediump float; 
 

 
varying vec2 texcoord; 
 
uniform sampler2D texture; 
 

 
void main() { 
 
    gl_FragColor = texture2D(texture, texcoord); 
 
} 
 
</script> 
 
<canvas id="c" width="500" height="150"></canvas>

+0

Я согласен с тем, что я задавал его много раз, но единственная причина для их принятия заключалась в том, что я шел шаг за шагом и в то же время понимал webgl в некоторой степени. Я не был уверен, что делать, поскольку у меня появилась еще одна идея, поэтому задайте вопрос на новый уровень.Старые вопросы могут помочь другому новичку, поэтому я не хочу их удалять – subhfyu546754

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