Rev 1155 |
Rev 1315 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
*
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
#include <drivers/vga.h>
#include <drivers/keyb.h>
#include <GL/osmesa.h>
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <kernel/log.h>
#include <kernel/kern.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif
#define WIDTH 640
#define HEIGHT 480
#define BYTES_PP 2 //BytesPerPixel
#define INITSTR G640x480x64K //SVGAlib standard mode definitions
#define CARD VESA //Video driver
OSMesaContext ctx
;
unsigned char *rgb_565_buf
= NULL
; //RGB 16 bpp Buffer
unsigned char *video_buf
= NULL
; //Video Buffer
unsigned long int VMEMLONG
= WIDTH
* HEIGHT
* BYTES_PP
/ 4; // Used by copy_videomem_16to16
unsigned long int RGB565MEM
= WIDTH
* HEIGHT
* BYTES_PP
; // Total video mem
unsigned long int PERIOD_REFRESH
= 100000;
unsigned long int PERIOD_DISEGNA
= 100000;
unsigned long int WCET_REFRESH
, WCET_DISEGNA
;
TASK refesh
(void);
TASK disegna
(void);
PID refresh_PID
, disegna_PID
;
static void
gear
(GLfloat inner_radius
, GLfloat outer_radius
, GLfloat width
,
GLint teeth
, GLfloat tooth_depth
)
{
GLint i
;
GLfloat r0
, r1
, r2
;
GLfloat angle
, da
;
GLfloat u
, v
, len
;
r0
= inner_radius
;
r1
= outer_radius
- tooth_depth
/ 2.0;
r2
= outer_radius
+ tooth_depth
/ 2.0;
da
= 2.0 * M_PI
/ teeth
/ 4.0;
glShadeModel
(GL_FLAT
);
glNormal3f
(0.0, 0.0, 1.0);
glBegin
(GL_QUAD_STRIP
);
for (i
= 0; i
<= teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
if (i
< teeth
) {
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
}
}
glEnd
();
glBegin
(GL_QUADS
);
da
= 2.0 * M_PI
/ teeth
/ 4.0;
for (i
= 0; i
< teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
glVertex3f
(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), width
* 0.5);
glVertex3f
(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), width
* 0.5);
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
}
glEnd
();
glNormal3f
(0.0, 0.0, -1.0);
glBegin
(GL_QUAD_STRIP
);
for (i
= 0; i
<= teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
if (i
< teeth
) {
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
}
}
glEnd
();
glBegin
(GL_QUADS
);
da
= 2.0 * M_PI
/ teeth
/ 4.0;
for (i
= 0; i
< teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
glVertex3f
(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), -width
* 0.5);
glVertex3f
(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), -width
* 0.5);
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
}
glEnd
();
glBegin
(GL_QUAD_STRIP
);
for (i
= 0; i
< teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
glVertex3f
(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
u
= r2
* cos(angle
+ da
) - r1
* cos(angle
);
v
= r2
* sin(angle
+ da
) - r1
* sin(angle
);
len
= sqrt(u
* u
+ v
* v
);
u
/= len
;
v
/= len
;
glNormal3f
(v
, -u
, 0.0);
glVertex3f
(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), width
* 0.5);
glVertex3f
(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), -width
* 0.5);
glNormal3f
(cos(angle
), sin(angle
), 0.0);
glVertex3f
(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), width
* 0.5);
glVertex3f
(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), -width
* 0.5);
u
= r1
* cos(angle
+ 3 * da
) - r2
* cos(angle
+ 2 * da
);
v
= r1
* sin(angle
+ 3 * da
) - r2
* sin(angle
+ 2 * da
);
glNormal3f
(v
, -u
, 0.0);
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
glVertex3f
(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
glNormal3f
(cos(angle
), sin(angle
), 0.0);
}
glVertex3f
(r1
* cos(0), r1
* sin(0), width
* 0.5);
glVertex3f
(r1
* cos(0), r1
* sin(0), -width
* 0.5);
glEnd
();
glShadeModel
(GL_SMOOTH
);
glBegin
(GL_QUAD_STRIP
);
for (i
= 0; i
<= teeth
; i
++) {
angle
= i
* 2.0 * M_PI
/ teeth
;
glNormal3f
(-cos(angle
), -sin(angle
), 0.0);
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
glVertex3f
(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
}
glEnd
();
}
static GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 0.0;
static GLint gear1
, gear2
, gear3
;
static GLfloat angle
= 0.0;
static void draw
(void)
{
glClear
(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
glPushMatrix
();
glRotatef
(view_rotx
, 1.0, 0.0, 0.0);
glRotatef
(view_roty
, 0.0, 1.0, 0.0);
glRotatef
(view_rotz
, 0.0, 0.0, 1.0);
glPushMatrix
();
glTranslatef
(-3.0, -2.0, 0.0);
glRotatef
(angle
, 0.0, 0.0, 1.0);
glCallList
(gear1
);
glPopMatrix
();
glPushMatrix
();
glTranslatef
(3.1, -2.0, 0.0);
glRotatef
(-2.0 * angle
- 9.0, 0.0, 0.0, 1.0);
glCallList
(gear2
);
glPopMatrix
();
glPushMatrix
();
glTranslatef
(-3.1, 4.2, 0.0);
glRotatef
(-2.0 * angle
- 25.0, 0.0, 0.0, 1.0);
glCallList
(gear3
);
glPopMatrix
();
glPopMatrix
();
glFinish
();
}
static void gl_init
()
{
static GLfloat red
[4] = {1.0, 0.0, 0.0, 1.0};
static GLfloat green
[4] = {0.0, 0.8, 0.2, 1.0};
static GLfloat blue
[4] = {0.2, 0.2, 1.0, 1.0};
static GLfloat pos
[4] = {5.0, 5.0, 10.0, 1.0};
static GLfloat h
= (GLfloat
) HEIGHT
/ (GLfloat
) WIDTH
;
//Create the OSMesa Context
ctx
= OSMesaCreateContext
(OSMESA_RGB_565
, NULL
);
//Make Current Context
OSMesaMakeCurrent
(ctx
, rgb_565_buf
, GL_UNSIGNED_SHORT_5_6_5
, WIDTH
, HEIGHT
);
glLightfv
(GL_LIGHT0
, GL_POSITION
, pos
);
glEnable
(GL_CULL_FACE
);
glEnable
(GL_LIGHTING
);
glEnable
(GL_LIGHT0
);
glEnable
(GL_DEPTH_TEST
);
/* make the gears */
gear1
= glGenLists
(1);
glNewList
(gear1
, GL_COMPILE
);
glMaterialfv
(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, red
);
gear
(1.0, 4.0, 1.0, 20, 0.7);
glEndList
();
gear2
= glGenLists
(1);
glNewList
(gear2
, GL_COMPILE
);
glMaterialfv
(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, green
);
gear
(0.5, 2.0, 2.0, 10, 0.7);
glEndList
();
gear3
= glGenLists
(1);
glNewList
(gear3
, GL_COMPILE
);
glMaterialfv
(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, blue
);
gear
(1.3, 2.0, 0.5, 10, 0.7);
glEndList
();
glEnable
(GL_NORMALIZE
);
glViewport
(0, 0, (GLint
) WIDTH
, (GLint
) HEIGHT
);
glMatrixMode
(GL_PROJECTION
);
glLoadIdentity
();
glFrustum
(-1.0, 1.0, -h
, h
, 5.0, 60.0);
glMatrixMode
(GL_MODELVIEW
);
glLoadIdentity
();
glTranslatef
(0.0, 0.0, -40.0);
}
static int screen
(int mode
)
{
vga_modeinfo
*minf
;
vga_setmode
(mode
,CARD
);
minf
= vga_getmodeinfo
(mode
);
if(! (minf
->flags
& CAPABLE_LINEAR
)){
vga_setmode
(TEXT
,CARD
);
printk
(KERN_INFO
"The mode %d is not capable of linear\n",mode
);
return 1;
}
vga_setpage
(0);
if(vga_setlinearaddressing
() == -1) {
vga_setmode
(TEXT
,CARD
);
printk
(KERN_INFO
"Could not set linear addressing for mode %d\n",mode
);
return 1;
}
video_buf
= vga_getgraphmem
();
grx_setbuffer
(rgb_565_buf
, WIDTH
, HEIGHT
); //Init of RGB16 version of grx functions
//created to work with Mesa buffer
return 0;
}
void program_end
(void *arg
)
{
OSMesaDestroyContext
(ctx
);
free(rgb_565_buf
);
vga_setmode
(TEXT
,CARD
);
sys_end
();
}
void program_key_end
(KEY_EVT
*k
)
{
sys_end
();
}
TASK refresh
(void)
{
while(1) {
copy_videomem_16to16
(rgb_565_buf
, video_buf
, VMEMLONG
);
task_endcycle
();
}
sys_end
();
}
TASK disegna
(void)
{
char text
[100];
TIME disegna_TIME
, refresh_TIME
;
while(1) {
jet_gettable
(refresh_PID
, &refresh_TIME
, 1);
jet_gettable
(disegna_PID
, &disegna_TIME
, 1);
angle
+= 1.0;
draw
();
sprintf(text
,"Hard Task Refresh PER:%6d us EX:%6d us",(int)PERIOD_REFRESH
,(int)refresh_TIME
);
grx_text
(text
,10,5,rgb16
(0,0,255),0);
sprintf(text
,"Hard Task Draw PER:%6d us EX:%6d us",(int)PERIOD_DISEGNA
,(int)disegna_TIME
);
grx_text
(text
,10,15,rgb16
(0,0,255),0);
task_endcycle
();
}
sys_end
();
}
int main
(int argc
, char *argv
[])
{
HARD_TASK_MODEL ht_refresh
, ht_disegna
;
sys_atrunlevel
(program_end
,NULL
, RUNLEVEL_BEFORE_EXIT
);
clear
();
WCET_REFRESH
=((long int) PERIOD_REFRESH
* (0.25));
WCET_DISEGNA
=((long int) PERIOD_DISEGNA
* (0.6));
hard_task_default_model
(ht_refresh
);
hard_task_def_wcet
(ht_refresh
,WCET_REFRESH
);
hard_task_def_mit
(ht_refresh
,PERIOD_REFRESH
);
hard_task_def_usemath
(ht_refresh
);
hard_task_def_group
(ht_refresh
,1);
hard_task_def_ctrl_jet
(ht_refresh
);
refresh_PID
= task_create
("refresh", refresh
, &ht_refresh
, NULL
);
if (refresh_PID
== -1) {
sys_end
();
exit(4);
}
hard_task_default_model
(ht_disegna
);
hard_task_def_mit
(ht_disegna
,PERIOD_DISEGNA
);
hard_task_def_wcet
(ht_disegna
,WCET_DISEGNA
);
hard_task_def_group
(ht_disegna
,1);
hard_task_def_ctrl_jet
(ht_disegna
);
hard_task_def_usemath
(ht_disegna
);
hard_task_def_stack
(ht_disegna
,30000); //VERY IMPORTANT FOR glCallList !!
disegna_PID
= task_create
("disegna", disegna
, &ht_disegna
, NULL
);
if (disegna_PID
== -1) {
sys_end
();
exit(4);
}
{
KEY_EVT k
;
k.
flag = ALTL_BIT
;
k.
scan = KEY_C
;
k.
ascii = 'c';
keyb_hook
(k
,program_key_end
);
}
rgb_565_buf
= malloc(RGB565MEM
);
gl_init
();
if (screen
(INITSTR
)) {
printk
(KERN_INFO
"Graphical initialization failed !!\n");
sys_end
();
}
memset(rgb_565_buf
, 0, RGB565MEM
);
group_activate
(1);
return 0;
}