-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathapp.js
More file actions
254 lines (204 loc) · 8.49 KB
/
app.js
File metadata and controls
254 lines (204 loc) · 8.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
const socket = new WebSocket('ws://localhost:8009');
// Get the canvas and setup WebGL context
const canvas = document.getElementById('glcanvas');
const gl = canvas.getContext('webgl');
// Verify WebGL support
if (!gl) {
alert('Unable to initialize WebGL. Your browser may not support it.');
throw new Error('WebGL not supported');
}
// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec2 aTextureCoord;
varying highp vec2 vTextureCoord;
void main(void) {
gl_Position = aVertexPosition;
vTextureCoord = aTextureCoord;
}
`;
// Fragment shader program
const fsSource = `
precision highp float;
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
function initShaderProgram(gl, vsSource, fsSource) {
// Function to load a shader, compile it, and check for errors
function loadShader(gl, type, source) {
const shader = gl.createShader(type); // Create a new shader object
gl.shaderSource(shader, source); // Send the source to the shader object
gl.compileShader(shader); // Compile the shader program
// Check if compilation was successful
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
// Load and compile the vertex and fragment shaders
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
// Create the shader program
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// Check if creating the shader program failed
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}
return shaderProgram;
}
// Initialize a shader program; this is where all the lighting for the
// vertices and so forth is established.
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
// Collect all the info needed to use the shader program.
// Look up which attributes our shader program is using.
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
},
uniformLocations: {
uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'),
},
};
function initBuffers(gl) {
// Create a buffer for the square's positions.
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Define the positions for a rectangle that covers the entire canvas.
const positions = [
-1.0, 1.0,
1.0, 1.0,
-1.0, -1.0,
1.0, -1.0,
];
// Pass the list of positions into WebGL to build the shape.
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// Set up the texture coordinates buffer for the rectangle.
const textureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
const textureCoordinates = [
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
];
// Pass the texture coordinates to WebGL.
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
return {
position: positionBuffer,
textureCoord: textureCoordBuffer,
};
}
function drawScene(gl, programInfo, buffers) {
// Clear the canvas before drawing.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Tell WebGL how to pull out the positions from the position buffer into the vertexPosition attribute.
{
const numComponents = 2; // pull out 2 values per iteration
const type = gl.FLOAT; // the data in the buffer is 32bit floats
const normalize = false; // don't normalize
const stride = 0; // how many bytes to get from one set of values to the next
const offset = 0; // how many bytes inside the buffer to start from
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexPosition);
}
// Tell WebGL how to pull out the texture coordinates from the texture coordinate buffer.
{
const numComponents = 2; // every coordinate consists of 2 values
const type = gl.FLOAT; // the data in the buffer is 32bit floats
const normalize = false; // don't normalize
const stride = 0; // how many bytes to get from one set of values to the next
const offset = 0; // how many bytes inside the buffer to start from
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.textureCoord);
gl.vertexAttribPointer(
programInfo.attribLocations.textureCoord,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.textureCoord);
}
// Specify the texture to use.
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.useProgram(programInfo.program)
gl.uniform1i(programInfo.uniformLocations.uSampler, 0);
// Draw the rectangle.
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
// Prepare and load texture
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set the parameters so we can render any size image.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const buffers = initBuffers(gl);
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
socket.binaryType = 'arraybuffer'; // Ensure you receive the data as ArrayBuffer
intToSend = 4;
function sendInteger(){
intToSend = parseInt(document.getElementById('numberInput').value, 10);
const arrayBuffer = new ArrayBuffer(4);
const view = new DataView(arrayBuffer);
view.setInt32(0, intToSend, false);
socket.send(arrayBuffer);
};
socket.onopen = function (event) {
console.log('Connected to WebSocket server.');
// Optionally send binary data like a negative integer as previously discussed
sendInteger();
};
socket.onmessage = function (event) {
const buffer = event.data;
// Use DataView to handle different data types in the same buffer
const view = new DataView(buffer);
// Read the two integers (assuming they are the first 8 bytes, 4 bytes each)
const width = view.getInt32(0, true); // Read first integer (little-endian)
const height = view.getInt32(4, true); // Read second integer (little-endian)
const canvas = document.getElementById('glcanvas');
if(canvas.width != width || canvas.height != height)
{
const dpr = window.devicePixelRatio || 1; // Get the device's pixel ratio
// Set the drawing buffer's size
canvas.width = width * dpr;
canvas.height = height * dpr;
gl.viewport(0, 0, width * dpr, height * dpr)
}
// Create a TypedArray for the remaining bytes (tensor data)
// Adjust the offset and length according to the actual data size
const data = new Uint8Array(buffer, 8); // Skip the first 8 bytes
if (data.byteLength !== width * height * 3) {
console.log(data.byteLength, width * height * 3)
}
//console.log("Data as array:", data);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, data);
drawScene(gl, programInfo, buffers);
sendInteger();
};
socket.onerror = function (error) {
console.error('WebSocket Error:', error);
};
socket.onclose = function (event) {
console.log('WebSocket is closed now.');
};