Page 1 of 3

Example program to draw random shapes using the C compiler

Posted: Fri Jul 27, 2012 4:35 am
by ajstarks
See: https://gist.github.com/3186193 for an example program that draws random shapes on the Raspberry Pi:

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 2:33 pm
by smithnerd
Very nice!

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 2:38 pm
by mahjongg
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.

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 2:39 pm
by smithnerd
gcc -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -L/opt/vc/lib -lGLESv2 demo.c -o demo

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 2:59 pm
by mahjongg
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.

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 3:17 pm
by smithnerd
Works out of the box here, on the latest official Raspbian/wheezy build.

Re: Example program to draw random shapes

Posted: Fri Jul 27, 2012 3:19 pm
by mahjongg
great!
Its also a nice introduction to C programming then!
Changed the subject title a bit to draw attention to that fact.

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

Posted: Sat Jul 28, 2012 3:38 pm
by smithnerd
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.

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

Posted: Sun Jul 29, 2012 4:23 am
by ajstarks
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.

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

Posted: Sun Jul 29, 2012 9:59 am
by bloodline
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

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

Posted: Sun Jul 29, 2012 10:54 am
by bloodline
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 ;-)

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

Posted: Mon Jul 30, 2012 12:01 am
by ajstarks
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

pi@raspberrypi ~/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
pi@raspberrypi ~/vg $ ./shapes # hit return when you are done looking at the awesomness

pi@raspberrypi ~/vg $ ./shapes 100 # show 100 random shapes

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

Posted: Mon Jul 30, 2012 12:42 am
by ajstarks
The code is now on github at https://github.com/ajstarks/openvg

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

Posted: Mon Jul 30, 2012 10:20 am
by Tijmenlv
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.

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

Posted: Tue Jul 31, 2012 5:45 am
by eppe
Thank you very much for posting it Anthony, there is a such a lack of documentation/sample on openvg ...
Thanks again.

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

Posted: Tue Jul 31, 2012 7:45 am
by bloodline
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?

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

Posted: Tue Jul 31, 2012 11:57 am
by ajstarks
@bloodline -- the mouse changes seem interesting, Feel free to send a pull request.

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

Posted: Wed Aug 01, 2012 12:32 am
by ajstarks
The documentation has been updated to include the API, using fonts, and building and running:

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

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

Posted: Wed Aug 01, 2012 12:40 am
by bloodline
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 ;)

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

Posted: Wed Aug 01, 2012 6:10 pm
by bloodline
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 ;)

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

Posted: Thu Aug 02, 2012 4:34 am
by ajstarks
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

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

Posted: Thu Aug 02, 2012 9:54 am
by bloodline
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?

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

Posted: Thu Aug 02, 2012 11:13 am
by ajstarks
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()
}
 

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

Posted: Fri Aug 03, 2012 2:08 am
by ajstarks
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();
}

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

Posted: Sun Aug 05, 2012 2:46 pm
by ajstarks
Screenshots of the library are here: http://www.flickr.com/photos/ajstarks/s ... 913689774/