Skip to content

Commit aa8f082

Browse files
committed
Resource clean up and adapted batches to allow shader swapping
1 parent 85a3830 commit aa8f082

34 files changed

Lines changed: 917 additions & 1168 deletions

v3/src/renderer/webgl/GL.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = (window.WebGLRenderingContext ? WebGLRenderingContext : {});
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
var Resources = require('./resources');
2+
var GL = require('./GL');
3+
4+
var ResourceManager = function (gl)
5+
{
6+
this.gl = gl;
7+
/* Maybe add pooling here */
8+
this.shaderCache = {};
9+
};
10+
11+
ResourceManager.prototype.constructor = ResourceManager;
12+
13+
ResourceManager.prototype = {
14+
15+
createRenderTarget: function (width, height, colorBuffer, depthStencilBuffer)
16+
{
17+
var gl = this.gl;
18+
var framebufferObject = gl.createFramebuffer();
19+
var depthStencilRenderbufferObject = null;
20+
var colorRenderbufferObject = null;
21+
var complete = 0;
22+
23+
gl.bindFramebuffer(GL.FRAMEBUFFER, framebufferObject)
24+
25+
if (depthStencilBuffer !== undefined && depthStencilBuffer !== null)
26+
{
27+
depthStencilBuffer.isRenderTexture = true;
28+
gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D, depthStencilBuffer.texture, depthStencilBuffer.mipLevel);
29+
}
30+
else
31+
{
32+
depthStencilRenderbufferObject = gl.createRenderbuffer();
33+
gl.bindRenderbuffer(GL.RENDERBUFFER, depthStencilRenderbufferObject);
34+
gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_STENCIL, width, height);
35+
gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, depthStencilRenderbufferObject);
36+
}
37+
38+
if (colorBuffer !== undefined && colorBuffer !== null)
39+
{
40+
colorBuffer.isRenderTexture = true;
41+
gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, colorBuffer.texture, colorBuffer.mipLevel);
42+
}
43+
else
44+
{
45+
colorRenderbufferObject = gl.createRenderbuffer();
46+
gl.bindRenderbuffer(GL.RENDERBUFFER, colorRenderbufferObject);
47+
gl.renderbufferStorage(GL.RENDERBUFFER, GL.RGBA4, width, height);
48+
gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.RENDERBUFFER, colorRenderbufferObject);
49+
}
50+
51+
complete = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
52+
53+
if (complete !== GL.FRAMEBUFFER_COMPLETE)
54+
{
55+
var errors = {
56+
36054: 'Incomplete Attachment',
57+
36055: 'Missing Attachment',
58+
36057: 'Incomplete Dimensions',
59+
36061: 'Framebuffer Unsupported'
60+
};
61+
62+
throw new Error('Framebuffer incomplete. Framebuffer status: ' + errors[complete]);
63+
}
64+
65+
gl.bindFramebuffer(GL.FRAMEBUFFER, null);
66+
67+
return new Resources.RenderTarget(
68+
framebufferObject,
69+
width, height,
70+
(colorBuffer === undefined ? null : colorBuffer),
71+
(depthStencilBuffer === undefined ? null : depthStencilBuffer)
72+
);
73+
},
74+
75+
createBuffer: function (target, initialDataOrSize, bufferUsage)
76+
{
77+
var gl = this.gl;
78+
var bufferObject = gl.createBuffer();
79+
gl.bindBuffer(target, bufferObject);
80+
gl.bufferData(target, initialDataOrSize, bufferUsage);
81+
82+
switch (target)
83+
{
84+
case GL.ARRAY_BUFFER:
85+
return new Resources.VertexBuffer(gl, bufferObject);
86+
case GL.ELEMENT_ARRAY_BUFFER:
87+
return new Resources.IndexBuffer(gl, bufferObject);
88+
default:
89+
throw new Error('Invalid Buffer Target');
90+
}
91+
92+
return null;
93+
},
94+
95+
createTexture: function (mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height)
96+
{
97+
var gl = this.gl;
98+
var texture = gl.createTexture();
99+
100+
gl.bindTexture(GL.TEXTURE_2D, texture);
101+
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, minFilter);
102+
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, magFilter);
103+
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, wrapS);
104+
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, wrapT);
105+
106+
if (pixels === null || pixels === undefined)
107+
{
108+
gl.texImage2D(GL.TEXTURE_2D, mipLevel, format, width, height, 0, format, GL.UNSIGNED_BYTE, null);
109+
}
110+
else
111+
{
112+
gl.texImage2D(GL.TEXTURE_2D, mipLevel, format, format, GL.UNSIGNED_BYTE, pixels);
113+
width = pixels.width;
114+
height = pixels.height;
115+
}
116+
117+
return new Resources.Texture(texture, width, height);
118+
},
119+
120+
createShader: function (shaderName, shaderSources)
121+
{
122+
if (!(shaderName in this.shaderCache))
123+
{
124+
var gl = this.gl;
125+
var program = gl.createProgram();
126+
var vertShader = gl.createShader(GL.VERTEX_SHADER);
127+
var fragShader = gl.createShader(GL.FRAGMENT_SHADER);
128+
var error;
129+
var shader;
130+
131+
gl.shaderSource(vertShader, shaderSources.vert);
132+
gl.shaderSource(fragShader, shaderSources.frag);
133+
134+
gl.compileShader(vertShader);
135+
gl.compileShader(fragShader);
136+
137+
error = gl.getShaderInfoLog(vertShader);
138+
139+
if (error.length > 0)
140+
{
141+
throw new Error('Vertex Shader Compilation Error.\n' + error);
142+
}
143+
144+
error = gl.getShaderInfoLog(fragShader);
145+
146+
if (error.length > 0)
147+
{
148+
throw new Error('Fragment Shader Compilation Error.\n' + error);
149+
}
150+
151+
gl.attachShader(program, vertShader);
152+
gl.attachShader(program, fragShader);
153+
gl.linkProgram(program);
154+
155+
error = gl.getProgramParameter(program, GL.LINK_STATUS);
156+
157+
if (error === 0)
158+
{
159+
error = gl.getProgramInfoLog(program);
160+
161+
throw new Error('Program Linking Error.\n' + error);
162+
}
163+
164+
shader = new Resources.Shader(shaderName, gl, program, vertShader, fragShader);
165+
this.shaderCache[shaderName] = shader;
166+
return shader;
167+
}
168+
else
169+
{
170+
return this.shaderCache[shaderName];
171+
}
172+
},
173+
174+
createOutputStage: function ()
175+
{
176+
var outputStage = new Resources.OutputStage();
177+
178+
outputStage.setDefaultDepthStencilState();
179+
outputStage.setNoBlending();
180+
181+
return outputStage;
182+
},
183+
184+
deleteShader: function (shader)
185+
{
186+
var storedShader = this.shaderCache[shader.name]
187+
var gl = this.gl;
188+
if (storedShader !== undefined)
189+
{
190+
delete this.shaderCache;
191+
}
192+
gl.deleteShader(shader.vertexShader);
193+
gl.deleteShader(shader.fragmentShader);
194+
gl.deleteProgram(shader.program);
195+
shader.vertexShader = null;
196+
shader.fragmentShader = null;
197+
shader.program = null;
198+
shader.name = null;
199+
},
200+
201+
deleteBuffer: function (buffer)
202+
{
203+
var gl = this.gl;
204+
205+
gl.deleteBuffer(buffer.bufferObject);
206+
}
207+
208+
};
209+
210+
module.exports = ResourceManager;

0 commit comments

Comments
 (0)