Weitere ähnliche Inhalte
Ähnlich wie Bs webgl소모임004 (20)
Kürzlich hochgeladen (20)
Bs webgl소모임004
- 3. ProjectBS – WebGL 소모임
TODO LIST!
1. 초기화!
2. 쉐이더파서!
3. 버퍼생성기!
4. 텍스쳐생성기!
5. 메쉬구조체!
6. 재질구조체!
7. 루프관리!
8. 렌더러!
- 4. ProjectBS – WebGL 소모임
원하는 API
bsGL.init(
'canvas‘ , // ID or Canvas Object
function(){
console.log('초기화!')
// Host Code
},
‘쉐이더.js','확장.js‘
)
- 5. bsGL.init(
'canvas‘ , // ID or Canvas Object
function(){
console.log('초기화!')
// Host Code
},
‘쉐이더.js','확장.js‘
)
ProjectBS – WebGL 소모임
Gl객체 찾기
확장,
쉐이더.js
로딩 / 파싱
호스트 실행
초기화를 하면?
- 6. var bsGL = (function () {
var W = window, DOC = document, HEAD = DOC.getElementsByTagName('head')[0];
var API = {
gl: null, cvs: null,
VBOS: {}, UVBOS: {}, IBOS: {}, // 버퍼관리용 공간
PROGRAMS: {}, TEXTURES: {}, // 프로그램 텍스쳐 공간
LOOPS: {}, // 루프를 관리할 공간
SHADER_SOURCES: {}, // 파싱된 쉐이더를 관리할 공간
children: [], // 루트의 자식객체를 관리할 공간
init: function ($cvs, $func) {
// 먼가 실행
}
}
return API
})();
ProjectBS – WebGL 소모임
가볍게 엔진구조체 생각!
bsGL.init(~~~)
bsGL.children.push(~~~)
- 7. ProjectBS – WebGL 소모임
bsGL.init 구현!
init: function ($cvs, $func) {
var script, list = arguments, i = list.length - 1
load(list[i])
function load($src) {
script ? (script.onload = null, HEAD.removeChild(script)) : 0
script = DOC.createElement('script')
script.type = 'text/javascript', script.charset = 'utf-8', script.src = $src
if (i == 2) script.onload = function () {
script.onload = null, HEAD.removeChild(script)
// 호스트 실행 전 우리가 필요한 것들을 한다!
// context3d를 얻어야겠고…
// 엔진에 기본적으로 필요한 주요버퍼와 프로그램을 미리생성한다!
$func() // 호스트 실행!
}
else script.onload = function () {
load(list[i])
}
HEAD.appendChild(script)
i--
}
}
- 8. ProjectBS – WebGL 소모임
호스트 실행전 준비!
if (i == 2) script.onload = function () {
script.onload = null, HEAD.removeChild(script)
API.getGL($cvs)
API.setBase()
$func();
(function animloop() {
for (var k in API.LOOPS) API.LOOPS[k]()
API.render()
requestAnimFrame(animloop)
})()
}
var bsGL = (function () {
var API = {
…
…
render: function () {},
setBase: function () {}
}
return API
})();
- 9. ProjectBS – WebGL 소모임
getGL 구현
getGL: function ($cvs) {
var cvs = typeof $cvs == 'string' ? DOC.getElementById($cvs) : $cvs;
var keys = 'webgl,experimental-webgl,webkit-3d,moz-webgl'.split(','), i = keys.length
while (i--) if (gl = cvs.getContext(keys[i])) break
console.log(gl ? 'webgl 초기화 성공!' : console.log('webgl 초기화 실패!!'))
API.gl = gl, API.cvs = cvs
}
- 10. ProjectBS – WebGL 소모임
setBase 구현
1. Rect와 관련된 버퍼를 생성한다!
2. 쉐이더.js를 해석해서 쉐이더 & 프로그램을
만든다.
bsGL.setBase = function () {
var data = [-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, 0.0 ]
var index = [0, 1, 2, 1, 2, 3]
var uv = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]
bsGL.makeBuffer('VBOS', 'rect', data, 3)
bsGL.makeBuffer('IBOS', 'rect', index, 1)
bsGL.makeBuffer('UVBOS', 'rect', uv, 2)
bsGL.makeBuffer('VBOS', 'null', [-0.5, -0.5, 0.0], 3)
bsGL.shaderParser()
}
- 11. ProjectBS – WebGL 소모임
makeBuffer 구현
bsGL.makeBuffer = function ($type, $name, $data, $itemSize, $drawType) {
var gl = bsGL.gl
// $type : IBOS….
var buffer = bsGL[$type][$name], bufferType, arrayType
if (buffer) return buffer
buffer = gl.createBuffer()
bufferType = $type == 'IBOS' ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER
arrayType = $type == 'IBOS' ? Uint16Array : Float32Array
gl.bindBuffer(bufferType, buffer)
gl.bufferData(bufferType, new arrayType($data), $drawType ? $drawType : gl.STATIC_DRAW)
buffer.name = $name, buffer.type = $type
buffer.itemSize = $itemSize
buffer.numItem = $data.length / $itemSize
bsGL[$type][$name] = buffer
console.log(bsGL[$type][$name])
}
Ex.js
- 12. ProjectBS – WebGL 소모임
Shader 소스 구조체!
bsGL.SHADER_SOURCES['color'] = {
vertex: "n",
fragment: "n",
attribs: 'aVertexPosition', // 사용한 버퍼
uniforms: 'uPixelMatrix,uRotation,uPosition,uScale,uColor' // 사용한 유니폼
}
shader.js
- 13. ProjectBS – WebGL 소모임
Shader Parser 구현!
bsGL.shaderParser = function () {
var gl = bsGL.gl, vShader, fShader, program
for (var k in bsGL.SHADER_SOURCES) {
var t = bsGL.SHADER_SOURCES[k]
vShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vShader, t.vertex), gl.compileShader(vShader)
fShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fShader, t.fragment), gl.compileShader(fShader)
program = gl.createProgram()
gl.attachShader(program, vShader), gl.attachShader(program, fShader)
gl.linkProgram(program)
vShader.name = k + '_vertex', fShader.name = k + '_fragment',
program.name = k
bsGL.PROGRAMS[k] = program
console.log(vShader), console.log(fShader), console.log(program)
}
} Ex.js
- 14. bsGL.shaderParser = function () {
var gl = bsGL.gl, vShader, fShader, program
for (var k in bsGL.SHADER_SOURCES) {
var t = bsGL.SHADER_SOURCES[k]
vShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vShader, t.vertex), gl.compileShader(vShader)
fShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fShader, t.fragment), gl.compileShader(fShader)
program = gl.createProgram()
gl.attachShader(program, vShader), gl.attachShader(program, fShader)
gl.linkProgram(program)
vShader.name = k + '_vertex', fShader.name = k + '_fragment',
program.name = k
bsGL.PROGRAMS[k] = program
console.log(vShader), console.log(fShader), console.log(program)
}
}
ProjectBS – WebGL 소모임
Shader Parser 구현!
- 15. var gl = bsGL.gl, vShader, fShader, program
for (var k in bsGL.SHADER_SOURCES) {
…
gl.useProgram(program)
var i = 0, list = t.attribs.split(','), max = list.length, key
for (i; i < max; i++) {
key = list[i]
program[key] = gl.getAttribLocation(program, key);
gl.bindBuffer(gl.ARRAY_BUFFER, bsGL.VBOS['null'])
gl.vertexAttribPointer(program[key], bsGL.VBOS['null'].itemSize, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(program[key]);
}
list = t.uniforms.split(','), max = list.length
for (i = 0; i < max; i++) {
key = list[i]
program[key] = gl.getUniformLocation(program, key);
}
bsGL.PROGRAMS[k] = program
}
ProjectBS – WebGL 소모임
Shader Parser 구현2!
Ex.js
- 16. bsGL.makeBuffer = function ($type, $name, $data, $itemSize, $drawType) {
var gl = bsGL.gl
// $type : IBOS, ....
var buffer = bsGL[$type][$name], bufferType, arrayType
if (buffer) return buffer
buffer = gl.createBuffer()
bufferType = $type == 'IBOS' ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER
arrayType = $type == 'IBOS' ? Uint16Array : Float32Array
gl.bindBuffer(bufferType, buffer)
gl.bufferData(bufferType, new arrayType($data), $drawType ? $drawType : gl.STATIC_DRAW)
buffer.name = $name, buffer.type = $type
buffer.itemSize = $itemSize, buffer.numItem = $data.length / $itemSize
bsGL[$type][$name] = buffer
}
ProjectBS – WebGL 소모임
bsGL.MakeBuffer() 구현
- 17. bsGL.makeBuffer = function ($type, $name, $data, $itemSize, $drawType) {
var gl = bsGL.gl
// $type : IBOS, ....
var buffer = bsGL[$type][$name], bufferType, arrayType
if (buffer) return buffer
buffer = gl.createBuffer()
bufferType = $type == 'IBOS' ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER
arrayType = $type == 'IBOS' ? Uint16Array : Float32Array
gl.bindBuffer(bufferType, buffer)
gl.bufferData(bufferType, new arrayType($data), $drawType ? $drawType : gl.STATIC_DRAW)
buffer.name = $name, buffer.type = $type
buffer.itemSize = $itemSize, buffer.numItem = $data.length / $itemSize
bsGL[$type][$name] = buffer
}
ProjectBS – WebGL 소모임
bsGL.MakeBuffer() 구현
- 18. ProjectBS – WebGL 소모임
더 필요한건?
1. 초기화! – 대충완료 -_-?
2. 쉐이더파서! - 대충완료
3. 버퍼생성기! - 대충완료
4. 텍스쳐생성기!
5. 메쉬구조체!
6. 재질구조체!
7. 렌더러!
- 19. bsGL.makeTexture = function ($src) {
var gl = bsGL.gl
var texture = bsGL.TEXTURES[$src]
if (texture) return texture
texture = gl.createTexture()
texture.img = new Image()
texture.img.src = $src
texture.loaded = 0
texture.img.onload = function () {
texture.loaded = 1
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.img);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.generateMipmap(gl.TEXTURE_2D)
gl.bindTexture(gl.TEXTURE_2D, null)
}
bsGL.TEXTURES[$src] = texture
return texture
}
ProjectBS – WebGL 소모임
bsGL.makeTexture() 구현
Ex.js
- 20. bsGL.Material = function ($type) {
var result
switch ($type) {
case 'color' :
result = new Float32Array([Math.random(), Math.random(), Math.random()])
result.program = bsGL.PROGRAMS['color']
break
case 'bitmap' :
result = bsGL.makeTexture(arguments[1])
result.program = bsGL.PROGRAMS['bitmap']
break
}
return result
}
ProjectBS – WebGL 소모임
bsGL.Material() 구현
bsGL.Material('bitmap','test.png')
Ex.js
- 21. bsGL.Mesh = function () {
var result = {
vbo: bsGL.VBOS['rect'],
ibo: bsGL.IBOS['rect'],
uvbo: bsGL.UVBOS['rect'],
position: new Float32Array([0, 0, 0]),
rotation: new Float32Array([0, 0, 0]),
scale: new Float32Array([100, 100, 1]),
alpha: 1,
material: new bsGL.Material('color'),
children: []
}
return result
}
ProjectBS – WebGL 소모임
bsGL.Mesh() 구현
Ex.js
- 23. ProjectBS – WebGL 소모임
Draw(Root.children)
child1
child2
…
Draw(child1.children)
Draw(child2.children)
가장 기초적인 렌더방식으로! – 1Object
1DrawCall
- 24. ProjectBS – WebGL 소모임
bsGL.render = function () {
var gl = bsGL.gl
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.enable(gl.BLEND), gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
// 전체프로그램 공용 유니폼은 1번만 세팅한다!
for (var k in bsGL.PROGRAMS) {
var tProgram = bsGL.PROGRAMS[k]
gl.useProgram(tProgram)
gl.uniformMatrix4fv(tProgram.uPixelMatrix, false, bsGL.uPixelMatrix)
}
prevVBO = prevUVBO = prevIBO = render = 0
draw(bsGL.children)
}
bsGL.render() 변경!
- 25. ProjectBS – WebGL 소모임
bsGL.render = function () {
var gl = bsGL.gl
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.enable(gl.BLEND), gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
// 전체프로그램 공용 유니폼은 1번만 세팅한다!
for (var k in bsGL.PROGRAMS) {
var tProgram = bsGL.PROGRAMS[k]
gl.useProgram(tProgram)
gl.uniformMatrix4fv(tProgram.uPixelMatrix, false, bsGL.uPixelMatrix)
}
prevVBO = prevUVBO = prevIBO = render = 0
draw(bsGL.children)
}
bsGL.render() 변경!
- 26. ProjectBS – WebGL 소모임
function draw($list) {
var gl = bsGL.gl
var i = $list.length
var tObject, tProgram, tVBO, tIBO, tUVBO, tMaterial;
while (i--) {
render = 0,
tObject = $list[i],tMaterial=tObject.material
tVBO = tObject.vbo, tIBO = tObject.ibo, tUVBO = tObject.uvbo,
gl.useProgram(tProgram = tMaterial.program),
gl.uniform3fv(tProgram.uRotation, tObject.rotation),
gl.uniform3fv(tProgram.uPosition, tObject.position),
gl.uniform3fv(tProgram.uScale, tObject.scale)
gl.bindBuffer(gl.ARRAY_BUFFER, tVBO),
gl.vertexAttribPointer(tProgram.aVertexPosition, tVBO.itemSize, gl.FLOAT, false, 0, 0);
bsGL.draw() 구현
- 27. ProjectBS – WebGL 소모임
switch (tProgram.name) {
case 'bitmap' :
if (tMaterial.loaded) {
gl.bindBuffer(gl.ARRAY_BUFFER, tUVBO);
gl.vertexAttribPointer(tProgram.aUV, tUVBO.itemSize, gl.FLOAT, false, 0, 0);
gl.bindTexture(gl.TEXTURE_2D, tMaterial), gl.uniform1i(tProgram.uSampler, 0)
render = 1
}
break
case 'color' :
gl.uniform3fv(tProgram.uColor, tMaterial), render = 1
break
}
if (render) {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tIBO)
gl.drawElements(gl.TRIANGLES, tIBO.numItem, gl.UNSIGNED_SHORT, 0)
}
tObject.children.length > 0 ? draw(tObject.children) : 0
bsGL.draw() 구현
- 28. ProjectBS – WebGL 소모임
bsGL.init('canvas', function () {
for (var i = 0; i < 500; i++) {
var test = bsGL.Mesh()
bsGL.children.push(test)
test.position[0] = Math.random() * 1920 - 960
test.position[1] = Math.random() * 1920 - 960
var s = Math.random() * 100
test.scale = [s, s, 1]
if (i % 5 == 0) {
test.material = bsGL.Material('bitmap', 'test.png')
}
}
bsGL.LOOPS['loopTest'] = function () {
for (var i = 0; i < 500; i++) {
bsGL.children[i].rotation[2] += 0.1
}
}
}, 'shader.js', 'ex.js')
Host Code