Rev 1139 |
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 <assert.h>
#include <kernel/log.h>
#include <kernel/kern.h>
#include <stdio.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 NV3 //Video driver (Supported SAVAGE, NV3, R128 from SVGALib)
#define DEG2RAD (3.14159/180.0)
static GLint ImgWidth
, ImgHeight
;
static GLenum ImgFormat
;
static GLubyte
*Image
= NULL
;
#define MAX_OBJECTS 2
static GLint table_list
;
static GLint objects_list
[MAX_OBJECTS
];
static GLfloat xrot
, yrot
;
static GLfloat spin
;
static GLboolean Anim
= GL_TRUE
;
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
static GLint w
= WIDTH
, h
= HEIGHT
;
unsigned long int PERIOD_REFRESH
= 80000; //fps = 20
unsigned long int PERIOD_DISEGNA
= 80000;
unsigned long int WCET_REFRESH
, WCET_DISEGNA
;
TASK refesh
(void);
TASK disegna
(void);
GLUquadricObj
*q
;
PID refresh_PID
, disegna_PID
;
static void gl_init
( void )
{
GLfloat yAspect
= 2.5;
GLfloat xAspect
= yAspect
* (float) w
/ (float) h
;
//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
);
q
= gluNewQuadric
();
gluQuadricDrawStyle
( q
, GLU_FILL
);
gluQuadricNormals
( q
, GLU_SMOOTH
);
ImgWidth
= 100;
ImgHeight
= 100;
ImgFormat
= GL_RGB
;
Image
= malloc(ImgWidth
* ImgHeight
* 3);
/*Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
if (!Image) {
printf("Couldn't read %s\n", TABLE_TEXTURE);
exit(0);
}*/
gluBuild2DMipmaps
(GL_TEXTURE_2D
, 3, ImgWidth
, ImgHeight
,
ImgFormat
, GL_UNSIGNED_BYTE
, Image
);
glTexParameteri
( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
glTexParameteri
( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
glTexParameteri
( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
glTexParameteri
( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
xrot
= 30.0;
yrot
= 50.0;
spin
= 0.0;
glShadeModel
( GL_FLAT
);
glEnable
( GL_LIGHT0
);
glEnable
( GL_LIGHTING
);
glClearColor
( 0.5, 0.5, 0.9, 0.0 );
glEnable
( GL_NORMALIZE
);
glViewport
(0, 0, w
, h
);
glMatrixMode
(GL_PROJECTION
);
glLoadIdentity
();
glFrustum
( -xAspect
, xAspect
, yAspect
, -yAspect
, 10.0, 30.0 );
glMatrixMode
(GL_MODELVIEW
);
glLoadIdentity
();
}
static void draw_objects
( GLfloat eyex
, GLfloat eyey
, GLfloat eyez
)
{
static GLfloat cyan
[] = { 0.0, 1.0, 1.0, 1.0 };
static GLfloat green
[] = { 0.2, 1.0, 0.2, 1.0 };
static GLfloat black
[] = { 0.0, 0.0, 0.0, 0.0 };
#ifndef USE_ZBUFFER
if (eyex
<0.5) {
#endif
glPushMatrix
();
glTranslatef
( 1.0, 1.5, 0.0 );
glRotatef
( spin
, 1.0, 0.5, 0.0 );
glRotatef
( 0.5*spin
, 0.0, 0.5, 1.0 );
glMaterialfv
( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, cyan
);
glMaterialfv
( GL_FRONT
, GL_EMISSION
, black
);
gluCylinder
( q
, 0.5, 0.5, 1.0, 15, 1 );
glPopMatrix
();
glPushMatrix
();
glTranslatef
( -1.0, 0.85+3.0*fabs( cos(0.01*spin
) ), 0.0 );
glRotatef
( 0.5*spin
, 0.0, 0.5, 1.0 );
glRotatef
( spin
, 1.0, 0.5, 0.0 );
glScalef
( 0.5, 0.5, 0.5 );
glMaterialfv
( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, green
);
glMaterialfv
( GL_FRONT
, GL_EMISSION
, black
);
gluCylinder
( q
, 1.5, 0.0, 2.5, 15, 1 );
glPopMatrix
();
#ifndef USE_ZBUFFER
}
else {
glPushMatrix
();
glTranslatef
( -1.0, 0.85+3.0*fabs( cos(0.01*spin
) ), 0.0 );
glRotatef
( 0.5*spin
, 0.0, 0.5, 1.0 );
glRotatef
( spin
, 1.0, 0.5, 0.0 );
glScalef
( 0.5, 0.5, 0.5 );
glMaterialfv
( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, green
);
glMaterialfv
( GL_FRONT
, GL_EMISSION
, black
);
gluCylinder
( q
, 1.5, 0.0, 2.5, 15, 1 );
glPopMatrix
();
glPushMatrix
();
glTranslatef
( 1.0, 1.5, 0.0 );
glRotatef
( spin
, 1.0, 0.5, 0.0 );
glRotatef
( 0.5*spin
, 0.0, 0.5, 1.0 );
glMaterialfv
( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, cyan
);
glMaterialfv
( GL_FRONT
, GL_EMISSION
, black
);
gluCylinder
( q
, 0.5, 0.5, 1.0, 15, 1 );
glPopMatrix
();
}
#endif
}
static void draw_table
( void )
{
static GLfloat table_mat
[] = { 1.0, 1.0, 1.0, 0.6 };
static GLfloat gray
[] = { 0.4, 0.4, 0.4, 1.0 };
/* load table's texture */
glMaterialfv
( GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, table_mat
);
glMaterialfv
( GL_FRONT
, GL_DIFFUSE
, table_mat
);
glMaterialfv
( GL_FRONT
, GL_AMBIENT
, gray
);
/* draw textured square for the table */
glPushMatrix
();
glScalef
( 4.0, 4.0, 4.0 );
glBegin
( GL_POLYGON
);
glNormal3f
( 0.0, 1.0, 0.0 );
glTexCoord2f
( 0.0, 0.0 ); glVertex3f
( -1.0, 0.0, 1.0 );
glTexCoord2f
( 1.0, 0.0 ); glVertex3f
( 1.0, 0.0, 1.0 );
glTexCoord2f
( 1.0, 1.0 ); glVertex3f
( 1.0, 0.0, -1.0 );
glTexCoord2f
( 0.0, 1.0 ); glVertex3f
( -1.0, 0.0, -1.0 );
glEnd
();
glPopMatrix
();
glDisable
( GL_TEXTURE_2D
);
}
static void draw
( void )
{
static GLfloat light_pos
[] = { 0.0, 20.0, 0.0, 1.0 };
static GLfloat dist
= 20.0;
static GLfloat eyex
, eyey
, eyez
;
glClear
( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
eyex
= dist
* cos(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
eyez
= dist
* sin(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
eyey
= dist
* sin(xrot
*DEG2RAD
);
/* view from top */
glPushMatrix
();
gluLookAt
( eyex
, eyey
, eyez
, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
glLightfv
( GL_LIGHT0
, GL_POSITION
, light_pos
);
/* draw table into stencil planes */
glDisable
( GL_DEPTH_TEST
);
glEnable
( GL_STENCIL_TEST
);
glStencilFunc
( GL_ALWAYS
, 1, 0xffffffff );
glStencilOp
( GL_REPLACE
, GL_REPLACE
, GL_REPLACE
);
glColorMask
( GL_FALSE
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
draw_table
();
glColorMask
( GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
glEnable
( GL_DEPTH_TEST
);
/* render view from below (reflected viewport) */
/* only draw where stencil==1 */
if (eyey
>0.0) {
glPushMatrix
();
glStencilFunc
( GL_EQUAL
, 1, 0xffffffff ); /* draw if ==1 */
glStencilOp
( GL_KEEP
, GL_KEEP
, GL_KEEP
);
glScalef
( 1.0, -1.0, 1.0 );
/* Reposition light in reflected space. */
glLightfv
(GL_LIGHT0
, GL_POSITION
, light_pos
);
draw_objects
(eyex
, eyey
, eyez
);
glPopMatrix
();
/* Restore light's original unreflected position. */
glLightfv
(GL_LIGHT0
, GL_POSITION
, light_pos
);
}
glDisable
( GL_STENCIL_TEST
);
glEnable
( GL_BLEND
);
glBlendFunc
( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
glEnable
( GL_TEXTURE_2D
);
draw_table
();
glDisable
( GL_TEXTURE_2D
);
glDisable
( GL_BLEND
);
/* view from top */
glPushMatrix
();
draw_objects
(eyex
, eyey
, eyez
);
glPopMatrix
();
glPopMatrix
();
glFinish
();
}
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
();
rgb_565_buf
= malloc(RGB565MEM
);
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);
spin
+= 2.0;
yrot
+= 3.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.22));
WCET_DISEGNA
=((long int) PERIOD_DISEGNA
* (0.72));
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
);
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
);
}
if (screen
(INITSTR
)) {
printk
(KERN_INFO
"Graphical initialization failed !!\n");
sys_end
();
}
memset(rgb_565_buf
, 0, RGB565MEM
);
gl_init
();
group_activate
(1);
return 0;
}