例: テクスチャ座標を指定した render-primitive の使用 | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} {define-proc {primitive-proc rg:Renderer3dGraphic, ren:Renderer3d, area:#RectangleSet}:void let d:Drawable={non-null rg.drawable} let fp:FillPattern = {FillPattern.from-url {url "curl://install/docs/default/images/adria.jpg"}} set ren.texture = {fp.to-Texture} {render-primitive p:Primitive, type=Primitive.triangles on ren do {p.texture-coord2 0.0, 0.0} {p.vertex2 0in, 1in} {p.texture-coord2 1.0, 0.0} {p.vertex2 1in, 0in} {p.texture-coord2 1.0, 1.0} {p.vertex2 1in, 2in} {p.texture-coord2 0.0, 0.0} {p.vertex2 1in, 0in} {p.texture-coord2 1.0, 0.0} {p.vertex2 1in, 2in} {p.texture-coord2 1.0, 1.0} {p.vertex2 2in, 1in} } } ||create a Renderer3dGraphic, ||passing that procedure as repaint-handler {Renderer3dGraphic repaint-handler=primitive-proc} |
例: render-vertices メソッドの使用 | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} ||define a simple repaint handler procedure {define-proc {primitive-proc rg:Renderer3dGraphic, ren:Renderer3d, area:#RectangleSet}:void let d:Drawable={non-null rg.drawable} let vertices:{FastArray-of FloatDistance3d} = {new {FastArray-of FloatDistance3d}, {FloatDistance3d 0f(in), 1f(in), 0f(in)}, {FloatDistance3d 1f(in), 0f(in), 0f(in)}, {FloatDistance3d 1f(in), 2f(in), 0f(in)}, {FloatDistance3d 1f(in), 0f(in), 0f(in)}, {FloatDistance3d 1f(in), 2f(in), 0f(in)}, {FloatDistance3d 2f(in), 1f(in), 0f(in)} } let colors:{FastArray-of Pixel} = {new {FastArray-of Pixel}, {Pixel.create 1, 0, 0, alpha = 0}, {Pixel.create 1, 0, 0, alpha = 0}, {Pixel.create 1, 0, 0, alpha = 0}, {Pixel.create 0, 1, 0, alpha = 0}, {Pixel.create 0, 1, 0, alpha = 0}, {Pixel.create 0, 1, 0, alpha = 0} } {ren.render-vertices Primitive.triangles, vertices, color-array = colors } } ||create a Renderer3dGraphic, ||passing that procedure as repaint-handler {Renderer3dGraphic repaint-handler=primitive-proc} |
例: cull-face-enabled? の使用 | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} {define-proc {primitive-proc rg:Renderer3dGraphic, ren:Renderer3d, area:#RectangleSet}:void let d:Drawable={non-null rg.drawable} set ren.cull-face-enabled? = true ||Uncomment the following line to cull the front facing ||(green) face instead of the back facing (red) face ||set ren.cull-face = Cull.front {render-primitive p:Primitive, type=Primitive.triangles on ren do {p.color3 1.0, 0, 0} || red {p.vertex2 0in, 1in} {p.vertex2 1in, 0in} {p.vertex2 1in, 2in} {p.color3 0, 1.0, 0} || green {p.vertex2 1in, 0in} {p.vertex2 1in, 2in} {p.vertex2 2in, 1in} } } {Renderer3dGraphic repaint-handler=primitive-proc} |
例: 正投影と透視投影 | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} {let (r:Renderer3d, d:Drawable) = {Renderer3d.create-offscreen 10cm, 10cm, resolution=100dpi}} {define-proc {draw3D what-projection:int=0}:void {r.clear color={Palette.get-black}, depth=1} {if what-projection == 0 then {r.projection-matrix.ortho -5cm, 5cm, || X extents (left/right) 5cm, -5cm, || Y extents (bottom/top) -50cm, 50cm || Z extents (near/far) } else {r.projection-matrix.frustum -1.5cm, 1.5cm, || X extents (left/right) 1.5cm, -1.5cm, || Y extents (bottom/top) 2cm, 25cm || Z extents (near/far) } } {r.modelview-matrix.load-identity} {r.modelview-matrix.translate -5cm, -5cm, 0cm} {r.modelview-matrix.scale 1, 1, -1} set r.depth-test-enabled? = true set r.depth-function = Compare.less {render-primitive p:Primitive, type="triangles" on r do || render the first triangle (blue) {p.color3 0.0, 0.0, 1.0} {p.vertex3 0cm, 0cm, 5cm} {p.vertex3 0cm, 10cm, 5cm} {p.vertex3 10cm, 10cm, 5cm} || render the second triangle (red) {p.color3 1.0, 0.0, 0.0} {p.vertex3 10cm, 0cm, 15cm} {p.vertex3 0cm, 0cm, 15cm} {p.vertex3 0cm, 10cm, 15cm} } } {draw3D what-projection = 0} {let ortho-backgrnd:Pixmap = {d.to-Pixmap}} {draw3D what-projection = 1} {let pers-backgrnd:Pixmap = {d.to-Pixmap}} {spaced-hbox {VBox "Orthographic:", {value {Frame width=2in, height=2in, background=ortho-backgrnd } } }, {VBox "Perspective (frustum):", {value {Frame width=2in, height=2in, background=pers-backgrnd } } } } {d.destroy} |
{renderer.modelview-matrix.translate 0m, 0m, -5m}
{renderer.projection-matrix.ortho 0in, width, || x extents, left and right height, 0in,|| y extents, bottom and top -1in, || the near plane 1in || the far plane. || near and far are relative || to the eye position: 0, 0, 0 }
例: モデルビュー マトリックスを使用した三角形の回転 | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} {define-class public ExampleObject {inherits BaseFrame} field rotation-angle:Angle = 0deg field rg:Renderer3dGraphic field public _timer:Timer {constructor public {default ...} set self.rg = {Renderer3dGraphic repaint-handler= {proc {rg:Renderer3dGraphic, ren:Renderer3d, area:#RectangleSet }:void {self.redraw-proc ren} }, ...} {self.add-internal self.rg} {construct-super ...} set self._timer = {self.rg.animate frequency=30fps, repeat = 0, {on TimerEvent do {self.rg.update-drawable} } } } {method {draw-a-triangle ren:Renderer3d}:void {render-primitive p:Primitive, type=Primitive.triangles on ren do {p.color3 1, 0, 0} {p.vertex3 -1in, 1in, 0in} {p.color3 0, 1, 0} {p.vertex3 0in, -1in, 0in} {p.color3 0, 0, 1} {p.vertex3 1in, 1in, 0in} } } {method {redraw-proc ren:Renderer3d}:void {ren.clear} {ren.projection-matrix.ortho -2in, 2in, || left, right -2in,2in, || bottom, top 0in, 3in || "near" and "far" are distances from the eye } {ren.modelview-matrix.load-identity} || Next line moves the model away from || the eye position (which is 0, 0, 0) {ren.modelview-matrix.translate 0in, 0in, -2in} {ren.modelview-matrix.rotate {Direction3d 0, 1, 0}, self.rotation-angle} || {ren.modelview-matrix.rotate {Direction3d 1, 0, 0}, self.rotation-angle} || {ren.modelview-matrix.rotate {Direction3d 0, 0, 1}, self.rotation-angle} {self.draw-a-triangle ren} || Increment or decrement the angle by 1 deg so that the object spins {if self.rotation-angle >= 0deg then {inc self.rotation-angle, 1deg} else {dec self.rotation-angle, 1deg} } } } {value let example-obj:ExampleObject = {ExampleObject width = 2in, height = 2in} example-obj let switch:CommandButton = {CommandButton label="Start", width=0.75in, {on Action do {if example-obj._timer.repeat == 0 then set example-obj._timer.repeat = -1 set switch.label = "Stop" else set example-obj._timer.repeat = 0 set switch.label = "Start" } } } {VBox example-obj, switch } } |
例: スピンする正六面体のレンダリング | |
![]() | |
{import * from CURL.GRAPHICS.RENDERER3D} || Define a class SpinCube that "has a" Renderer3dGraphic {define-class public SpinCube {inherits BaseFrame} field left-top-back-vertex:Distance3d = {Distance3d -1in, 1in, -1in} field right-top-back-vertex:Distance3d = {Distance3d 1in, 1in, -1in} field right-top-front-vertex:Distance3d = {Distance3d 1in, 1in, 1in} field left-top-front-vertex:Distance3d = {Distance3d -1in, 1in, 1in} field left-bottom-back-vertex:Distance3d = {Distance3d -1in, -1in, -1in} field right-bottom-back-vertex:Distance3d = {Distance3d 1in, -1in, -1in} field right-bottom-front-vertex:Distance3d = {Distance3d 1in, -1in, 1in} field left-bottom-front-vertex:Distance3d = {Distance3d -1in, -1in, 1in} field cube-angle:Angle = 0deg field _alpha:Fraction = 1.0 field _face:Texture field rg:Renderer3dGraphic field public _timer:Timer {constructor public {default face:FillPattern={url "../../default/images/generic.gif"}, ...} set self._face = {face.to-Texture} set self.rg = {Renderer3dGraphic repaint-handler= {proc {rg:Renderer3dGraphic, ren:Renderer3d, area:#RectangleSet }:void {self.redraw-proc ren} }, ...} {self.add-internal self.rg} {construct-super ...} set self._timer = {self.rg.animate frequency=30fps, repeat = 0, {on TimerEvent do {self.rg.update-drawable} } } } {method {draw-quad renderer:Renderer3d, vertex-0:Distance3d, vertex-1:Distance3d, vertex-2:Distance3d, vertex-3:Distance3d, color-0:Fraction3d, alpha:double }:void || Clamp the alpha channel to zero (fully transparent) if the || given parameter is less than zero. {if alpha < 0.0 then set alpha = 0.0} || Add 4 vertices {render-primitive p:Primitive, type=Primitive.quads on renderer do {p.color4 color-0.x, color-0.y, color-0.z, alpha} {p.texture-coord2 0, 1} {p.vertex3v vertex-3} {p.texture-coord2 1, 1} {p.vertex3v vertex-2} {p.texture-coord2 1, 0} {p.vertex3v vertex-1} {p.texture-coord2 0, 0} {p.vertex3v vertex-0} } } {method {redraw-proc renderer:Renderer3d}:void || Clear window graphic with background color {renderer.clear color={Color.from-rgb 0.8, 0.8, 0.8}} || uncomment the next line to see 'inside' the cube || set renderer.cull-face = Cull.front set renderer.cull-face-enabled? = true || The following calls enable transparency (alpha blending) set renderer.blend-enabled? = true set renderer.blend-src-function = Blend.src-alpha set renderer.blend-dst-function = Blend.one-minus-src-alpha || Render in perspective {renderer.projection-matrix.frustum -0.5in, 0.5in, || left, right -0.5in, 0.5in, || bottom, top || "near" and "far" are distances from the eye position (for frustum) 1in, 10in } {renderer.modelview-matrix.load-identity} || This moves the model away from the eye position (which is 0, 0, 0) {renderer.modelview-matrix.translate 0in, 0in, -5in} || This rotates the whole cube along the y-axis by cube-angle {renderer.modelview-matrix.rotate {Direction3d 0, 1, 0}, self.cube-angle} || This rotates the whole cube along the z-axis by 30deg {renderer.modelview-matrix.rotate {Direction3d 0, 0, 1}, -45deg} || Sets the texture to use. set renderer.texture = self._face || Draw the front face of the cube, blended with a white background. {self.draw-quad renderer, self.left-bottom-front-vertex, self.left-top-front-vertex, self.right-top-front-vertex, self.right-bottom-front-vertex, {Fraction3d 1, 1, 1}, self._alpha } || Draw the back face of the cube, blended with a yellow background. {self.draw-quad renderer, self.left-top-back-vertex, self.left-bottom-back-vertex, self.right-bottom-back-vertex, self.right-top-back-vertex, {Fraction3d 1, 1, 0}, self._alpha } || Draw the bottom face of the cube, blended with a red background. {self.draw-quad renderer, self.left-bottom-back-vertex, self.left-bottom-front-vertex, self.right-bottom-front-vertex, self.right-bottom-back-vertex, {Fraction3d 1, 0, 0}, self._alpha } || Draw the top face of the cube, blended with a green background. {self.draw-quad renderer, self.left-top-front-vertex, self.left-top-back-vertex, self.right-top-back-vertex, self.right-top-front-vertex, {Fraction3d 0, 1, 0}, self._alpha } || Draw the right face of the cube, blended with a blue background. {self.draw-quad renderer, self.right-bottom-back-vertex, self.right-bottom-front-vertex, self.right-top-front-vertex, self.right-top-back-vertex, {Fraction3d 0, 0, 1}, self._alpha } || Draw the left face of the cube, blended with a purple background. {self.draw-quad renderer, self.left-bottom-front-vertex, self.left-bottom-back-vertex, self.left-top-back-vertex, self.left-top-front-vertex, {Fraction3d 1, 0, 1}, self._alpha } || Increment the angle by 1 deg so that the cube spins {if self.cube-angle >= 0deg then {inc self.cube-angle, 1deg} else {dec self.cube-angle, 1deg} } } } {value let my-cube:SpinCube = {SpinCube} let switch:CommandButton = {CommandButton label="Spin", width=0.75in, {on Action do {if my-cube._timer.repeat == 0 then set my-cube._timer.repeat = -1 set switch.label = "Stop" else set my-cube._timer.repeat = 0 set switch.label = "Spin" } } } {spaced-vbox halign="center", my-cube, {HBox {Fill}, switch, {Fill}} } } |