User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Example program to draw random shapes using the C compiler

Fri Jul 27, 2012 4:35 am

See: https://gist.github.com/3186193 for an example program that draws random shapes on the Raspberry Pi:

smithnerd
Posts: 8
Joined: Thu Jun 14, 2012 1:18 pm

Re: Example program to draw random shapes

Fri Jul 27, 2012 2:33 pm

Very nice!

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 11024
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Example program to draw random shapes

Fri Jul 27, 2012 2:38 pm

seems to be written in C, care to explain to new users how to compile that into a working program?

nice work by the way.

smithnerd
Posts: 8
Joined: Thu Jun 14, 2012 1:18 pm

Re: Example program to draw random shapes

Fri Jul 27, 2012 2:39 pm

gcc -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -L/opt/vc/lib -lGLESv2 demo.c -o demo

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 11024
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Example program to draw random shapes

Fri Jul 27, 2012 2:59 pm

Oooops, glad I asked! :roll: I wouldn't have guessed that string of characters, thats for sure....
Does a new user have to install anything (GCC, libraries) or is everything available (on what distro actually?)

I'm just asking because I can image many people seeing this working for themselves, who may get very frustrated if they cannot get it to work.

smithnerd
Posts: 8
Joined: Thu Jun 14, 2012 1:18 pm

Re: Example program to draw random shapes

Fri Jul 27, 2012 3:17 pm

Works out of the box here, on the latest official Raspbian/wheezy build.

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 11024
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Example program to draw random shapes

Fri Jul 27, 2012 3:19 pm

great!
Its also a nice introduction to C programming then!
Changed the subject title a bit to draw attention to that fact.

smithnerd
Posts: 8
Joined: Thu Jun 14, 2012 1:18 pm

Re: Example program to draw random shapes using the C compil

Sat Jul 28, 2012 3:38 pm

gcc -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -L/opt/vc/lib -lGLESv2 demo.c -o demo


For young players, this may look daunting, but it's really not. It translates as:

gcc - the GNU C compiler command

-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads - the include paths - directories which hold the '.h' files which tell the compiler how to access the Raspberry Pi's low level graphics functionality.

-L/opt/vc/lib - this is the library path. We are specifically telling the compiler about an extra directory, which holds the code that deals with the graphics subsystem.

-lGLESv2 - We wish to use the GLESv2 library (it lives in /opt/vc/lib) . A library is a set of code which has already been developed and compiled. The library is the actual code that the '.h' files above, refer to.

demo.c - the name of the file to compile.

-o demo - the name of the file that the compiler should create. such that one might type:

./demo

...and the programme will run.

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Sun Jul 29, 2012 4:23 am

In this update:

https://gist.github.com/3196007

I've added more shapes (lines, polygon, polyline, cubic and quadratic bezier curves, arc, circles) and the ability to control the number of objects on the command line.

Here's the Makefile:

Code: Select all

shapes:	shapes.c
	cc -Wall -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -o shapes shapes.c  -L/opt/vc/lib -lGLESv2 
to run it:

1) download the gist, save it as shapes.c
2) copy the Makefile to the same directory
3) make && ./shapes 100
4) just press [Enter] to clear the screen and return

During development, on my Mac sitting next the RasPi, I open two terminals and ssh into the RasPi with each. In one terminal, I edit the file, in the other, issue the make && ./shapes command to see the result.

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Sun Jul 29, 2012 9:59 am

Excellent code!

I've been struggling to figure out OpenVG for a few weeks now! So thank you for this!

I was wondering if you could show how to integrate this with SDL, so we can get some Events (and gfx blitting)... Or maybe there is a better (interrupt based, as I hate SDL's event polling architecture) to capture keyboard/mouse events and blitting images when using OpenVG?

Thanks,

Matt

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Sun Jul 29, 2012 10:54 am

I'm having a go at getting this working with SDL... and though I would point out to anyone having a go, that the y axis is inverted from normal (0,0 is bottom left, rather than top left)... took me by surprise, even though I write iPhone apps, hahaha ;-)

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Mon Jul 30, 2012 12:01 am

The code found here: https://gist.github.com/3196007 has been updated to display text using TrueType fonts.

The gist now contains a Makefile and the font2openvg program, which will turn font information into C source that you can embed in your program. The Makefile makes font code from files found in /usr/share/fonts/truetype/ttf-dejavu/. If you want to use other fonts, adjust the Makefile accordingly, or generate them on your own once, the font2openvg program is built.

If you run the program with no command line arguments, you get a "reference card" that demonstrates the calls in the library (Text, Arc, Circle, Ellipse, Rect, Roundrect, Line, Polyline, Polygon, Cubic Bezier, and Quadratic Bezier). Running with a numeric command line argument shows the specified number of random shapes.

Code: Select all

[email protected] ~/vg $ make fonts shapes
g++ -I /usr/include/freetype2 font2openvg.cpp   -o font2openvg -lfreetype
for f in /usr/share/fonts/truetype/ttf-dejavu/*.ttf; do fn=`basename $f .ttf`; ./font2openvg $f $fn.inc $fn; done
224 glyphs written
224 glyphs written
224 glyphs written
224 glyphs written
224 glyphs written
224 glyphs written
cc -Wall -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -o shapes shapes.c -L/opt/vc/lib -lGLESv2
[email protected] ~/vg $ ./shapes # hit return when you are done looking at the awesomness

[email protected] ~/vg $ ./shapes 100 # show 100 random shapes


Tijmenlv
Posts: 1
Joined: Mon Jul 30, 2012 10:12 am

Re: Example program to draw random shapes using the C compil

Mon Jul 30, 2012 10:20 am

You sir should receive a medal. I can see the light now! I have been stuck on hardware accelerated 2d graphics and since OpenVG is very poorly documented YOU MADE MY DAY!

And all of this over the weekend:O love how fast the R pi is developing.

eppe
Posts: 19
Joined: Mon May 14, 2012 12:23 am

Re: Example program to draw random shapes using the C compil

Tue Jul 31, 2012 5:45 am

Thank you very much for posting it Anthony, there is a such a lack of documentation/sample on openvg ...
Thanks again.

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Tue Jul 31, 2012 7:45 am

I couldn't get openVG and SDL to play nicely, so I have added some code to get mouse events from the normal /dev kernel interface.

Which works, and with ajstarks' openVG functions, gives us the beginnings of a 2D graphics framework... but the read() function is rather slow... I will post the code if anyone is interested and able to assist in speeding this up?

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Tue Jul 31, 2012 11:57 am

@bloodline -- the mouse changes seem interesting, Feel free to send a pull request.

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Wed Aug 01, 2012 12:32 am

The documentation has been updated to include the API, using fonts, and building and running:

https://github.com/ajstarks/openvg/blob ... /README.md

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Wed Aug 01, 2012 12:40 am

I will clean up my code and post a patch for mouse input :)

I'm currently reading up on how to replace my current code with an interrupt based version ;)

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Wed Aug 01, 2012 6:10 pm

I don't want to mess with Anthony's GIT repository, so I will let Anthony test and merge the code if he likes it. Here is the mouse code:

There are three parts you need, the includes (put these just after the existing includes):

Code: Select all

#include <linux/input.h>
#include <fcntl.h>
#include <pthread.h>
under the includes you need to add these two parts, they are a mouse variable structure and a the mouse thread code (I run the mouse reading code in a separate thread... at the moment this polls the mouse device, I will replace this with proper interrupt code hopefully soon).

Code: Select all


typedef struct{
	int fd;
	struct input_event ev;
	VGfloat x;
	VGfloat y;
	int left;
	int right;
}mouse_t;

mouse_t mouse;

void* eventThread(void* arg) {

//Open mouse driver

		if ( (mouse.fd = open("/dev/input/event2", O_RDONLY)) < 0) {
			printf("Error opening Mouse!\n");
			quitState=1;
			return &quitState;
		}
		
		printf("Mouse Active!\n");	
	
	//Reset mouse
		mouse.x=0;
		mouse.y=0;

		while(1){
				read(mouse.fd,&mouse.ev,sizeof(struct input_event));

		// Check events
			
			//Reset Mouse button states
				mouse.left=0;
				mouse.right=0;

				if(mouse.ev.type == EV_REL) {

						if(mouse.ev.code==REL_X){
							mouse.x += (VGfloat)mouse.ev.value; 
							if(mouse.x<0){mouse.x=0;} 
							if(mouse.x>1680){mouse.x=1680;}
						}

						if(mouse.ev.code==REL_Y){
							mouse.y -= (VGfloat)mouse.ev.value; 
							if(mouse.y<0){mouse.y=0;} 
							if(mouse.y>1050){mouse.y=1050;}
						} //This ones goes backwards hense the minus
			
				}
			
				if(mouse.ev.type==EV_KEY){
					//printf("Time Stamp:%d - type %d, code %d, value %d\n",mouse.ev.time.tv_usec,mouse.ev.type,mouse.ev.code,mouse.ev.value);
					if(mouse.ev.code==BTN_LEFT){ 
						mouse.left=1;
						printf("User Quit\n");
						quitState=1;
						return &quitState;  //Left mouse to quit
					}
					if(mouse.ev.code==BTN_RIGHT){ 
						mouse.right=1;
					}
				}
	
		}


	}

The final bit of code you need should be put near the top of your main function, before the main loop... this kicks off the mouse reading thread.

Code: Select all

//Start Event Thread
	int err =pthread_create( &inputThread, NULL, &eventThread, NULL);

	if(err != 0){
		printf("Error creating input event thread...");
		return -1;
	}

	printf("Event Thread Started\n");

You now have four variables to use... mouse.x, mouse.y will return the x and y position of the mouse, this is the absolute screen position. The next two variables mouse.left and mouse.right will both == 1 if the button is pressed.

I want to make this a c++ class and interrupt based... watch this space ;)

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Thu Aug 02, 2012 4:34 am

The API has changed, (shape functions don't do their own style), and the code has been cleaned up and refactored (for example the GL state stuff is moved into its own C file, making it easier to understand the higher-level functions.

See: http://github.com/ajstarks/openvg

I got @bloodline's mouse code working as a standalone program, but I have not integrated it yet.

Code: Select all

#include <linux/input.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>

typedef struct
{
    int fd;
    struct input_event ev;
    float x;
    float y;
    int left;
    int right;
} mouse_t;

mouse_t mouse;
int quitState;
float width = 1920, height=1080;

void* eventThread(void* arg) {

//Open mouse driver

    if ( (mouse.fd = open("/dev/input/event2", O_RDONLY)) < 0) {
        printf("Error opening Mouse!\n");
        quitState=1;
        return &quitState;
    }

    printf("Mouse Active!\n");

//Reset mouse
    mouse.x=0;
    mouse.y=0;

    while(1) {
        read(mouse.fd,&mouse.ev,sizeof(struct input_event));
		printf("[%4.0f,%4.0f]\n", mouse.x, mouse.y);

// Check events

//Reset Mouse button states
        mouse.left=0;
        mouse.right=0;

        if(mouse.ev.type == EV_REL) {

            if(mouse.ev.code==REL_X) {
                mouse.x += (float)mouse.ev.value;
                if(mouse.x<0){mouse.x=0;}
                if(mouse.x>width){mouse.x=width;}
            }

            if(mouse.ev.code==REL_Y) {
                mouse.y -= (float)mouse.ev.value;
                if(mouse.y<0){mouse.y=0;}
                if(mouse.y>height){mouse.y=height;}
            }                                     //This ones goes backwards hense the minus

        }

        if(mouse.ev.type==EV_KEY) {
            if(mouse.ev.code==BTN_LEFT) {
                mouse.left=1;
                printf("User Quit\n");
                quitState=1;
                return &quitState;                //Left mouse to quit
            }
            if(mouse.ev.code==BTN_RIGHT) {
                mouse.right=1;
            }
        }
    }
}


void main() {
//Start Event Thread
	pthread_t inputThread;
    int err =pthread_create( &inputThread, NULL, &eventThread, NULL);

    if(err != 0) {
        printf("Error creating input event thread...");
        return -1;
    }

    printf("Event Thread Started\n");
	while (getchar() != '\n') {
		;
	}
}
Compile and run like this:

Code: Select all

cc m.c -o m -lpthread
./m
Event Thread Started
Mouse Active!
if you move the mouse, you see a stream of coordinates

bloodline
Posts: 76
Joined: Sun Jun 10, 2012 8:44 pm
Location: London - England

Re: Example program to draw random shapes using the C compil

Thu Aug 02, 2012 9:54 am

Ah, yes Anthony fixed the missing variables in the code I pasted!

quitState is not required by the code and can be safely removed (it was part of my test app).

Also, I have added keyboard events to my code, so next code update will do more than just mouse events... Also looking into adding the ability to attach user callback functions to events! That should be really useful!

@Anthony: does the removal of style setting in the individual primitive functions afford any performance advantage?
Also I want to look at adding a blitting function perhaps using openGL?

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Thu Aug 02, 2012 11:13 am

The style was removed because sometimes it was not required, and in some cases, it's redundant. For example in a loop you want to set the style once to be applied to subsequent objects. In the cases where you need individual style, you can make a helper function to apply the *precise* style needed---sometimes you want to control fill and stroke, sometime just one or the other.

As to performance, perhaps it helps a small bit. The tradeoff is you have to keep track of the state of style yourself.

I considered making the calls variadic, but that would complicate matters (what order?, do I parse some string representation?) and I was afraid of the the performance hit of processing the variable calls.

The design mirrors how Processing (http://processing.org) works. I have it in the back of my head to make the calls compatible with Processing so that you can port/run Processing sketches on the Raspi.

I also have been thinking about making a Go library via cgo. There I can more easily mimic the behavior of SVGo. (http://github.com/ajstarks/svgo). I can add the variadic style processing at that level, including having an optional style specification, say one that is compatible with CSS.

The client code for such a library might look like this.

Code: Select all

import "github.com/ajstarks.openvg"
func main() {
    width, height  := 500, 500
    openvg.Init()
    openvg.Start(width, height, "black")
    openvg.Circle(100,100,20, "fill:red")
    openvg.Setfill("bliue")
    r := 20
    for i:=0; i < width; i+=25 {
        openvg.Circle(i, 200, r)
    }
    openvg.End()
    openvg.Finish()
}
 

User avatar
ajstarks
Posts: 129
Joined: Fri Jun 22, 2012 2:14 am

Re: Example program to draw random shapes using the C compil

Fri Aug 03, 2012 2:08 am

The API now includes transformations: Translate, Scale, Rotate, and Shear.
Running the shapes program with two arguments:

./shapes 20 a

shows the character "a" rotated 20 times around the center of the screen.

Here's the function:

Code: Select all

void rotext(VGfloat x, VGfloat y, int w, int h, int n, VGfloat deg, char *s) {
    int i;
    VGfloat textcolor[4] = {0,0,0,1}, bgcolor[4] = {1,1,1,1};
    VGfloat fade = (100.0/(VGfloat)n)/100.0;

    Start(w, h, bgcolor);
    Translate(x,y);
    for (i=0; i < n; i++) {
        Text(0,0, s, 256, textcolor, DejaVuSansPaths, DejaVuSans_characterMap,  DejaVuSans_glyphAdvances, VG_FILL_PATH);
        textcolor[3] -= fade;
        Rotate(deg);
    }
    End();
}


Return to “OpenVG”