claygl-next
Advanced tools
Comparing version 2.0.0-alpha.28 to 2.0.0-alpha.29
@@ -30,4 +30,2 @@ import { GLEnum } from '../core/type'; | ||
getProgramKey?(): string; | ||
beforeCompileShader?(): void; | ||
afterCompileShader?(): void; | ||
} | ||
@@ -115,2 +113,3 @@ /** | ||
private _viewport?; | ||
private _parallelShaderCompile?; | ||
throwError: boolean; | ||
@@ -120,2 +119,3 @@ maxJointNumber: number; | ||
throwError?: boolean; | ||
parallelShaderCompile?: boolean; | ||
}); | ||
@@ -141,4 +141,5 @@ setViewport(x: number, y: number, width: number, height: number, dpr: number): void; | ||
*/ | ||
render(list: GLRenderableObject[], renderHooks?: GLRenderHooks): void; | ||
render(list: GLRenderableObject[], renderHooks?: GLRenderHooks): boolean; | ||
private _updatePrograms; | ||
isAllProgramCompiled(): boolean; | ||
getWebGLExtension(extName: string): any; | ||
@@ -145,0 +146,0 @@ private _getGLTexture; |
@@ -40,5 +40,8 @@ import GLExtension from './GLExtension'; | ||
// Init managers | ||
this._programMgr = new ProgramManager(this); | ||
this._glext = new GLExtension(gl, gl.getSupportedExtensions() || []); | ||
this.throwError = optional(opts.throwError, true); | ||
if (opts.parallelShaderCompile) { | ||
this._parallelShaderCompile = this._glext.getExtension('KHR_parallel_shader_compile'); | ||
} | ||
this._programMgr = new ProgramManager(this, this._parallelShaderCompile || false); | ||
} | ||
@@ -119,2 +122,3 @@ setViewport(x, y, width, height, dpr) { | ||
let drawBuffersCount = 0; | ||
let unfinished = false; | ||
for (let i = 0; i < list.length; i++) { | ||
@@ -129,2 +133,6 @@ const renderable = list[i]; | ||
let program = renderable.__program; | ||
if (program.isCompiling()) { | ||
unfinished = true; | ||
continue; | ||
} | ||
// If has error in shader and program is invalid | ||
@@ -231,2 +239,3 @@ if (!program.isValid()) { | ||
} | ||
return unfinished; | ||
} | ||
@@ -257,2 +266,5 @@ _updatePrograms(list, renderHooks) { | ||
} | ||
isAllProgramCompiled() { | ||
return this._programMgr.isAllProgramCompiled(); | ||
} | ||
getWebGLExtension(extName) { | ||
@@ -259,0 +271,0 @@ return this._glext.getExtension(extName); |
@@ -14,6 +14,11 @@ import Shader, { AttributeSemantic, UniformType } from '../Shader'; | ||
private _valueCache; | ||
private _vertexShader?; | ||
private _fragmentShader?; | ||
__error?: string; | ||
__compiling?: boolean; | ||
constructor(); | ||
bind(gl: WebGL2RenderingContext): void; | ||
isValid(): boolean; | ||
isCompiling(): boolean | undefined; | ||
checkParallelCompiled(gl: WebGL2RenderingContext, parallelExt: any): boolean | undefined; | ||
hasUniform(symbol: string): boolean; | ||
@@ -30,4 +35,5 @@ useTextureSlot(gl: WebGL2RenderingContext, texture: GLTexture | undefined, slot: number): void; | ||
}): number; | ||
buildProgram(gl: WebGL2RenderingContext, shader: Shader, vertexShaderCode: string, fragmentShaderCode: string): string | undefined; | ||
buildProgram(gl: WebGL2RenderingContext, shader: Shader, vertexShaderCode: string, fragmentShaderCode: string): void; | ||
updateLinkStatus(gl: WebGL2RenderingContext): void; | ||
} | ||
export default GLProgram; |
@@ -16,3 +16,3 @@ import { assign, genGUID, isArray, keys } from '../core/util'; | ||
if (!_gl.getShaderParameter(shader, constants.COMPILE_STATUS)) { | ||
return [_gl.getShaderInfoLog(shader), addLineNumbers(shaderString)].join('\n'); | ||
return [addLineNumbers(shaderString), _gl.getShaderInfoLog(shader)].join('\n'); | ||
} | ||
@@ -42,4 +42,11 @@ } | ||
isValid() { | ||
return !!this._program; | ||
return !!this._program && !this.__compiling; | ||
} | ||
isCompiling() { | ||
return this.__compiling; | ||
} | ||
checkParallelCompiled(gl, parallelExt) { | ||
return (this._program && | ||
gl.getProgramParameter(this._program, parallelExt.COMPLETION_STATUS_KHR) == true); | ||
} | ||
hasUniform(symbol) { | ||
@@ -200,7 +207,19 @@ const location = this._uniformLocations[symbol]; | ||
gl.linkProgram(program); | ||
gl.deleteShader(vertexShader); | ||
gl.deleteShader(fragmentShader); | ||
// Save code. | ||
this.vertexCode = vertexShaderCode; | ||
this.fragmentCode = fragmentShaderCode; | ||
this._vertexShader = vertexShader; | ||
this._fragmentShader = fragmentShader; | ||
this._program = program; | ||
} | ||
updateLinkStatus(gl) { | ||
const program = this._program; | ||
const vertexShader = this._vertexShader; | ||
const fragmentShader = this._fragmentShader; | ||
const vertexShaderCode = this.vertexCode; | ||
const fragmentShaderCode = this.fragmentCode; | ||
if (!program) { | ||
return; | ||
} | ||
let errMsg = ''; | ||
if (!gl.getProgramParameter(program, constants.LINK_STATUS)) { | ||
@@ -211,11 +230,18 @@ // Only check after linked | ||
if (msg) { | ||
return msg; | ||
errMsg = msg; | ||
} | ||
msg = checkShaderErrorMsg(gl, fragmentShader, fragmentShaderCode); | ||
if (msg) { | ||
return msg; | ||
if (!errMsg) { | ||
msg = checkShaderErrorMsg(gl, fragmentShader, fragmentShaderCode); | ||
if (msg) { | ||
errMsg = msg; | ||
} | ||
} | ||
return 'Could not link program\n' + gl.getProgramInfoLog(program); | ||
if (!errMsg) { | ||
errMsg = 'Could not link program\n' + gl.getProgramInfoLog(program); | ||
} | ||
} | ||
this._program = program; | ||
this.__error = errMsg; | ||
gl.deleteShader(vertexShader); | ||
gl.deleteShader(fragmentShader); | ||
this._vertexShader = this._fragmentShader = undefined; | ||
// Cache uniform locations | ||
@@ -232,2 +258,3 @@ const numUniforms = gl.getProgramParameter(program, constants.ACTIVE_UNIFORMS); | ||
} | ||
this.__compiling = false; | ||
} | ||
@@ -234,0 +261,0 @@ } |
@@ -8,5 +8,7 @@ import { ShaderDefineValue } from '../Shader'; | ||
private _cache; | ||
constructor(renderer: GLPipeline); | ||
private _parallelExt; | ||
constructor(renderer: GLPipeline, parallelExt: any); | ||
getProgram(renderable: GLRenderableObject, material: GLMaterialObject, extraKey: string, extraDefines?: Record<string, ShaderDefineValue>): GLProgram; | ||
isAllProgramCompiled(): boolean; | ||
} | ||
export default ProgramManager; |
@@ -101,5 +101,6 @@ import { keys } from '../core/util'; | ||
class ProgramManager { | ||
constructor(renderer) { | ||
constructor(renderer, parallelExt) { | ||
this._cache = {}; | ||
this._pipeline = renderer; | ||
this._parallelExt = parallelExt; | ||
} | ||
@@ -109,2 +110,4 @@ getProgram(renderable, material, extraKey, extraDefines) { | ||
const renderer = this._pipeline; | ||
const parallelExt = this._parallelExt; | ||
const _gl = renderer.gl; | ||
const isSkinnedMesh = renderable.isSkinnedMesh && renderable.isSkinnedMesh(); | ||
@@ -133,6 +136,10 @@ const isInstancedMesh = renderable.isInstancedMesh && renderable.isInstancedMesh(); | ||
if (program) { | ||
if (program.__compiling) { | ||
// Check compiling status | ||
if (program.checkParallelCompiled(_gl, parallelExt)) { | ||
program.updateLinkStatus(_gl); | ||
} | ||
} | ||
return program; | ||
} | ||
material.beforeCompileShader && material.beforeCompileShader(); | ||
const _gl = renderer.gl; | ||
let commonDefineCode = ''; | ||
@@ -174,10 +181,33 @@ if (isSkinnedMesh) { | ||
program.attributes = shader.attributes; | ||
const errorMsg = program.buildProgram(_gl, shader, finalVertexCode, finalFragmentCode); | ||
program.__error = errorMsg; | ||
program.buildProgram(_gl, shader, finalVertexCode, finalFragmentCode); | ||
if (parallelExt) { | ||
program.__compiling = true; | ||
} | ||
else { | ||
program.updateLinkStatus(_gl); | ||
} | ||
cache[key] = program; | ||
material.afterCompileShader && material.afterCompileShader(); | ||
return program; | ||
} | ||
isAllProgramCompiled() { | ||
if (!this._parallelExt) { | ||
return true; | ||
} | ||
const cache = this._cache; | ||
const gl = this._pipeline.gl; | ||
for (const key in cache) { | ||
const program = cache[key]; | ||
if (program.__compiling) { | ||
if (program.checkParallelCompiled(gl, this._parallelExt)) { | ||
program.updateLinkStatus(gl); | ||
} | ||
else { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
export default ProgramManager; | ||
//# sourceMappingURL=ProgramManager.js.map |
@@ -52,4 +52,2 @@ import Shader, { ShaderDefineValue, ShaderPrecision, ShaderType, VertexShader, FragmentShader, UniformType } from './Shader'; | ||
interface Material extends Omit<MaterialOpts, 'shader'> { | ||
beforeCompileShader?(): void; | ||
afterCompileShader?(): void; | ||
} | ||
@@ -56,0 +54,0 @@ /** |
@@ -94,2 +94,6 @@ import Notifier from './core/Notifier'; | ||
throwError: boolean; | ||
/** | ||
* If use parallel shader compile. | ||
*/ | ||
parallelShaderCompile: boolean; | ||
} | ||
@@ -206,2 +210,3 @@ interface Renderer extends Pick<RendererOpts, 'canvas' | 'clearColor' | 'clearBit' | 'logDepthBuffer'> { | ||
getWebGLExtension(name: string): any; | ||
isAllProgramCompiled(): boolean; | ||
/** | ||
@@ -227,3 +232,3 @@ * Render the scene in camera to the screen or binded offline framebuffer | ||
filter?: (renderable: Renderable) => boolean; | ||
}): void; | ||
}): boolean | undefined; | ||
/** | ||
@@ -236,3 +241,3 @@ * Render a single pass. | ||
*/ | ||
renderPass(list: GLRenderableObject<Material>[], camera?: Camera, frameBuffer?: FrameBuffer, renderHooks?: RenderHooks, scene?: Scene): void; | ||
renderPass(list: GLRenderableObject<Material>[], camera?: Camera, frameBuffer?: FrameBuffer, renderHooks?: RenderHooks, scene?: Scene): boolean; | ||
/** | ||
@@ -239,0 +244,0 @@ * Bind frame buffer manually. |
@@ -51,3 +51,4 @@ // TODO Resources like shader, texture, geometry reference management | ||
this._glPipeline = new GLPipeline(gl, { | ||
throwError: opts.throwError | ||
throwError: opts.throwError, | ||
parallelShaderCompile: opts.parallelShaderCompile | ||
}); | ||
@@ -185,2 +186,5 @@ this._width = opts.width || canvas.width || 100; | ||
} | ||
isAllProgramCompiled() { | ||
return this._glPipeline.isAllProgramCompiled(); | ||
} | ||
/** | ||
@@ -251,2 +255,3 @@ * Render the scene in camera to the screen or binded offline framebuffer | ||
} | ||
let unfinished = false; | ||
// Render skybox before anyother objects | ||
@@ -256,15 +261,20 @@ const skybox = scene.skybox; | ||
skybox.update(); | ||
this._renderPass([skybox], camera, frameBuffer); | ||
unfinished = unfinished || this._renderPass([skybox], camera, frameBuffer); | ||
} | ||
// Render opaque list | ||
this._renderPass(opaqueList, camera, frameBuffer, { | ||
getMaterial, | ||
sortCompare: Renderer.opaqueSortCompare, | ||
filter: opts.filter | ||
}, scene); | ||
this._renderPass(transparentList, camera, frameBuffer, { | ||
getMaterial, | ||
sortCompare: Renderer.transparentSortCompare, | ||
filter: opts.filter | ||
}, scene); | ||
unfinished = | ||
unfinished || | ||
this._renderPass(opaqueList, camera, frameBuffer, { | ||
getMaterial, | ||
sortCompare: Renderer.opaqueSortCompare, | ||
filter: opts.filter | ||
}, scene); | ||
unfinished = | ||
unfinished || | ||
this._renderPass(transparentList, camera, frameBuffer, { | ||
getMaterial, | ||
sortCompare: Renderer.transparentSortCompare, | ||
filter: opts.filter | ||
}, scene); | ||
return unfinished; | ||
} | ||
@@ -280,3 +290,3 @@ /** | ||
this._bindFrameBuffer(frameBuffer); | ||
this._renderPass(list, camera, frameBuffer, renderHooks, scene); | ||
return this._renderPass(list, camera, frameBuffer, renderHooks, scene); | ||
} | ||
@@ -416,4 +426,5 @@ /** | ||
renderHooks && renderHooks.prepare && renderHooks.prepare(gl); | ||
this._glPipeline.render(list, assign(renderHooksForScene, renderHooks)); | ||
const unfinished = this._glPipeline.render(list, assign(renderHooksForScene, renderHooks)); | ||
renderHooks && renderHooks.cleanup && renderHooks.cleanup(gl); | ||
return unfinished; | ||
} | ||
@@ -420,0 +431,0 @@ getMaxJointNumber() { |
{ | ||
"name": "claygl-next", | ||
"version": "2.0.0-alpha.28", | ||
"version": "2.0.0-alpha.29", | ||
"description": "A 3D graphic library", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7000611
106234