Created
April 23, 2022 03:47
-
-
Save sergeystoma/1b9bf7fce6e58ef8ae0f6a99a1c5a49f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// eslint-disable-next-line func-names, no-underscore-dangle | |
this.engine._readTexturePixelsSync = function (texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion) { | |
if (texture._hardwareTexture | |
&& texture._hardwareTexture.underlyingResource | |
&& texture._hardwareTexture.underlyingResource.__SPECTOR_Object_CustomData) { | |
const t = texture._hardwareTexture.underlyingResource; | |
// eslint-disable-next-line | |
console.log(`Exporting texture id ${t.__SPECTOR_Object_TAG.id}, format ${t.__SPECTOR_Object_CustomData.format}, compressed ${t.__SPECTOR_Object_CustomData.isCompressed}`); | |
} | |
if (faceIndex === 0) { | |
// eslint-disable-next-line no-param-reassign | |
faceIndex = -1; | |
} | |
if (level === 0) { | |
// eslint-disable-next-line no-param-reassign | |
level = 0; | |
} | |
if (buffer === 0) { | |
// eslint-disable-next-line no-param-reassign | |
buffer = null; | |
} | |
if (flushRenderer === 0) { | |
// eslint-disable-next-line no-param-reassign | |
flushRenderer = true; | |
} | |
if (noDataConversion === 0) { | |
// eslint-disable-next-line no-param-reassign | |
noDataConversion = false; | |
} | |
// eslint-disable-next-line no-underscore-dangle | |
const gl = this._gl; | |
if (!gl) { | |
throw new Error('Engine does not have gl rendering context.'); | |
} | |
if (flushRenderer) { | |
this.flushFramebuffer(); | |
} | |
// Make a new framebuffer texture. | |
const colorTarget = gl.createTexture(); | |
gl.bindTexture(gl.TEXTURE_2D, colorTarget); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); | |
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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); | |
// Setup new framebuffer instead of BJS dummy framebuffer since that may be used elsewhere. | |
const fb = gl.createFramebuffer(); | |
gl.bindFramebuffer(gl.FRAMEBUFFER, fb); | |
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTarget, 0); | |
// Old state. | |
const previousProgram = gl.getParameter(gl.CURRENT_PROGRAM); | |
const previousViewport = gl.getParameter(gl.VIEWPORT); | |
// Viewport. | |
gl.viewport(0, 0, width, height); | |
// Shaders. | |
const vertShaderSource = `#version 300 es | |
in vec2 aVertex; | |
in vec2 aTexture; | |
out vec2 vTexture; | |
void main(void) { | |
gl_Position = vec4(aVertex, 0.0, 1.0); | |
vTexture = aTexture; | |
} | |
`; | |
const fragShaderSource = `#version 300 es | |
precision mediump float; | |
in vec2 vTexture; | |
out vec4 fragmentColor; | |
uniform sampler2D uSampler; | |
void main(void) { | |
fragmentColor = texture(uSampler, vTexture); | |
} | |
`; | |
const vertShader = gl.createShader(gl.VERTEX_SHADER); | |
const fragShader = gl.createShader(gl.FRAGMENT_SHADER); | |
gl.shaderSource(vertShader, vertShaderSource); | |
gl.shaderSource(fragShader, fragShaderSource); | |
gl.compileShader(vertShader); | |
// const vertLog = gl.getShaderInfoLog(vertShader); | |
// // eslint-disable-next-line | |
// console.log(`Vertex shader: ${vertLog}`); | |
gl.compileShader(fragShader); | |
// const fragLog = gl.getShaderInfoLog(fragShader); | |
// // eslint-disable-next-line | |
// console.log(`Fragment shader: ${fragLog}`); | |
const program = gl.createProgram(); | |
gl.attachShader(program, vertShader); | |
gl.attachShader(program, fragShader); | |
gl.linkProgram(program); | |
gl.useProgram(program); | |
const vertLocation = gl.getAttribLocation(program, 'aVertex'); | |
const textLocation = gl.getAttribLocation(program, 'aTexture'); | |
const samplerLocation = gl.getUniformLocation(program, 'uSampler'); | |
// Quad. | |
const vertBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]), gl.STATIC_DRAW); | |
const textBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, textBuffer); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]), gl.STATIC_DRAW); | |
// Draw quad. | |
gl.enableVertexAttribArray(vertLocation); | |
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer); | |
gl.vertexAttribPointer(vertLocation, 2, gl.FLOAT, false, 0, 0); | |
gl.enableVertexAttribArray(textLocation); | |
gl.bindBuffer(gl.ARRAY_BUFFER, textBuffer); | |
gl.vertexAttribPointer(textLocation, 2, gl.FLOAT, false, 0, 0); | |
gl.activeTexture(gl.TEXTURE0); | |
gl.bindTexture(gl.TEXTURE_2D, texture._hardwareTexture == null ? null : texture._hardwareTexture.underlyingResource); | |
const magFilter = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER); | |
const minFilter = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_ANISOTROPY_EXT, 1); | |
gl.uniform1i(samplerLocation, 0); | |
gl.disable(gl.DEPTH_TEST); | |
gl.depthMask(false); | |
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); | |
gl.disableVertexAttribArray(vertLocation); | |
gl.disableVertexAttribArray(textLocation); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); | |
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); | |
// Get pixels. | |
const readBuffer = new Uint8Array(4 * width * height); | |
gl.flush(); | |
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuffer); | |
// Clean up. | |
gl.depthMask(true); | |
gl.deleteBuffer(vertBuffer); | |
gl.deleteBuffer(textBuffer); | |
gl.deleteShader(vertShader); | |
gl.deleteShader(fragShader); | |
gl.deleteProgram(program); | |
gl.deleteFramebuffer(fb); | |
gl.deleteTexture(colorTarget); | |
gl.useProgram(previousProgram); | |
gl.viewport(previousViewport[0], previousViewport[1], previousViewport[2], previousViewport[3]); | |
gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer); | |
return readBuffer; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment