| 1 | <!DOCTYPE html>
 | 
| 2 | <html xmlns="http://www.w3.org/1999/xhtml">
 | 
| 3 |     <head>
 | 
| 4 |         <meta content="text/html; charset=utf-8" http-equiv="Content-Type"  />
 | 
| 5 |         <title>WebGL-Beispiel 3 : Farbe</title>
 | 
| 6 |     <script src="webgl-utils.js" ></script>
 | 
| 7 |     <script src="gl-matrix.js" ></script>
 | 
| 8 |     <script type="text/javascript">
 | 
| 9 |     "use strict";
 | 
| 10 |     /*global window */  // tells jslint that 'window' is defined!
 | 
| 11 |     /*global WebGLUtils */  // tells jslint that 'WebGLUtils' is defined!
  | 
| 12 |     /*global mat4 */  // tells jslint that 'mat4' is defined!
 | 
| 13 |     /*global Float32Array */  // tells jslint that 'Float32Array' is defined!
  | 
| 14 | 
 | 
| 15 |     var WebGLApplication = {};
 | 
| 16 | 
 | 
| 17 |     /**
 | 
| 18 |     * globales Core-Objekt, dass gekapselten Zugriff aus zentrale 
 | 
| 19 |     * Properties gewährt.
 | 
| 20 |     */
 | 
| 21 |     WebGLApplication.Core = (function () {
 | 
| 22 |         var members = {
 | 
| 23 |             // Zeiger zum WebGLProgram-Objekt
 | 
| 24 |             programObject: 0,
 | 
| 25 |             canvas: null,
 | 
| 26 |             gl: null,
 | 
| 27 |             pMatrix: null,
 | 
| 28 |             model: null,
 | 
| 29 |             shaderVarLocations: null
 | 
| 30 |         };
 | 
| 31 |         return {
 | 
| 32 |             getMember: function (key) {
 | 
| 33 |                 if (typeof members[key] !== 'undefined') {
 | 
| 34 |                     return members[key];
 | 
| 35 |                 } else {
 | 
| 36 |                     return false;
 | 
| 37 |                 }
 | 
| 38 |             },
 | 
| 39 |             setMember: function (key, value) {
 | 
| 40 |                 members[key] = value;
 | 
| 41 |             }
 | 
| 42 |         };
 | 
| 43 |     }());
 | 
| 44 | 
 | 
| 45 |     /**
 | 
| 46 |     * Beschreibt ein einfachstes 3D-Modell aus Raumpunkten und 
 | 
| 47 |     * zugehörigen Farbwerten.
 | 
| 48 |     */
 | 
| 49 |     WebGLApplication.Model = function () {
 | 
| 50 |         this.vertices = null;
 | 
| 51 |         this.verticesBuffer = null;
 | 
| 52 |         this.colors = null;
 | 
| 53 |         this.colorBuffer = null;
 | 
| 54 |         this.mvMatrix = null;
 | 
| 55 |     };
 | 
| 56 | 
 | 
| 57 |     /**
 | 
| 58 |     * Speichert alle Adressen der Variablen, die zwischen JavaScript und
 | 
| 59 |     * den Shadern ausgetauscht werden.
 | 
| 60 |     */
 | 
| 61 |     WebGLApplication.ShaderVarLocations = function () {
 | 
| 62 |         this.vertexAttribute = null;
 | 
| 63 |         this.colorAttribute = null;
 | 
| 64 |         this.mvMatrixUniform = null;
 | 
| 65 |         this.pMatrixUniform = null;
 | 
| 66 |         this.update = function (gl, programObject) {
 | 
| 67 |             this.vertexAttribute = gl.getAttribLocation(programObject,  "av4Position");
 | 
| 68 |             this.colorAttribute = gl.getAttribLocation(programObject, "av4VertexFarbe");
  | 
| 69 |             this.mvMatrixUniform = gl.getUniformLocation(programObject,  "um4ModelviewMatrix");
 | 
| 70 |             this.pMatrixUniform = gl.getUniformLocation(programObject, "um4PerspektivMatrix");
  | 
| 71 |         };
 | 
| 72 |     };
 | 
| 73 | 
 | 
| 74 |     /**
 | 
| 75 |     * Initialisiert die WebGL-Umgebung und erstellt das Shader-Program objekt
  | 
| 76 |     * @param {canvas} canvas die Zeichenfläche innerhalb der HTML-Seite.
  | 
| 77 |     * @param {String} vertexShaderString der Quellcode des VertexShaders
  | 
| 78 |     * @param {String} fragmentShaderString der Quellcode des FragmentShaders
  | 
| 79 |     * @param {String} eine ID aus dem DOM, in die ggf. Fehlermeldungen  geschrieben werden
 | 
| 80 |     * @return {WebGLContex} der erzeugte WebGL-Context    
 | 
| 81 |     */
 | 
| 82 |     WebGLApplication.init = function (canvas, vertexShaderString, fragmentShaderString,  statusAusgabeDOM_ID) {
 | 
| 83 |         var gl, programObject, compilerErfolg, fShader, vShader, webGLBrowserStatus,  linkerErfolg;
 | 
| 84 |         this.Core.setMember("canvas", canvas);
 | 
| 85 |         try {
 | 
| 86 |             this.Core.setMember("gl", WebGLUtils.setupWebGL(canvas));
 | 
| 87 |         } catch (e) { }
 | 
| 88 | 
 | 
| 89 |         if (!this.Core.getMember("gl")) {
 | 
| 90 |             webGLBrowserStatus = window.document.getElementById(statusAusgabeDOM_ID);
  | 
| 91 |             webGLBrowserStatus.innerHTML = "Dein Browser unterstützt WebGL  (noch) nicht. Die <a href=\"http://webgl.peter-strohm.de/webgltutorial0.php\">Liste der Bro wser mit WebGL-Support<\/a> kann Dir weiterhelfen.";
  | 
| 92 |         }
 | 
| 93 | 
 | 
| 94 |         gl = this.Core.getMember("gl");
 | 
| 95 |         programObject = gl.createProgram();
 | 
| 96 |         this.Core.setMember("programObject", programObject);
 | 
| 97 | 
 | 
| 98 |         vShader = gl.createShader(gl.VERTEX_SHADER);    // Das Vertex-Shader-Objekt  wird angelegt
 | 
| 99 |         gl.shaderSource(vShader, vertexShaderString);         //           - mit seinem Quelltext verknüpft
 | 
| 100 |         gl.compileShader(vShader);                           //           - kompiliert
 | 
| 101 |         // Check the compile status
 | 
| 102 |         compilerErfolg = gl.getShaderParameter(vShader, gl.COMPILE_STATUS);
  | 
| 103 |         if (!compilerErfolg) {
 | 
| 104 |             window.alert("Fehler beim erstellen des VertexShaders : \n\n"  + gl.getShaderInfoLog(vShader));
 | 
| 105 |             gl.deleteShader(vShader);
 | 
| 106 |             return false;
 | 
| 107 |         } else {
 | 
| 108 |             gl.attachShader(programObject, vShader);
 | 
| 109 |         }
 | 
| 110 | 
 | 
| 111 |         fShader = gl.createShader(gl.FRAGMENT_SHADER);
 | 
| 112 |         gl.shaderSource(fShader, fragmentShaderString);
 | 
| 113 |         gl.compileShader(fShader);
 | 
| 114 |         compilerErfolg = gl.getShaderParameter(fShader, gl.COMPILE_STATUS);
  | 
| 115 |         if (!compilerErfolg) {
 | 
| 116 |             window.alert("Fehler beim erstellen des FragmentShaders : \n\n"  + gl.getShaderInfoLog(fShader));
 | 
| 117 |             gl.deleteShader(fShader);
 | 
| 118 |             return false;
 | 
| 119 |         } else {
 | 
| 120 |             gl.attachShader(programObject, fShader);
 | 
| 121 |         }
 | 
| 122 | 
 | 
| 123 |         gl.linkProgram(programObject);                  // Das Shader-Program-Objekt  ist vollständig und muss gelinkt werden.
  | 
| 124 |         // Fehlerüberprüfung: Hat das Linken geklappt ?:
 | 
| 125 |         linkerErfolg = gl.getProgramParameter(programObject, gl.LINK_STATUS);
  | 
| 126 |         if (!linkerErfolg) {
 | 
| 127 |             window.alert("Fehler beim Linken des ShaderPrograms : \n\n"  + gl.getProgramInfoLog(programObject));
 | 
| 128 |             gl.deleteProgram(programObject);
 | 
| 129 |             return false;
 | 
| 130 |         }
 | 
| 131 |         gl.useProgram(programObject);                   // Da theoretisch  mehrere Shader-Program-Objekte möglich sind, muss 
  | 
| 132 |                                                         // angegeben werden,  welches benutzt werden soll.
 | 
| 133 |         return gl;
 | 
| 134 |     };
 | 
| 135 | 
 | 
| 136 |     /**
 | 
| 137 |     * Erstellt eine Perspektivische Projektionsmatrix und übergibt sie an  die Shader
 | 
| 138 |     * @param zNah {double} Z-Koordinate der nahen Begrenzungsebene des Sichtfelds
  | 
| 139 |     * @param zFern {double} Z-Koordinate der fernen Begrenzungsebene des Sichtfelds
  | 
| 140 |     * @param zFern {double} Öffnungswinkel des Sichtfelds in Grad
 | 
| 141 |     */
 | 
| 142 |     WebGLApplication.setupViewpoint = function (zNah, zFern, sichtfeldOeffnungswinkel)  {
 | 
| 143 |         var
 | 
| 144 |             aspektVerhaeltnis,
 | 
| 145 |             pMatrix,
 | 
| 146 |             canvas;
 | 
| 147 |         // Jetzt wird die Perspektivmatrix angelegt:
 | 
| 148 |         // Die Perspektivmatrix sorgt dafür, dass die Raumkoordinaten  der Vertizes auf der zweidimensionalen Webseite 
 | 
| 149 |         // so dargestellt werden, dass die Tiefenwirkung entsteht.
 | 
| 150 |         canvas = this.Core.getMember("canvas");
 | 
| 151 |         aspektVerhaeltnis = canvas.width / canvas.height;
 | 
| 152 |         pMatrix = mat4.perspective(sichtfeldOeffnungswinkel, aspektVerhaeltnis,  zNah, zFern);
 | 
| 153 |         this.Core.getMember("gl").uniformMatrix4fv(this.Core.getMember("shaderVarLocations").pMatrixUniform,  false, pMatrix);
  | 
| 154 | 
 | 
| 155 |     };
 | 
| 156 | 
 | 
| 157 |     /**
 | 
| 158 |     * Erzeugt Daten eines 3D-Modells (hier nur ein Dreieck) und übergibt  diese an die Shader
 | 
| 159 |     */
 | 
| 160 |     WebGLApplication.bufferModel = function () {
 | 
| 161 |         var
 | 
| 162 |             gl,
 | 
| 163 |             Model,
 | 
| 164 |             shaderVarLocations;
 | 
| 165 | 
 | 
| 166 |         gl = this.Core.getMember("gl");
 | 
| 167 |         Model = new this.Model();
 | 
| 168 |         this.Core.setMember("Model", Model);
 | 
| 169 | 
 | 
| 170 |         if (this.Core.getMember("shaderVarLocations") === null) {
 | 
| 171 |             shaderVarLocations = new WebGLApplication.ShaderVarLocations(gl);
  | 
| 172 |             shaderVarLocations.update(gl, this.Core.getMember("programObject"));
  | 
| 173 |             this.Core.setMember("shaderVarLocations", shaderVarLocations);
  | 
| 174 |         }
 | 
| 175 | 
 | 
| 176 |         // Ein Array mit den Koordinaten, der Eckpunkte des Dreiecks das dargestellt  wird.
 | 
| 177 |         Model.vertices = new Float32Array([
 | 
| 178 |             0.0, 1.0, 0.0,  //x y z des ersten Dreieckpunktes
 | 
| 179 |             -1.0, -1.0, 0.0,  //x y z des zweiten Dreieckpunktes
 | 
| 180 |             1.0, -1.0, 0.0]);   //x y z des dritten Dreieckpunktes
 | 
| 181 |         Model.vertexBuffer = gl.createBuffer();                // ein WebGL-Buffer-Objekt  wird erzeugt
 | 
| 182 |         gl.bindBuffer(gl.ARRAY_BUFFER, Model.vertexBuffer);    // ...und  als aktives Objekt gesetzt
 | 
| 183 |         gl.bufferData(gl.ARRAY_BUFFER, Model.vertices, gl.STATIC_DRAW);   // die Arraydaten werden an den aktiven Puffer übergeben
  | 
| 184 | 
 | 
| 185 |         Model.colors = new Float32Array([
 | 
| 186 |             1.0, 0.0, 0.0, 1.0, //rot
 | 
| 187 |             0.0, 1.0, 0.0, 1.0, //grün
 | 
| 188 |             0.0, 0.0, 1.0, 1.0]); //blau
 | 
| 189 | 
 | 
| 190 |         Model.colorBuffer = gl.createBuffer();
 | 
| 191 |         gl.bindBuffer(gl.ARRAY_BUFFER, Model.colorBuffer);
 | 
| 192 |         gl.bufferData(gl.ARRAY_BUFFER, Model.colors, gl.STATIC_DRAW);
 | 
| 193 | 
 | 
| 194 |         Model.mvMatrix = mat4.identity();
 | 
| 195 |         mat4.translate(Model.mvMatrix, [0.0, 0.0, -3.0]);
 | 
| 196 |         gl.uniformMatrix4fv(shaderVarLocations.mvMatrixUniform, false,  Model.mvMatrix);
 | 
| 197 |     };
 | 
| 198 | 
 | 
| 199 |     /**
 | 
| 200 |     * Löscht den Bildschirm und zeichnet das aktive Modell neu.
 | 
| 201 |     * @param gl {WebGLContext} aktiver WebGLContext
 | 
| 202 |     */
 | 
| 203 |     WebGLApplication.drawScene = function (gl) {
 | 
| 204 |         var shaderVarLocations,
 | 
| 205 |             Model;
 | 
| 206 |         shaderVarLocations = this.Core.getMember("shaderVarLocations");
  | 
| 207 |         Model = this.Core.getMember("Model");
 | 
| 208 |         gl.clearColor(0.0, 0.0, 0.0, 1.0);                     // RGB-Alpha  Farbe zum Löschen des Hintergrundes
 | 
| 209 |         gl.clear(gl.COLOR_BUFFER_BIT);                         // Hintergrund  löschen
 | 
| 210 | 
 | 
| 211 |         gl.bindBuffer(gl.ARRAY_BUFFER, Model.colorBuffer);
 | 
| 212 |         gl.vertexAttribPointer(shaderVarLocations.colorAttribute, 4, gl.FLOAT,  false, 0, 0);
 | 
| 213 |         gl.enableVertexAttribArray(shaderVarLocations.colorAttribute);
  | 
| 214 | 
 | 
| 215 |         gl.bindBuffer(gl.ARRAY_BUFFER, Model.vertexBuffer);    // ...und  als aktives Objekt gesetzt
 | 
| 216 |         gl.vertexAttribPointer(shaderVarLocations.vertexAttribute, 3, gl.FLOAT,  false, 0, 0);
 | 
| 217 |         gl.enableVertexAttribArray(shaderVarLocations.vertexAttribute);
  | 
| 218 | 
 | 
| 219 |         gl.drawArrays(gl.TRIANGLES, 0, 3);
 | 
| 220 |     };
 | 
| 221 | 
 | 
| 222 |     /**
 | 
| 223 |     * Zentrale Einstiegsstelle des WebGL-Programms. Wird nach dem Laden der  HTML-Seite 
 | 
| 224 |     * ausgeführt und ruft synchron alle weiteren Methoden auf.
 | 
| 225 |     */
 | 
| 226 |     function meinWebGLStart() {
 | 
| 227 |         var
 | 
| 228 |             meineCanvas,
 | 
| 229 |             gl,
 | 
| 230 |             fragmentShaderQuellcode,
 | 
| 231 |             vertexShaderQuellcode;
 | 
| 232 | 
 | 
| 233 |         meineCanvas = window.document.getElementById("meineWebGLCanvas");   // canvas ist die "Leinwand" innerhalb der HTML Seite, auf die gezeichnet werden kann
  | 
| 234 | 
 | 
| 235 |         vertexShaderQuellcode =
 | 
| 236 |             'attribute vec4 av4Position; \n\
 | 
| 237 |              attribute vec4 av4VertexFarbe; \n\
 | 
| 238 |              uniform mat4 um4PerspektivMatrix; \n\
 | 
| 239 |              uniform mat4 um4ModelviewMatrix; \n\
 | 
| 240 |              varying vec4 vFarbe; \n\
 | 
| 241 |              void main() \n\
 | 
| 242 |              { \n\
 | 
| 243 |                  gl_Position = um4PerspektivMatrix * um4ModelviewMatrix  * av4Position; \n\
 | 
| 244 |                  vFarbe = av4VertexFarbe; \n\
 | 
| 245 |              } \n';
 | 
| 246 | 
 | 
| 247 |         fragmentShaderQuellcode =
 | 
| 248 |             'precision mediump float;\n\
 | 
| 249 |              varying vec4 vFarbe; \n\
 | 
| 250 |              void main()  \n\
 | 
| 251 |              {     \n\
 | 
| 252 |                  gl_FragColor = vFarbe;\n\
 | 
| 253 |              } \n';
 | 
| 254 | 
 | 
| 255 |         gl = WebGLApplication.init(meineCanvas, vertexShaderQuellcode,  fragmentShaderQuellcode, "webGLBrowserStatus");
 | 
| 256 | 
 | 
| 257 |         WebGLApplication.bufferModel();
 | 
| 258 |         WebGLApplication.setupViewpoint(0.1, 100.0, 90);
 | 
| 259 | 
 | 
| 260 |         WebGLApplication.drawScene(gl);
 | 
| 261 |     }
 | 
| 262 | 
 | 
| 263 |     /**
 | 
| 264 |     * Event-Zuordnung: Sobald die Seite geladen ist, wird meinWebGLStart()  ausgeführt.
 | 
| 265 |     */
 | 
| 266 |     window.onload = function () {
 | 
| 267 |         meinWebGLStart();
 | 
| 268 |     };
 | 
| 269 | 
 | 
| 270 |     </script>
 | 
| 271 |     
 | 
| 272 |     </head>
 | 
| 273 |     <body>
 | 
| 274 |         <noscript><h2>JavaScript ist in Deinem Browser deaktiviert oder  wird nicht unterstützt. Ohne JavaScript kann diese Seite nicht korrekt dargestellt wer den.</h2>   </noscript>
  | 
| 275 |         <p id="webGLBrowserStatus"></p>
 | 
| 276 |         <a href="webgltutorial3.php">zurück zum Tutorial</a><br />
 | 
| 277 |         <canvas id="meineWebGLCanvas" width="500" height="500"></canvas>  
 | 
| 278 |         <br />
 | 
| 279 |         <a href="webgltutorial3.php">zurück zum Tutorial</a>
 | 
| 280 |     </body>
 | 
| 281 | </html>
 | 
| 282 | 
 | 
| 283 |  |