Saturday, November 17th, 2007
3D Canvas in Opera
Tim Johansson is talking about Opera's support for a 3d Canvas which differs from Mozilla's in that it doesn't map directly to OpenGL, which they did because:
- It makes it easier to implement on non-OpenGL platforms (such as D3D)
- We wanted to have some form of collision detection available
What can you do? Here is the interface that you get to work with:
-
-
interface CanvasRenderingContextOpera3D {
-
-
// state
-
void save(); // push state on state stack
-
void restore(); // pop state stack and restore state
-
-
// scene/frame
-
void beginScene(); // start rendering a new frame
-
void endScene(); // finish rendering of the scene and present the result
-
-
// transformations
-
void translate(in float x, in float y, in float z);
-
void scale(in float x, in float y, in float z);
-
void rotateX(in float rotation);
-
void rotateY(in float rotation);
-
void rotateZ(in float rotation);
-
-
// rendering operation
-
void drawTriangle(in float x1, in float y1, in float z1, in float tex_s1, in float tex_t1,
-
in float x2, in float y2, in float z2, in float tex_s2, in float tex_t2,
-
in float x3, in float y3, in float z3, in float tex_s3, in float tex_t3);
-
void draw3DModel(in Canvas3DModel model);
-
-
// create objects
-
CanvasTexture createTexture(in Image img);
-
Canvas3DModel create3DModel();
-
-
// collision detection
-
string checkIntersection(in float x, in float y, in float z, in float radius, in Canvas3DModel model);
-
-
// rendering state
-
attribute CanvasTexture texture; // current texture or null for no texture, default is null
-
attribute string color; // current color, default is transparent black
-
attribute float fov; // field of view of the scene in degrees, default is 45
-
attribute float nearPlane; // distance to the near clipping plane, default is 0.1
-
attribute float farPlane; // distance to the far clipping plane, default is 100
-
attribute string ztest; // "none", "less", "lessequal", "greater", "greaterequal", "equal", "notequal". Default is "lessequal"
-
attribute string blend; // "replace", "add", "srcalpha", "multiply". Default is "replace"
-
};
-
-
interface Canvas3DModel {
-
void addVertex(in float x, in float y, in float z, in float s, in float t);
-
void addTriangle(in integer vertex1, in integer vertex2, in integer vertex3);
-
};
-
-
interface CanvasTexture{
-
};
-
And, here is an example of a rotating cube (which you can see if you are using a new Opera build).
-
-
<canvas id="canvas" width="200" height="200">
-
Canvas not supported!
-
</canvas>
-
-
var canvas;
-
var context3d;
-
var rotation;
-
var texture;
-
var cube;
-
function render(){
-
context3d.beginScene();
-
context3d.translate(0,0,-5);
-
context3d.rotateY(rotation);
-
context3d.rotateX(rotation);
-
rotation += 2;
-
context3d.color = "white";
-
context3d.draw3DModel(cube);
-
context3d.endScene();
-
}
-
function onTick(){
-
render();
-
}
-
function onload(){
-
canvas = document.getElementById("canvas");
-
context3d = canvas.getContext("opera-3d");
-
if (!context3d)
-
{
-
alert("3d canvas not supported");
-
return;
-
}
-
logo = new Image();
-
logo.src = "operalogo.png";
-
texture = context3d.createTexture(logo);
-
context3d.texture = texture;
-
-
cube = context3d.create3DModel();
-
cube.addVertex(-1, 1, 1, 0, 0);
-
cube.addVertex(1, 1, 1, 1, 0);
-
cube.addVertex(-1, -1, 1, 0, 1);
-
cube.addVertex(1, -1, 1, 1, 1);
-
cube.addVertex(-1, 1, -1, 1, 1);
-
cube.addVertex(1, 1, -1, 0, 1);
-
cube.addVertex(-1, -1, -1, 1, 0);
-
cube.addVertex(1, -1, -1, 0, 0);
-
-
cube.addTriangle(0,1,2);
-
cube.addTriangle(2,1,3);
-
cube.addTriangle(4,5,6);
-
cube.addTriangle(6,5,7);
-
cube.addTriangle(0,4,2);
-
cube.addTriangle(2,4,6);
-
cube.addTriangle(1,5,3);
-
cube.addTriangle(3,5,7);
-
cube.addTriangle(0,4,1);
-
cube.addTriangle(1,4,5);
-
cube.addTriangle(2,6,3);
-
cube.addTriangle(3,6,7);
-
-
setInterval(onTick, 10);
-
}
-
document.onload = onload();
-
</script>
-












Here we go again. Everyone is implementing the 3d Canvas in his own way. :s
i tried to view this in a virtualbox machine. i only get the “3d canvas not supported”, of course using opera last build presented on that post.
i wonder why
dan
This is great news :)
I find it really interesting that people tries to implement HTML(ish) ways of creating more RIA capabilities, not only that but with the current state of FireFox, Safari and Opera I think Opera is the only real contestant left for Safari in the long run… :(
Safari virtually only needs the plugin architecture from FireFox and the fox is dead… :(
So it’s great to see Opera becoming better…!
(Not only that but it’s also great seeing other great companies here in cold little Norway doing great besides us)
@Dan Tamas: you need this build http://dev.opera.com/articles/view/a-call-for-video-on-the-web-opera-vid/
yes, this one is what i used
i even uninstalled opera 9.24 and put that one…
nothing.
It drives me nuts when browser vendors can’t come to some sort of agreement on standards.
Currently to set the context for a 2d canvas you write:
var myCanvas = $(’canvas’).getContext(’2d’);
So Opera wasn’t arrogant enough to set there version with:
var myCanvas = $(’canvas’).getContext(’3d’);
But rather:
var myCanvas = $(’canvas’).getContext(’opera-3d’);
So it seems to me they are still keeping their options open. If pressured enough Opera may end up rendering .getContent(’3d’) as Firefox does or vice versa.
Also, I imagine the 3d canvas syntax is going to remain the same regardless of the context, so even if two different browsers use a different rendering engine you may still end up with the same or very similar result.
Will see …
*sighs* in dispair.
Not only is it yet another API, no they also went and implemented it against a library (Direct3d) which is only available on one platform alone (Windows). Wasn’t opera intended to be cross platform?
Also the thing about collision detection is pure and utter rubbish, there’s plenty of excelent collision detection engines out there, both commercial and open source. You don’t _have_ to use Direct3d in order to get collision detection.
Maybe it helps to drop another hint…
Ever seen a productivity application (like 3dstudio max, you know, which people keep open all day to work, much like a browser) that uses Direct3d?
I tell you why, because Direct3d makes bloddy unstable applications. Whoever goes for any sort of “real” 3d programming scoffs at the notion of using Direct3d for anything then short lived games.
Yeah, I want to see Opera reimplement Direct3D in Linux. O, wait, they can use Wine for this, just like Borland did the Kylix UI back then… Huge success, never quite understood why they dropped the project.
“makes it easier to implement on non-OpenGL platforms” is a bogus reason, as there is only one platform that Direct3D supports, Windows, _and_ Windows supports OpenGL. This is a super-lame move by Opera. At least say you only had Windows programmers working on it and be honest.
I don’t know why everyone’s up in arms about an experimental implementation of something that’s far from standardization. In fact, none of the 3d contexts will be useful on the Real Web until they’re somewhat emulated in IE (excanvas). Would a Direct3D-like API make that easier? I don’t know anything about 3D APIs.
Opera will once again be ignored by developers for this retarded move
Why’re we up in arms?
Coding on the web means: Dealing with various subtly or wildly different or simply missing APIs/implementations of basic things like DOM, CSS, XHR, javascript, svg, canvas, events, etc.
This has spawned an entire ecosystem of libraries/frameworks that wrap a unified API/hacks/fixes/reimplementations in javascript over basic browser infrastructure just so we can code applications that run more or less everywhere.
We usually put up with it because we don’t have a chance to change it, and when we complain loudly enough at the right places we get told it’s historical and we just have to live with it. OK
Now here we have something brand-new like 3d canvas. And instead of fixing the old mistakes of bloddy once going after one single API/functionality right from the start they go and implement it with widly different features and a wildly different API…
great, what’re we supposed to do? Roll over and get ready for yet another round of 3d javascript frameworks just so we can code against one API?
Thanks.Good article
3D sounds like a lot of fun! Armenian Genocide April 24th 1915.