TextureCube
One more example taken from the Processing examples, this time drawing a simple textured 3D cube which you can rotate by dragging the mouse.
Processing / Java
/**
* Texture Cube
* by Dave Bollinger.
*
* Drag mouse to rotate cube. Demonstrates use of u/v coords in
* vertex() and effect on texture(). The textures get distorted using
* the P3D renderer as you can see, but they look great using OPENGL.
*/
PImage tex;
float rotx = PI/4;
float roty = PI/4;
void setup() {
size(640, 360, P3D);
tex = loadImage("berlin-1.jpg");
textureMode(NORMAL);
fill(255);
}
void draw() {
background(255);
noStroke();
translate(width/2.0, height/2.0, -80);
rotateX(rotx);
rotateY(roty);
scale(90);
TexturedCube(tex);
}
void TexturedCube(PImage tex) {
beginShape(QUADS);
texture(tex);
// Given one texture and six faces, we can easily set up the uv coordinates
// such that four of the faces tile "perfectly" along either u or v, but the other
// two faces cannot be so aligned. This code tiles "along" u, "around" the X/Z faces
// and fudges the Y faces - the Y faces are arbitrarily aligned such that a
// rotation along the X axis will put the "top" of either texture at the "top"
// of the screen, but is not otherwised aligned with the X/Z faces. (This
// just affects what type of symmetry is required if you need seamless
// tiling all the way around the cube)
// +Z "front" face
vertex(-1, -1, 1, 0, 0);
vertex( 1, -1, 1, 1, 0);
vertex( 1, 1, 1, 1, 1);
vertex(-1, 1, 1, 0, 1);
// -Z "back" face
vertex( 1, -1, -1, 0, 0);
vertex(-1, -1, -1, 1, 0);
vertex(-1, 1, -1, 1, 1);
vertex( 1, 1, -1, 0, 1);
// +Y "bottom" face
vertex(-1, 1, 1, 0, 0);
vertex( 1, 1, 1, 1, 0);
vertex( 1, 1, -1, 1, 1);
vertex(-1, 1, -1, 0, 1);
// -Y "top" face
vertex(-1, -1, -1, 0, 0);
vertex( 1, -1, -1, 1, 0);
vertex( 1, -1, 1, 1, 1);
vertex(-1, -1, 1, 0, 1);
// +X "right" face
vertex( 1, -1, 1, 0, 0);
vertex( 1, -1, -1, 1, 0);
vertex( 1, 1, -1, 1, 1);
vertex( 1, 1, 1, 0, 1);
// -X "left" face
vertex(-1, -1, -1, 0, 0);
vertex(-1, -1, 1, 1, 0);
vertex(-1, 1, 1, 1, 1);
vertex(-1, 1, -1, 0, 1);
endShape();
}
void mouseDragged() {
float rate = 0.01;
rotx += (pmouseY-mouseY) * rate;
roty += (mouseX-pmouseX) * rate;
}
OPENRNDR / Kotlin
Assets
Imports
import org.openrndr.WindowMultisample
import org.openrndr.application
import org.openrndr.draw.DepthTestPass
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.loadImage
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.meshgenerators.boxMesh
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
fun main() = application {
configure {
width = 640
height = 360
multisample = WindowMultisample.SampleCount(2)
}
program {
val cube = boxMesh()
var rot = Vector2(45.0)
val tex = loadImage("data/images/berlin-1.jpg")
extend {
drawer.perspective(60.0, width * 1.0 / height, 0.01, 1000.0)
drawer.depthWrite = true
drawer.depthTestPass = DepthTestPass.LESS_OR_EQUAL
drawer.shadeStyle = shadeStyle {
fragmentTransform = "x_fill = texture(p_tex, va_texCoord0.xy);"
parameter("tex", tex)
}
drawer.translate(0.0, 0.0, -150.0)
drawer.rotate(Vector3.UNIT_X, rot.x)
drawer.rotate(Vector3.UNIT_Y, rot.y)
drawer.scale(90.0)
drawer.vertexBuffer(cube, DrawPrimitive.TRIANGLES)
}
mouse.dragged.listen {
val rate = 0.5
rot += it.dragDisplacement.yx * rate
}
}
}
Concept | Processing | OPENRNDR |
---|---|---|
graphics mode | choose between JAVA2D (default), P2D, P3D and others | one mode only, works for 2D and 3D |
view type | perspective by default | orthographic by default, therefore we call drawer.perspective which also centers the origin |
multisampling | calls smooth(N) by default |
you can set multisample inside configure
|
depth writing | enabled by default | must be enabled in 3D, otherwise objects far away may appear in front of objects which are closer |
creating a cube with texture (uv) coordinates | not built-in. you need to write your own or use a library | provided by orx-mesh-generators via the boxMesh() method |
texture mapping shader | by calling texture()
|
by setting a GLSL shadeStyle
|
drawing an existing mesh |
shape() , but this sketch reconstructs the cube on every animation frame instead |
drawer.vertexBuffer() |
rotations | expressed in radians | expressed in degrees |
To obtain a similar effect when dragging the mouse we use different values: 0.5 degrees vs 0.01 radians (per dragged pixel). If we would rotate 0.01 degrees per pixel the effect might be too subtle to notice.
OPENRNDR sets up less defaults for us and we must therefore write a few extra lines. On the other hand it comes with many extensions providing very powerful features.
Share your questions and comments below | Find other OPENRNDR & Processing posts