Wednesday, April 7, 2010

eSCALAtion Blog Interview

I was asked to give a brief interview with the Scala blog "eSCALAtion" regarding sgine. Here is the link: http://dgronau.wordpress.com/2010/04/05/interview-with-matt-hicks/

Monday, April 5, 2010

Beginnings of Components

Last week I made a new post daily outlining the work of the day, showing a screenshot of the progress, and posting a code sample. This past weekend I didn't post anything, but not because I wasn't working hard, but because primarily what I was working on had no real visual presence. A quick look at the change log for Mercurial will show significant increase in code being checked in: see!

Last week I showed how nicely both images and text can be displayed to the screen with relatively little amounts of code, but that code is not very practical from a modularity and simplicity perspective. The goal was never for developers to rely specifically on that functionality but to work as a core to build upon within sgine to provide more powerful abstractions for developers to use in order to develop with simplicity and logically.

This past weekend I spent quite a bit of time working on what I consider to be the fulfillment of that objective (or at least the beginning of) through the use of what I call Components. Components in sgine are sort of a hybrid between what would classically be a Node/Spatial in a 3D scenegraph and a Component / Widget in a standard GUI like Swing. There will be much more coming soon on this topic, but for now I'll leave you with a very short snippet to portray the same as my original example did of the puppies but using the Image component in sgine:

package org.sgine.ui

import org.sgine.core.Resource

import org.sgine.easing.Elastic

import org.sgine.property.adjust.EasingNumericAdjuster

import org.sgine.render.Renderer
import org.sgine.render.scene.RenderableScene

import org.sgine.scene.GeneralNodeContainer

object TestImage {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test RenderScene")
  
  val scene = new GeneralNodeContainer()
  val component = new Image()
  component.location.z := -1000.0
  component.source := Resource("resource/puppies.jpg")
  scene += component
  
  r.renderable := RenderableScene(scene)
 }
}

Friday, April 2, 2010

Font Testing

I think I'm just about done with the first pass on bitmap font work. I still need to provide convenience methods for determining size of blocks of text and paragraph support as well as creating a system to dynamically generate bitmapped fonts via AWT at runtime, but I think I've finally knocked out all the major bugs. Here is a prettier example using the AngelCode fonts I've been working on:



Finally starting to look like something useful and less like a crappy hobby project, but still a long way to go. Anyway, here's the source:

package org.sgine.render

import org.sgine.math.mutable.Matrix4

import javax.imageio.ImageIO

import org.lwjgl.opengl.GL11._

import scala.io.Source

object TestFonts {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test Fonts")

  val franklinFont = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/Franklin.fnt")), getClass.getClassLoader.getResource("resource/Franklin.png"))
  val arialFont = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/Arial.fnt")), getClass.getClassLoader.getResource("resource/Arial.png"))
  val lcdFont = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/lcd.fnt")), getClass.getClassLoader.getResource("resource/lcd.png"))
  
  val m1 = Matrix4().translate(x = -400.0, z = -1000.0)
  val m2 = Matrix4().translate(x = -100.0, y = -50.0, z = -1000.0)
  val fps = FPS(1.0, lcdFont)
  
  val a = new Array[() => Unit](5)
  a(0) = MatrixState(m1)
  a(1) = () => franklinFont.drawString("Franklin Gothic Heavy with a blue gradient.", true)
  a(2) = MatrixState(m2)
  a(3) = () => arialFont.drawString("Standard Arial", false)
  a(4) = fps
  r.renderable := RenderList(a)
 }
}

AngelCode Fonts - Kerning

I already did most of the legwork earlier this week, but hadn't gotten around to turning on support for kerning, but that's all changed now:



Pretty easy to see the benefits of kerning here. However, this example also shows I seem to have a little problem with my low-hanging characters like 'g' and 'p'. Hopefully that will be fixed in the next update.

For now, here's the source:

package org.sgine.render

import org.sgine.math.mutable.Matrix4

import javax.imageio.ImageIO

import org.lwjgl.opengl.GL11._

import scala.io.Source

object TestFonts {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test Fonts")
  
  val m1 = Matrix4().translate(x = -200.0, z = -1000.0)
  val m2 = Matrix4().translate(x = -200.0, y = -25.0, z = -1000.0)
  val fps = FPS(1.0)
  
  val font = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/Arial.fnt")), getClass.getClassLoader.getResource("resource/Arial.png"))
  
  val a = new Array[() => Unit](5)
  a(0) = MatrixState(m1)
  a(1) = () => font.drawString("VAST Kerning Example Enabled", true)
  a(2) = MatrixState(m2)
  a(3) = () => font.drawString("VAST Kerning Example Disabled", false)
  a(4) = fps
  r.renderable := RenderList(a)
 }
}

A couple more days of effort and we can hopefully dig into some much more interesting features. :)

Wednesday, March 31, 2010

AngelCode Fonts - Second Steps

I was determined to get some more work done on this today after my sorry screenshot I posted last night. I've added parsing support to kerning but have not implemented it graphically. Hopefully I'll get around to that tomorrow. However, the xOffset, yOffset, and xAdvance functionality is working now and I have a much better screenshot to post:



I've also cleaned up the process by adding a "drawString" method to AngelCodeFont. See the following example code:

package org.sgine.render

import org.sgine.math.mutable.Matrix4

import javax.imageio.ImageIO

import org.lwjgl.opengl.GL11._

import scala.io.Source

object TestFonts {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test Fonts")
  
  val m = Matrix4().translate(x = -70.0, z = -1000.0)
  val fps = FPS(1.0)
  
  val font = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/Arial.fnt")), getClass.getClassLoader.getResource("resource/Arial.png"))
  
  val a = new Array[() => Unit](3)
  a(0) = MatrixState(m)
  a(1) = () => font.drawString("Hello World!")
  a(2) = fps
  r.renderable := RenderList(a)
 }
}

Tuesday, March 30, 2010

AngelCode Fonts - First Steps

I spent a little bit of time the past couple of evenings writing a parser in Scala to process AngelCode font files so sgine could support bitmap fonts and though the actual results look a bit sad, the progress is quite nice. :)

Now, I know this looks ugly, but for a combined time of less than two hours I think it's some decent progress:



You'll notice the x and y offsets are not specified, and I sort of hard-coded multi-character rendering, but still, it's a start. :)

Here's the code required:
package org.sgine.render

import org.sgine.math.mutable.Matrix4

import javax.imageio._

import org.lwjgl.opengl.GL11._

import scala.io.Source

object TestFonts {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test Fonts")
  
  val m = Matrix4().translate(z = -1000.0)
  val fps = FPS(1.0)
  
  val font = AngelCodeFont(Source.fromURL(getClass.getClassLoader.getResource("resource/Arial.fnt")), getClass.getClassLoader.getResource("resource/Arial.png"))
  
  val a = new Array[() => Unit](13)
  a(0) = MatrixState(m)
  a(1) = () => font('H').draw(-60.0)
  a(2) = () => font('e').draw(-40.0)
  a(3) = () => font('l').draw(-20.0)
  a(4) = () => font('l').draw(0.0)
  a(5) = () => font('o').draw(20.0)
  a(6) = () => font(' ').draw(40.0)
  a(7) = () => font('W').draw(60.0)
  a(8) = () => font('o').draw(80.0)
  a(9) = () => font('r').draw(100.0)
  a(10) = () => font('l').draw(120.0)
  a(11) = () => font('d').draw(140.0)
  a(12) = fps
  r.renderable := RenderList(a)
  
  println("Renderer started! " + 81.asInstanceOf[Char] + " - " + font.face + ", " + font.size)
 }
}

Next step is to properly support drawing of Strings correctly. More to come soon.

Sunday, March 28, 2010

Replacement Renderer

Not really a lot to see at the moment. The engine has been taken apart and put back together a few times, but finally I think we're going to start making some serious progress. To that end I'm planning on documenting here as things progress.

I've just recently completely started over with renderer in sgine and am getting pretty nice framerates even if I am just rendering an image of my two puppies:



Over the next few weeks the UI framework will be coming together hopefully along with much of the functionality I had previously written in to jSeamless.

Here's the code required:

package org.sgine.render

import org.sgine.math.Matrix4

import javax.imageio._

import org.lwjgl.opengl.GL11._

object TestRenderer {
 def main(args: Array[String]): Unit = {
  val r = Renderer.createFrame(1024, 768, "Test Renderer")
  
  val t = new Texture(700, 366)
  TextureUtil(t, ImageIO.read(getClass.getClassLoader.getResource("resource/puppies.jpg")), 0, 0, 700, 366)
  
  val m = Matrix4().translate(z = -1000.0)
  val i = Image(t)
  val fps = FPS(1.0)
  
  r.renderable := RenderList(MatrixState(m) :: i :: fps :: Nil)
  
  println("Renderer started!")
 }
}

Stay tuned.
Scala Engine for high-performance interactive applications.