-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebGLExample1.html
More file actions
121 lines (109 loc) · 9.58 KB
/
webGLExample1.html
File metadata and controls
121 lines (109 loc) · 9.58 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
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script id="vShader" type="x-shader/x-vertex">
// Ο παρακάτω κώδικας δεν είναι Javascript αλλά GLSL-ES
attribute vec4 aVertexPosition; // attribute: παράμετρος εισόδου του shader
varying vec4 vColor; // varying: μεταβλητή εξόδου προς το fragment shader (μέσω rasterization)
void main() {
gl_Position = aVertexPosition; // Θέση κάθε κορυφής (vertex) σε ομογενείς συντεταγμένες
vColor = vec4(0.0,0.0,1.0,1.0); // Χρώμα κάθε κορυφής (vertex) (r,g,b,a)
}
</script>
<script id="fShader" type="x-shader/x-fragment">
// Ο παρακάτω κώδικας δεν είναι Javascript αλλά GLSL-ES
precision mediump float; // Ορίζεται η ακρίβεια των πραγματικών που θα χρησιμοποιηθούν
varying vec4 vColor; // varying: Παράμετρος εισόδου από το vertex shader (μέσω rasterization)
void main() {
gl_FragColor = vColor;
}
</script>
<script>
var gl; // Το rendering context που ***ΜΑΣ ΔΙΝΕΙ ΠΡΟΣΒΑΣΗ ΣΤΟ WebGL API*** μέσω των μεθόδων του και των ιδιοτήτων του
var canvas; // Το DOM αντικείμενο που θα φιλοξενήσει το context
var shadersProgram; // O κώδικας των vertex και fragment shaders
var vertexPositionAttributePointer; // Η διεύθυνση του attribute aVertexPosition
var vertexBuffer; // Η μεταβλητή στην οποία θα αποθηκευτούν προσωρινά τα δεδομένα των vertices
function createRenderingContext(inCanvas) {
var outContext = null;
outContext = inCanvas.getContext("webgl"); // 4.1 Δημιούργησε ένα WebGL context
if (!outContext)
outContext = inCanvas.getContext("experimental-webgl"); // 4.2 Αν δεν πέτυχε προσπάθησε ξανά με το παλαιότερο όνομα
if (!outContext) // 4.3 Αν δεν πέτυχε εμφάνισε μήνυμα λάθους
alert("WebGL rendering context creation error.");
return outContext;
}
function createCompileShader(shaderType, shaderSource) {
var outShader = gl.createShader(shaderType); // 5.3.1 και 5.4.1 Δημιούργησε έναν κενό shader του τύπου που δόθηκε σαν παράμετρος
gl.shaderSource(outShader, shaderSource); // 5.3.2 και 5.4.2 Ενημέρωσε το shader με τον κώδικά του (σε μορφή string)
gl.compileShader(outShader); // 5.3.3 και 5.4.3 Κάνε compile τον κώδικα του shader
if (!gl.getShaderParameter(outShader, gl.COMPILE_STATUS)) { // Αν δεν γίνει compile με επιτυχία
alert( "Shader compilation error. " + gl.getShaderInfoLog(outShader) ); // Δώσε μήνυμα με πληροφορίες για το shader
gl.deleteShader(outShader); // και κατάστρεψέ τον
outShader = null;
}
return outShader; // 5.3.4 και 5.3.5 επίστρεψε τον compiled shader ή null
}
function initShaders() {
var vertexShaderSource = document.getElementById("vShader").textContent;
// 5.1 Δημιούργησε string με τον κώδικα του vertex shader από το κείμενο του αντίστοιχου script
var fragmentShaderSource = document.getElementById("fShader").textContent;
// 5.2 Δημιούργησε string με τον κώδικα του fragment shader από το κείμενο του αντίστοιχου script
var vertexShader = createCompileShader(gl.VERTEX_SHADER, vertexShaderSource); // CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ:
// 5.3 Δημιούργησε και ενημέρωσε το αντικείμενο vertex shader
var fragmentShader = createCompileShader(gl.FRAGMENT_SHADER, fragmentShaderSource); // CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ:
// 5.4 ομοίως το fragment shader
shadersProgram = gl.createProgram();
// 5.5 Δημιούργησε ένα (κενό) πρόγραμμα(=αντικείμενο) (που πρόκειται να περιέχει τους shaders)
gl.attachShader(shadersProgram, vertexShader); // 5.6 Επισύναψε το vertex shader στο συγκεκριμένο πρόγραμμα
gl.attachShader(shadersProgram, fragmentShader); // 5.7 Επισύναψε το fragment shader στο συγκεκριμένο πρόγραμμα
gl.linkProgram(shadersProgram); // 5.8 δημιούργησε το αντίστοιχο εκτελέσιμο (και των δύο shaders)
if (!gl.getProgramParameter(shadersProgram, gl.LINK_STATUS)) {// 5.9 Αν υπήρξε λάθος στη δημιουργία του εκτελέσιμο πες το
alert("Shaders linking error.");
}
gl.useProgram(shadersProgram); // 5.10 Προσάρτησε το εκτελέσιμο στο context
vertexPositionAttributePointer = gl.getAttribLocation(shadersProgram, "aVertexPosition"); // 5.11 Βρες και αποθήκευσε στην αντίστοιχη μεταβλητή, τον αύξοντα αριθμό της διεύθυνσης του attribute του shader program, το οποίο έχει όνομα το string που δόθηκε σα δεύτερη παράμετρος
gl.enableVertexAttribArray(vertexPositionAttributePointer); // 5.12 Προετοίμασε το attribute (μέσω του παραπάνω pointer που δείχνει σε αυτό) να δεχθεί δεδομένα
}
function initBuffers() { // Άλλαξα μόνο εδώ τις συντεταγμένες των κορυφών του τριγώνου
var triangleVertices = new Float32Array([
0.5, 0.5, 0.5, 1.0,
0.5, -0.5, 0.5, 1.0,
-0.5, -0.5, 0.5, 1.0
]);
// 6.1 Δημιούργησε έναν πίνακα (ArrayBuffer) στη μνήμη με τις συντεταγμένες (x,y,z,w) κάθε κορυφής. Ο πίνακας είναι μονοδιάστατος
vertexBuffer = gl.createBuffer(); // 6.2 Δημιούργησε (δέσμευσε) έναν buffer για τις κορυφές
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // 6.3 Ενεργοποίησέ τον, δηλ. φέρε τον στο προσκήνιο: ό,τι δουλειά γίνεται με buffer θα αφορά αυτόν
gl.bufferData(gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW); // 6.4 "Τάισε" τα δεδομένα του πίνακα στον (ενεργοποιημένο) buffer (επίσης μονοδιάστατος)
vertexBuffer.itemSize = 4; // 6.5 Δώσε τιμή στην (custom) ιδιότητα του buffer που καθορίζει ανά πόσες τιμές αφορούν την ίδια κορυφή
vertexBuffer.itemCount = 3; // 6.6 Δώσε τιμή στην (custom) ιδιότητα του buffer που καθορίζει πόσες κορυφές αφορά ο buffer συνολικά
}
function drawScene() {
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); // 8.1 Ενεργοποίησε το viewport με τις διαστάσεις που δίνονται σαν παράμετροι
gl.clear(gl.COLOR_BUFFER_BIT); // 8.2 "Καθάρισε" το viewport χρωματίζοντάς το με το χρώμα που έχει οριστεί στο βήμα 7.
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // 8.3 Κάνε ενεργό το vertex buffer
gl.vertexAttribPointer(vertexPositionAttributePointer, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
// 8.4 Παίρνε στοιχεία από τον ενεργό buffer και "τάιζέ" τα στη διεύθυνση του attribute μέσω του pointer(1η παράμετρος),
// με μέγεθος στοιχείου σε πλήθος αριθμών (2η παρ.),
// τύπο δεδομένων (3η), κανονικοποιώντας (4η παρ.) με βήμα (παράλειψης) τόσα bytes (5η παρ.) και ξεκινώντας από αυτό το byte (6η παράμετρος..)
gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.itemCount); // 8.5 Σχεδίασε τρίγωνα (1η παρ.) ξεκινώντας από την κορυφή με σειρά όση η 2η παρ., και χρησιμοποίησε τόσες κορυφές όσες η 3η παρ.
}
function main() {
var minDimension = Math.min(window.innerHeight, window.innerWidth); // 0. Καταχώρησε την ελάχιστη διάσταση του παραθύρου
canvas = document.getElementById("sceneCanvas"); // 1. Απομόνωσε ("ψάρεψε") τον καμβά (έχει δημιουργηθεί ως HTML αντικείμενο)
canvas.width = 0.95*minDimension; // 2. Όρισε τις διαστάσεις του
canvas.height = 0.95*minDimension; // 3. Όρισε τις διαστάσεις του
gl = createRenderingContext(canvas); // 4. CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ: Δημιούργησε μέσα στον καμβά ένα WebGL rendering context
initShaders(); // 5. CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ: Προετοίμασε τους shaders
initBuffers(); // 6. CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ: Προετοίμασε τους buffers
gl.clearColor(0.5, 0.5, 0.5, 1.0); // 7. Όρισε το χρώμα του background στο WebGL context (R,G,B,A) με τιμές από 0 ως 1
drawScene(); // 8. CUSTOM ΣΥΝΑΡΤΗΣΗ - ΔΕΣ ΠΑΡΑΠΑΝΩ: Σχεδίασε τη σκηνή
}
</script>
</head>
<body onload="main()">
<canvas id="sceneCanvas">
</canvas>
</body>
</html>