C-style rendering?

22 views
Skip to first unread message

rhoam.ba...@gmail.com

unread,
Apr 4, 2017, 11:05:06 PM4/4/17
to CodenameOne Discussions
Hello! This is a bit of a Java question + a Codename One question. I'm migrating a project from another library that uses C to Codename One's API. Here is an example of how I do it currently, starting with the function prototype:

void Draw(_Texture *tex,    // Source texture
          _Rect *src,       // Which pixels in the texture will we be copying?
          _Rect *dst        // At what x/y will we be placing these pixels on the screen?
         );

Then, let's say I have an optimized sprite sheet with a _Rect array that specifies where every sprite on the sprite sheet is:

_Rect sprite[]={
    { 0, 0, 46, 49 },    // Stand Right
    { 46, 0, 15, 15 },   // Walk Right 1
    { 46, 15, 15, 15 },  // Walk Right 2
    { 46, 30, 15, 17 },  // Stand Left
    { 102, 20, 15, 17 }, // Walk Left 1
    { 117, 20, 15, 17 }  // Walk Left 2
};

And the player is at a position that is always changing:

_Rect playerRect={Player.x,Player.y};

The final function call would look like:

Draw(Player.tex,&sprite[Player.sprite],&playerRect);

This has proven to be an incredibly fast and portable solution for me, which I have used for some Wii homebrew apps for fun. It's sort of a write-once, compile anywhere solution. With some #ifdefs, the contents of "Draw" change based on the target platform, but the function always takes the same arguments and handles them in a multi-platform way. However, extending my API (if you can even call it that) to work on Android and iOS... no need for that when projects like Codename One exist. :)

Can I please get a simple runnable example that does something like this? I have been digging through the documentation for a couple of days now and none of the Frankenstein code I'm writing so far works. I'm trying to make it so it has this redraw loop going 30 or 60 frames per second where objects get evaluated and can move every frame, that way, it can be more familiar to the workflow I'm adjusted to than putting animation frames in form labels and the like.

I also think an example like this would make Codename One more accessible for newcomers who want to use it to make simple 2D games, where manually handling on-screen objects in this way is preferable and offers more control over the end result. :)

Anyone care to help a CN1 n00b out? :)

Steve Hannah

unread,
Apr 5, 2017, 1:29:56 PM4/5/17
to codenameone...@googlegroups.com
You can achieve this sort of thing by creating a custom Component and implementing the "paint" method in it.  Codename One's EDT maintains a refresh loop that you can tap into to trigger your paint method.

Your paint() method is passed a Graphics object which includes functionality to draw graphics primitives, like shapes, text, and images.  

This series of blog posts describes this process.  The last one in the list deals with animation.  The first two, with drawing to Graphics.


Best regards

Steve


--
You received this message because you are subscribed to the Google Groups "CodenameOne Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codenameone-discussions+unsub...@googlegroups.com.
Visit this group at https://groups.google.com/group/codenameone-discussions.
To view this discussion on the web visit https://groups.google.com/d/msgid/codenameone-discussions/d91cba10-2ff0-4d4d-96bb-1e9dc247d23f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Steve Hannah
Software Developer
Codename One

rhoam.ba...@gmail.com

unread,
Apr 5, 2017, 3:02:11 PM4/5/17
to CodenameOne Discussions
This is exactly what I was looking for, thank you so much for taking the time to help me out, Steve! :) I'd like to ask a few more questions if that's okay, just to get some clarification on a few things!

Is there any documentation regarding the performance of the low-level drawing routines? One thing I like is how pixel-perfect the scaling on pixel art turns out when using drawImage and manually specifying a width and height. The result is so much more crisp than what can be achieved with multi-resolution images. As a Codename One developer, do you think it is way more expensive handle rendering this way instead of using muti-res, or is it about the same?

How performant is it to do something like, say, an array of images? Would this be undefined behavior? drawImage(testimage[3],objx,objy), for example.

Finally, Image.getWidth and Image.getHeight: how expensive are these? Do they have to poll the GPU, or are image width and height stored on the CPU and these are light operations? I ask because I noticed that scale(x,y) isn't 100% portable yet due to limited Affine support, so instead of setting scale(logicalsize,logicalsize) to change the logical draw size, a developer could do something like drawImage(testimage,objx*logicalsize,objy*logicalsize,testimage.getWidth*logicalsize,testimage.getHeight*logicalsize) as an alternative. But only if these are not expensive and/or slow operations to perform?

Of the many write-once-build-anywhere frameworks I have tested so far, Codename One feels the most powerful (especially when it comes to load times and performance) while also being the most affordable. Not to mention, other frameworks have this really spaghetti-looking code and little to no low-level drawing access. I haven't delved too deeply into CN1 yet, of course, but from my impressions so far, I definitely gravitate towards it the most. It's also a business model that I can see myself supporting. This team, this project, you guys are doing something incredible here. :)

Steve Hannah

unread,
Apr 6, 2017, 12:54:36 PM4/6/17
to codenameone...@googlegroups.com
On Wed, Apr 5, 2017 at 12:02 PM, <rhoam.ba...@gmail.com> wrote:
This is exactly what I was looking for, thank you so much for taking the time to help me out, Steve! :) I'd like to ask a few more questions if that's okay, just to get some clarification on a few things!

Is there any documentation regarding the performance of the low-level drawing routines? One thing I like is how pixel-perfect the scaling on pixel art turns out when using drawImage and manually specifying a width and height. The result is so much more crisp than what can be achieved with multi-resolution images. As a Codename One developer, do you think it is way more expensive handle rendering this way instead of using muti-res, or is it about the same?

I haven't don't any profiling on this myself, so I'm not sure the difference in performance.  The performance will likely vary by platform a little bit.
 

How performant is it to do something like, say, an array of images? Would this be undefined behavior? drawImage(testimage[3],objx,objy), for example.

Keeping images in an array should not impact performance in any way (vs just keeping them in variables). While accessing an array index is an extra lookup vs using a local variable, that lookup is negligible compared to the task of drawing the image.
 

Finally, Image.getWidth and Image.getHeight: how expensive are these? Do they have to poll the GPU, or are image width and height stored on the CPU and these are light operations? I ask because I noticed that scale(x,y) isn't 100% portable yet due to limited Affine support, so instead of setting scale(logicalsize,logicalsize) to change the logical draw size, a developer could do something like drawImage(testimage,objx*logicalsize,objy*logicalsize,testimage.getWidth*logicalsize,testimage.getHeight*logicalsize) as an alternative. But only if these are not expensive and/or slow operations to perform?

getWidth() and getHeight() should be fast.  It doesn't need to hit the GPU.


Best regards

Steve

rhoam.ba...@gmail.com

unread,
Apr 6, 2017, 2:39:16 PM4/6/17
to CodenameOne Discussions
Thank you again, Steve, you have been very helpful! :)
Reply all
Reply to author
Forward
0 new messages