Перемещение окна просмотра в холсте webGL - PullRequest
0 голосов
/ 27 марта 2020

Я создаю игру, в которой пользователь использует клавиши WASD для перемещения окна просмотра, чтобы увидеть игровой мир. На данный момент отображаются только начальные спрайты в области просмотра. Я смог переместить область просмотра через gl.viewport (x, y, width, height), обновив его x и y, но когда я перехожу в область просмотра в другое пространство мира, экран становится черным, и должны быть спрайты. Нет ошибок в журнале и обновления вычисляются. Я очищал экран каждый рисунок и

private drawSprite( webGL : WebGLRenderingContext,
    viewport : Viewport, 
    sprite : AnimatedSprite) : void {

        let canvasWidth : number = webGL.canvas.width;
        let canvasHeight : number = webGL.canvas.height;
        let spriteType : AnimatedSpriteType = sprite.getSpriteType();
        let texture : WebGLGameTexture = spriteType.getSpriteSheetTexture();

        let spriteWidth : number = spriteType.getSpriteWidth();
        let spriteHeight : number = spriteType.getSpriteHeight();
        let spriteXInPixels : number = sprite.getPosition().getX() + (spriteWidth/2);
        let spriteYInPixels : number = sprite.getPosition().getY() + (spriteHeight/2);
        let spriteXTranslate : number = (spriteXInPixels - (canvasWidth/2))/(canvasWidth/2);
        let spriteYTranslate : number = (spriteYInPixels - (canvasHeight/2))/(canvasHeight/2);
        this.meshTranslate.setX(spriteXTranslate);
        this.meshTranslate.setY(-spriteYTranslate);

        let defaultWidth : number = canvasWidth;
        let defaultHeight : number = canvasHeight;
        let scaleX : number = 2*spriteWidth/defaultWidth;
        let scaleY : number = 2*spriteHeight/defaultHeight;
        this.meshScale.set(scaleX, scaleY, 0.0, 0.0);//1.0, 1.0);

        let rotation: Vector3 = sprite.getRotation()
        this.meshRotate.setThetaZ(rotation.getThetaZ())

        MathUtilities.identity(this.meshTransform);
        MathUtilities.model(this.meshTransform, this.meshTranslate, this.meshRotate, this.meshScale);

        // FIGURE OUT THE TEXTURE COORDINATE FACTOR AND SHIFT
        let texCoordFactorX : number = spriteWidth/texture.width;
        let texCoordFactorY : number = spriteHeight/texture.height;
        let spriteLeft : number = sprite.getLeft();
        let spriteTop : number = sprite.getTop();
        let texCoordShiftX : number = spriteLeft/texture.width;
        let texCoordShiftY : number = spriteTop/texture.height;

        webGL.bindBuffer(webGL.ARRAY_BUFFER, this.vertexDataBuffer);
        webGL.bindTexture(webGL.TEXTURE_2D, texture.webGLTexture);

        let a_PositionLocation : GLuint = this.webGLAttributeLocations.get(this.A_POSITION);
        webGL.vertexAttribPointer(a_PositionLocation, this.FLOATS_PER_TEXTURE_COORDINATE, webGL.FLOAT, false, this.TOTAL_BYTES, this.VERTEX_POSITION_OFFSET);
        webGL.enableVertexAttribArray(a_PositionLocation);
        let a_TexCoordLocation : GLuint = this.webGLAttributeLocations.get(this.A_TEX_COORD);
        webGL.vertexAttribPointer(a_TexCoordLocation, this.FLOATS_PER_TEXTURE_COORDINATE, webGL.FLOAT, false, this.TOTAL_BYTES, this.TEXTURE_COORDINATE_OFFSET);
        webGL.enableVertexAttribArray(a_TexCoordLocation);

        let u_MeshTransformLocation : WebGLUniformLocation = this.webGLUniformLocations.get(this.U_MESH_TRANSFORM);
        webGL.uniformMatrix4fv(u_MeshTransformLocation, false, this.meshTransform.getData());
        let u_SamplerLocation : WebGLUniformLocation = this.webGLUniformLocations.get(this.U_SAMPLER);
        webGL.uniform1i(u_SamplerLocation, texture.webGLTextureId);
        let u_TexCoordFactorLocation : WebGLUniformLocation = this.webGLUniformLocations.get(this.U_TEX_COORD_FACTOR);
        webGL.uniform2f(u_TexCoordFactorLocation, texCoordFactorX, texCoordFactorY);
        let u_TexCoordShiftLocation : WebGLUniformLocation = this.webGLUniformLocations.get(this.U_TEX_COORD_SHIFT);
        webGL.uniform2f(u_TexCoordShiftLocation, texCoordShiftX, texCoordShiftY);

        webGL.drawArrays(webGL.TRIANGLE_STRIP, this.INDEX_OF_FIRST_VERTEX, this.NUM_VERTICES);
}

Вершинный шейдер

uniform mat4 u_MeshTransform;
uniform vec2 u_TexCoordFactor;
uniform vec2 u_TexCoordShift;
attribute vec4 a_Position;
attribute vec2 a_TexCoord;
varying vec2 v_TexCoord;
void main() {
    gl_Position = u_MeshTransform * a_Position;
    vec2 tempTexCoord = a_TexCoord * u_TexCoordFactor;
    v_TexCoord = tempTexCoord + u_TexCoordShift;
}

FragShader

precision mediump float;

uniform sampler2D u_Sampler;
varying vec2 v_TexCoord;
void main() {
    gl_FragColor = texture2D(u_Sampler, v_TexCoord);
}

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

1 Ответ

1 голос
/ 27 марта 2020

gl.viewport только устанавливает преобразование из нормализованных координат устройства в пиксельное пространство. Это не поможет вам переместить представление.

Если вы хотите переместить представление вокруг, вы обычно добавляете матрицу представления либо в математике в Javascript, где вы вычисляете meshTransform, либо добавляя еще одна матрица для вашего шейдера

gl_Position = u_viewProjectionTransform * u_MeshTransform * a_Position;

или

gl_Position = u_projectionTransform * u_viewTransform * u_MeshTranform * a_Position;

Затем вы устанавливаете u_projectionTransform для своей проекции ( перспектива или орфография c) и вы установите u_viewTransform для своей камеры

...