без GL
https://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differencesgl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(this.gl.TEXTURE_2D, ..., image)
gl.uniform1i(gl.getUniformLocation('u_image'), 0);
setState(arg1)
setState(arg1, arg2)
setState(arg1, ..., arg9)
// but you can't
let state = getState()
const texture = gl.createTexture()
const canvas = document.createElement('canvas')
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, ..., canvas)
const texture = gl.createTexture()
const canvas = document.createElement('canvas')
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, ..., canvas)
const texture = gl.createTexture()
const canvas = document.createElement('canvas')
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, ..., canvas)
uniform sampler2D u_background;
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_background, v_texCoord);
}
const texture = gl.createTexture()
const canvas = document.createElement('canvas')
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, ..., canvas)
// получаем ссылки на сэмплеры
var u_image0 = gl.getUniformLocation(program, "u_image0")
var u_image1 = gl.getUniformLocation(program, "u_image1")
// задаём, какой текстурный блок использовать при рендеринге
gl.uniform1i(u_image0, 0)
gl.uniform1i(u_image1, 1)
// привязываем текстуру к текстурному блоку
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, textures[0])
gl.activeTexture(gl.TEXTURE1)
gl.bindTexture(gl.TEXTURE_2D, textures[1])
const textures = []
function addTexture(canvas, name) {
const texture = gl.createTexture()
const location = gl.getUniformLocation(program, name)
textures.push({texture, canvas, location})
}
textures.forEach(({texture, canvas, location}, i) => {
gl.activeTexture(gl[`TEXTURE${i}`])
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(this.gl.TEXTURE_2D, ..., canvas)
gl.uniform1i(location, i);
})
textures.forEach(({texture, canvas, location}, i) => {
gl.activeTexture(gl[`TEXTURE${i}`])
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(this.gl.TEXTURE_2D, ..., canvas)
gl.uniform1i(location, i);
})
textures.forEach(({texture, canvas, location}, i) => {
gl.activeTexture(gl[`TEXTURE${i}`])
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(this.gl.TEXTURE_2D, ..., canvas)
gl.uniform1i(location, i);
})
uniform sampler2D u_background;
uniform sampler2D u_foreground;
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_background, v_texCoord)
+ texture2D(u_foreground, v_texCoord);
}
rules: [
...
{
test: /\.frag?$/,
use: 'raw-loader',
}]
import * as fragmentShader from './shader.frag'
import * as vertexShader from './shader.vert'
const shaders = [vertexShader, fragmentShader]
const program = createProgramFromSources(gl, shaders)
<Container>
{state.enemies.map(e => (<Enemy {...e}/>))}
{state.explosions.map(e => (<Explosion {...e}/>))}
<Actor {...state.hero}/>
<Header x={0} y={0} text={state.kills}/>
<Container>
<Clickable onClick={_=>this.setState({screen: 'game'})}>
<Text text="Играть" />
</Clickable>
{this.renderScreen(this.state.screen)}
const OPTIONS = {
backgroundColor: color('#12bcf6'),
autoResize: true,
resolution: window.devicePixelRatio || 1,
};
<Button width={clamp(props.width * .6, 100, 200)}>
Button {
width: 60%;
min-width: 100px;
max-width: 200px;
}
Рендерится в растр, потому растягиваем его в 2 раза
<svg width="100" height="100"
viewBox="0 0 50 50" ... >
...
</svg>
componentDidMount() {
this.props.app.ticker.add(this.onTick);
}
onTick() {
this.setState({enemies, actor, time...})
}
import {CustomPIXIComponent} from 'react-pixi-fiber';
import Viewport from 'pixi-viewport';
const TYPE = 'Viewport';
const behavior = {
customDisplayObject: props => {
return new Viewport({
screenWidth: props.app.renderer.width,
screenHeight: props.app.renderer.height,
worldWidth: 1000,
worldHeight: 1000,
})
},
};
export default CustomPIXIComponent(behavior, TYPE);
<Viewport app={app}>
{/* add display objects here */}
</Viewport>
<MountainsViewport app={app}>
<Mountains />
</MountainsViewport>
<PlatformsViewport app={app}>
{platforms.map(p => (<Platform {...p}/>))
</PlatformsViewport>
<ActorViewport app={app}>
<Actor />
</ActorViewport>