Benutzer:Coolcat/Tutorial WebGL: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „{{Warnung|Dieser Artikel befindet sich noch im Aufbau!}} WebGL ist der neue Standard für OpenGL im Browser. Der Standard ermöglicht es hardwarebeschleunigte 3D-…“)
 
(Weiterleitung auf Tutorial WebGL, Artikel war identisch)
 
(32 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{Warnung|Dieser Artikel befindet sich noch im Aufbau!}}
+
#REDIRECT [[Tutorial WebGL]]
WebGL ist der neue Standard für OpenGL im Browser. Der Standard ermöglicht es hardwarebeschleunigte 3D-Grafik im Browser darzustellen, ohne dabei auf spezielle Plugins angewiesen zu sein. Bisher wird der Standard von den folgenden Browsern unterstützt:
 
* Mozilla Firefox 3.7a1pre ([http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/ Nightly Build], "Minefield")
 
:: WebGL muss über die Einstellung <tt>about:config</tt> -> <tt>webgl.enabled_for_all_sites</tt> aktiviert werden. Unter Windows kann es einige Probleme geben, wenn kein OpenGL verfügbar ist, in dem Fall muss [http://hacks.mozilla.org/2009/09/webgl-for-firefox/ in den Softwaremodus geschaltet] werden.
 
* WebKit ([http://nightly.webkit.org/ Nightly Build])
 
** Google Chrome 4.0.221.8 (Nightly Build, [http://www.khronos.org/news/permalink/webgl-seen-in-chrome-browser/ siehe hier])
 
* ...bitte ergänzen...
 
 
 
 
 
__TOC__
 
 
 
 
 
==WebGL Context==
 
Um WebGL nutzen zu können benötigt man zunächst einmal natürlich ein HTML5 Canvas-Element, welchem wir passenderweise die ID "canvas" geben. Von diesem Canvas erhalten wir zum einen die spätere Viewportgröße und zum anderen einen sogenannten Context. Das Context-Objekt erlaubt uns sämtliche OpenGL ES 2.0 Funktionen aufzurufen.
 
 
 
<source lang="javascript">
 
// our WebGL rendering context, it might be useful to use a global variable for this
 
var gl = null;
 
 
 
// grab the canvas object and its dimensions
 
var canvas = document.getElementById("canvas");
 
var viewportWidth = canvas.width;
 
var viewportHeight = canvas.height;
 
 
 
// request rendering context from the canvas
 
try {
 
    // using Mozilla? (e.g. Firefox, ...)
 
    if (!gl) { gl = canvas.getContext("moz-webgl"); }
 
} catch (e) { }
 
try {
 
    // using Webkit? (e.g. Google Chrome, ...)
 
    if (!gl) { gl = canvas.getContext("webkit-3d"); }
 
} catch (e) { }
 
 
 
if (!gl) {
 
    alert("No known OpenGL context detected! Is it enabled?");
 
    return;
 
}
 
</source>
 
 
 
==Shader==
 
In OpenGL ES 2.0 herrscht Shader-Zwang, eine [[Feste Funktionspipeline|feste Funktionspipeline]] existiert nicht. Das laden von GLSL-Shadern geschieht wie gewohnt. Zuerst werden Vertex- und Fragmentshader geladen und compiliert. Beide Shader werden dann an ein Program-Objekt angehängt und gelinkt.
 
 
 
<source lang="javascript">
 
function loadShader(shaderType, shaderSource) {
 
    var shader = gl.createShader(shaderType);
 
    if (!shader) { return null; }   
 
    gl.shaderSource(shader, shaderSource);
 
    gl.compileShader(shader);
 
   
 
    if (!gl.getShaderi(shader, gl.COMPILE_STATUS)) {
 
        alert(gl.getShaderInfoLog(shader));
 
        return null;
 
    }   
 
   
 
    return shader;
 
}
 
 
 
var vertexShaderSource = "...Vertexshader als String...";
 
var fragmentShaderSource = "...Fragmentshader als String...";
 
 
 
var vertexShader = loadShader(gl.VERTEX_SHADER, vertexShaderSource);
 
var fragmentShader = loadShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
 
if (!vertexShader || !fragmentShader) {
 
alert("Shader problem");
 
}
 
 
 
// create program object
 
var program = gl.createProgram();
 
 
 
// attach our two shaders to the program
 
gl.attachShader(program, vertexShader);
 
gl.attachShader(program, fragmentShader);
 
 
 
// setup attributes and uniforms (optional)
 
gl.bindAttribLocation(program, 0, "aPosition");
 
gl.bindAttribLocation(program, 1, "aNormal");
 
gl.bindAttribLocation(program, 2, "aTexCoord");
 
gl.uniform1i(gl.getUniformLocation(program, "uTexture"), 0);
 
 
 
// linking
 
gl.linkProgram(program);
 
if (!gl.getProgrami(program, gl.LINK_STATUS)) {
 
    alert(gl.getProgramInfoLog(program));
 
}
 
</source>
 
 
 
Im obigen Beispiel wird der Shader-Quellcode fest als String in den JavaScript-Code integriert. Das ist natürlich ziemlich unübersichtlich. Vom Prinzip spielt es keine Rolle wo der String herkommt. Beispielsweise kann man ihn mit einem HTTP-Request in einer Shader-Datei vom Server laden. Es ist aber auch möglich den Shader-Code als spezielles Script-Element in die HTML-Datei einzubinden.
 
 
 
<source lang="html4strict">
 
<script id="shader-vs" type="x-shader/x-vertex">
 
attribute vec3 aPosition;
 
attribute vec3 aNormal;
 
attribute vec3 aTexCoord;
 
varying vec3 vNormal;
 
varying vec2 vTexCoord;
 
void main() {
 
    gl_Position = vec4(aPosition, 1.0);
 
    vTexCoord = aTexCoord;
 
    vNormal = aNormal;
 
}
 
</script>
 
 
 
<script id="shader-fs" type="x-shader/x-fragment">
 
varying vec3 vNormal;
 
varying vec2 vTexCoord;
 
uniform sampler2D uTexture;
 
void main() {
 
    gl_FragColor = texture2D(uTexture, vTexCoord);
 
}
 
</script>
 
</source>
 
 
 
Der Browser hat vom Script-Typ <tt>"x-shader/x-vertex"</tt> natürlich noch nie etwas gehört und wird das Element entsprechend einfach ignorieren. Mit einer einfachen JavaScript-Funktion kann man aber trotzdem an den Inhalt gelangen.
 
 
 
<source lang="javascript">
 
function getShaderSource(id) {
 
    var script = document.getElementById(id);
 
    if (!script) { return null; }
 
   
 
    var source = "";
 
    var child = script.firstChild;
 
    while (child) {
 
        if (child.nodeType == 3) {
 
            source += child.textContent;
 
        }
 
        child = child.nextSibling;
 
    }
 
    return source;
 
}
 
 
 
var vertexShaderSource = getShaderSource("shader-vs");
 
var fragmentShaderSource = getShaderSource("shader-fs");
 
</source>
 
 
 
==VertexBufferObjects==
 
...demnächst...
 
 
 
==Texturen==
 
Das Laden von Texturen ist relativ einfach, da der Browser bereits über die nötige Infrastruktur zum Laden von Bildern in vielen Formaten bereitstellt. Etwas ungewohnt ist der asynchrone Ladevorgang: Ein Bild steht nicht sofort zur Verfügung, da dieses ja möglicherweise zuerst vom Server geladen werden muss. Sobald aber das Bild verfügbar ist wird das <tt>onload</tt>-Event ausgelöst.
 
<source lang="javascript">
 
function loadTexture(filename) {
 
    var texture = gl.createTexture();
 
    gl.bindTexture(gl.TEXTURE_2D, texture);
 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
 
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
 
    var image = new Image();
 
    image.onload = function() {
 
        gl.bindTexture(gl.TEXTURE_2D, texture);
 
        gl.texImage2D(gl.TEXTURE_2D, 0, image);
 
        gl.generateMipmap(gl.TEXTURE_2D);
 
        draw(); // texture now available, we can redraw the scene
 
    }
 
    image.onerror = function() {
 
        alert("error while loading image '"+filename+"'.");
 
    }
 
    image.src = filename;
 
    return texture;
 
}
 
</source>
 
 
 
==Links==
 
* [http://people.mozilla.com/~vladimir/webgl/spore/sporeview.html Spore Creature Viewer], ein Viewer für [http://www.collada.org/ COLLADA]-Meshes, allerdings nur für aus dem Spiel [http://www.spore.com/ Spore] exportierte Meshes.
 
* [http://code.google.com/p/chromium/source/browse/trunk/samples/webgl Beispiele für Chromium], funktionieren nicht mit Firefox
 

Aktuelle Version vom 27. Oktober 2009, 21:52 Uhr

Weiterleitung nach: