slide bar
This commit is contained in:
parent
9922846acc
commit
515537ea68
24
index.css
24
index.css
@ -12,3 +12,27 @@ body{
|
||||
left: 0;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#drawer-button{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
position: fixed;
|
||||
background-color: rgb(0, 0, 0,0.5);
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#drawer{
|
||||
position: fixed;
|
||||
width: 350px;
|
||||
height: calc(90vh - 70px);
|
||||
top: 70px;
|
||||
right: -380px;
|
||||
transition: right 0.4s ease;
|
||||
background-color: white;
|
||||
box-shadow: black 5px 5px 10px 0px;
|
||||
border-radius: 5px;
|
||||
padding: 15px;
|
||||
}
|
10
index.html
10
index.html
@ -5,9 +5,17 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<script src="./index.ts" defer></script>
|
||||
<script src="./index.tsx" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="500" height="500"></canvas>
|
||||
<div id="drawer-button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-list" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="drawer">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
95
index.ts
95
index.ts
@ -1,95 +0,0 @@
|
||||
/// <reference path="node_modules/webgl-strict-types/index.d.ts" />
|
||||
import {createProgramFromSource, ProgramError, ShaderError} from "./src/gl_util";
|
||||
|
||||
/// <reference path="./src/glsl.d.ts" />
|
||||
import vert_src from "./src/vertex";
|
||||
import frag_src from "./src/fragment";
|
||||
|
||||
function findCanvas(){
|
||||
const canvas = document.querySelector("canvas");
|
||||
if(canvas === null){
|
||||
console.error("couldn't find canvas");
|
||||
throw new Error("canvas is null");
|
||||
}
|
||||
return canvas;
|
||||
}
|
||||
|
||||
function getGLContext(canvas : HTMLCanvasElement){
|
||||
const gl = canvas.getContext("webgl2") as any as WebGL2RenderingContextStrict|null;
|
||||
if(gl === null){
|
||||
console.error("webgl2 is not supported!");
|
||||
throw new Error("webgl2 not supported");
|
||||
}
|
||||
return gl;
|
||||
}
|
||||
|
||||
class Renderer{
|
||||
gl : WebGL2RenderingContextStrict;
|
||||
constructor(gl: WebGL2RenderingContextStrict){
|
||||
this.gl = gl;
|
||||
}
|
||||
init(){
|
||||
const gl = this.gl;
|
||||
let program: WebGLProgram;
|
||||
try{
|
||||
program = createProgramFromSource(gl,vert_src,frag_src);
|
||||
gl.useProgram(program);
|
||||
}
|
||||
catch(e){
|
||||
if(e instanceof ShaderError){
|
||||
console.log(e.message,"\n",e.info);
|
||||
}
|
||||
else if(e instanceof ProgramError){
|
||||
console.log(e.message,"\n",e.info);
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
const position = [
|
||||
-0.5,-0.5,
|
||||
0.5,-0.5,
|
||||
0.5,0.5,
|
||||
-0.5,0.5
|
||||
];
|
||||
const index = [
|
||||
0,1,2,
|
||||
2,3,0
|
||||
];
|
||||
const positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(position),gl.STATIC_DRAW);
|
||||
|
||||
const indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(index),gl.STATIC_DRAW);
|
||||
|
||||
let location = gl.getUniformLocation(program, "u_color"); //u_color 변수 위치를 참조
|
||||
gl.uniform4f(location, 0.8, 0.3, 0.8, 1.0); //해당 위치에 0.2, 0.3, 0.8, 1.0 데이터를 전달
|
||||
|
||||
}
|
||||
draw(){
|
||||
const gl = this.gl;
|
||||
gl.viewport(0,0,gl.canvas.width,gl.canvas.height);
|
||||
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0,2,gl.FLOAT,false,0,0);
|
||||
|
||||
gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,0);
|
||||
}
|
||||
}
|
||||
|
||||
function main(){
|
||||
const canvas = findCanvas();
|
||||
const gl = getGLContext(canvas);
|
||||
const renderer = new Renderer(gl);
|
||||
renderer.init()
|
||||
window.addEventListener("resize",(e)=>{
|
||||
e.preventDefault();
|
||||
canvas.width = document.body.clientWidth;
|
||||
canvas.height = document.body.clientHeight;
|
||||
renderer.draw();
|
||||
});
|
||||
canvas.width = document.body.clientWidth;
|
||||
canvas.height = document.body.clientHeight;
|
||||
renderer.draw();
|
||||
}
|
||||
main();
|
60
index.tsx
Normal file
60
index.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { Renderer } from './src/renderer';
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { MenuBar } from "./src/menu";
|
||||
|
||||
function findCanvas(){
|
||||
const canvas = document.querySelector("canvas");
|
||||
if(canvas === null){
|
||||
console.error("couldn't find canvas");
|
||||
throw new Error("canvas is null");
|
||||
}
|
||||
return canvas;
|
||||
}
|
||||
|
||||
function getGLContext(canvas : HTMLCanvasElement){
|
||||
const gl = canvas.getContext("webgl2") as any as WebGL2RenderingContext|null;
|
||||
if(gl === null){
|
||||
console.error("webgl2 is not supported!");
|
||||
throw new Error("webgl2 not supported");
|
||||
}
|
||||
return gl;
|
||||
}
|
||||
|
||||
function setupButton(){
|
||||
let toggle = false;
|
||||
const button = document.querySelector("#drawer-button") as HTMLDivElement;
|
||||
const drawer = document.querySelector("#drawer") as HTMLDivElement;
|
||||
button.addEventListener("click",()=>{
|
||||
toggle = !toggle;
|
||||
if(toggle){
|
||||
drawer.style.right = "0px";
|
||||
}
|
||||
else{
|
||||
drawer.style.right = "";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function main(){
|
||||
setupButton();
|
||||
const canvas = findCanvas();
|
||||
const gl = getGLContext(canvas);
|
||||
const renderer = new Renderer(gl);
|
||||
renderer.init();
|
||||
ReactDOM.render(<MenuBar u={renderer.uniforms}
|
||||
onUniformChange={(u)=>{renderer.settingUniform(u); renderer.draw();}} />
|
||||
,document.getElementById("drawer"));
|
||||
window.addEventListener("resize",(e)=>{
|
||||
e.preventDefault();
|
||||
canvas.width = document.body.clientWidth;
|
||||
canvas.height = document.body.clientHeight;
|
||||
renderer.draw();
|
||||
});
|
||||
canvas.width = document.body.clientWidth;
|
||||
canvas.height = document.body.clientHeight;
|
||||
renderer.draw();
|
||||
}
|
||||
main();
|
@ -10,7 +10,13 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"parcel-bundler": "^1.12.5"
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@mui/material": "^5.0.1",
|
||||
"@types/react": "^17.0.24",
|
||||
"parcel-bundler": "^1.12.5",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"glslify-bundle": "^5.1.1",
|
||||
|
@ -1,6 +1,3 @@
|
||||
import GL = WebGLRenderingContextStrict;
|
||||
import GL2 = WebGL2RenderingContextStrict;
|
||||
|
||||
export class ShaderError extends Error{
|
||||
constructor(
|
||||
readonly info:string
|
||||
@ -20,7 +17,7 @@ export class ProgramError extends Error{
|
||||
/***
|
||||
* compile shader
|
||||
*/
|
||||
export function compileShader(gl:GL2, source:string, type: GL.ShaderType): WebGLShader{
|
||||
export function compileShader(gl:WebGL2RenderingContext, source:string, type: GLenum): WebGLShader{
|
||||
const shader = gl.createShader(type);
|
||||
gl.shaderSource(shader,source);
|
||||
gl.compileShader(shader);
|
||||
@ -32,7 +29,7 @@ export function compileShader(gl:GL2, source:string, type: GL.ShaderType): WebGL
|
||||
return shader;
|
||||
}
|
||||
|
||||
export function createProgram(gl:GL2, vertex:WebGLShader,frag:WebGLShader){
|
||||
export function createProgram(gl:WebGL2RenderingContext, vertex:WebGLShader,frag:WebGLShader){
|
||||
const program = gl.createProgram();
|
||||
gl.attachShader(program,vertex);
|
||||
gl.attachShader(program,frag);
|
||||
@ -46,7 +43,7 @@ export function createProgram(gl:GL2, vertex:WebGLShader,frag:WebGLShader){
|
||||
}
|
||||
return program;
|
||||
}
|
||||
export function createProgramFromSource(gl:GL2, vert:string,frag:string){
|
||||
export function createProgramFromSource(gl:WebGL2RenderingContext, vert:string,frag:string){
|
||||
const vert_shader = compileShader(gl,vert,gl.VERTEX_SHADER);
|
||||
const frag_shader = compileShader(gl,frag,gl.FRAGMENT_SHADER);
|
||||
return createProgram(gl,vert_shader,frag_shader);
|
||||
|
19
src/menu.tsx
Normal file
19
src/menu.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import * as React from 'react';
|
||||
import Slider from "@mui/material/Slider";
|
||||
import Typograpy from "@mui/material/Typography";
|
||||
import {UniformSet} from "./uniform";
|
||||
|
||||
export function MenuBar(prop:{u:UniformSet,onUniformChange:(u:UniformSet)=>void}){
|
||||
const [uniform,setUniform] = React.useState(prop.u);
|
||||
const onRedChange = (_,v)=>{
|
||||
setUniform({...uniform,redcolor:v/100});
|
||||
};
|
||||
React.useEffect(()=>{
|
||||
prop.onUniformChange(uniform);
|
||||
})
|
||||
const a = uniform.redcolor*100;
|
||||
return (<div>
|
||||
<Typograpy variant="h4">Uniform</Typograpy>
|
||||
<Slider aria-label="Small" valueLabelDisplay="auto" onChange={onRedChange} value={a}></Slider>
|
||||
</div>);
|
||||
}
|
74
src/renderer.ts
Normal file
74
src/renderer.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import {createProgramFromSource, ProgramError, ShaderError} from "./gl_util";
|
||||
|
||||
/// <reference path="./glsl.d.ts" />
|
||||
import vert_src from "./vertex.vert";
|
||||
import frag_src from "./fragment.frag";
|
||||
|
||||
import { getUniformDefaultValue, UniformSet } from "./uniform";
|
||||
|
||||
export class Renderer{
|
||||
gl : WebGL2RenderingContext;
|
||||
uniforms : UniformSet;
|
||||
program: WebGLProgram;
|
||||
positionBuffer: WebGLBuffer;
|
||||
indexBuffer: WebGLBuffer;
|
||||
constructor(gl: WebGL2RenderingContext){
|
||||
this.gl = gl;
|
||||
this.uniforms = getUniformDefaultValue();
|
||||
try{
|
||||
this.program = createProgramFromSource(gl,vert_src,frag_src);
|
||||
gl.useProgram(this.program);
|
||||
}
|
||||
catch(e){
|
||||
if(e instanceof ShaderError){
|
||||
console.log(e.message,"\n",e.info);
|
||||
}
|
||||
else if(e instanceof ProgramError){
|
||||
console.log(e.message,"\n",e.info);
|
||||
}
|
||||
else throw e;
|
||||
}
|
||||
}
|
||||
init(){
|
||||
const gl = this.gl;
|
||||
const position = [
|
||||
-0.5,-0.5,
|
||||
0.5,-0.5,
|
||||
0.5,0.5,
|
||||
-0.5,0.5
|
||||
];
|
||||
const index = [
|
||||
0,1,2,
|
||||
2,3,0
|
||||
];
|
||||
this.positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER,this.positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(position),gl.STATIC_DRAW);
|
||||
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,this.indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(index),gl.STATIC_DRAW);
|
||||
this.settingUniform(this.uniforms);
|
||||
}
|
||||
useProgram(){
|
||||
this.gl.useProgram(this.program);
|
||||
}
|
||||
settingUniform(u:UniformSet){
|
||||
const gl = this.gl;
|
||||
this.uniforms = u;
|
||||
const location = gl.getUniformLocation(this.program, "u_color"); //u_color 변수 위치를 참조
|
||||
gl.uniform4f(location, this.uniforms.redcolor, 0.3, 0.8, 1.0); //해당 위치에 0.2, 0.3, 0.8, 1.0 데이터를 전달
|
||||
}
|
||||
draw(){
|
||||
const gl = this.gl;
|
||||
gl.clearColor(0,0,0,0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
gl.viewport(0,0,gl.canvas.width,gl.canvas.height);
|
||||
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0,2,gl.FLOAT,false,0,0);
|
||||
|
||||
gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,0);
|
||||
}
|
||||
}
|
9
src/uniform.ts
Normal file
9
src/uniform.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export type UniformSet = {
|
||||
redcolor:number
|
||||
};
|
||||
|
||||
export function getUniformDefaultValue():UniformSet{
|
||||
return {
|
||||
redcolor:0.5,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user