medium/6_colors.c

Le but de ce programme est de donner un outil simple permettant d'obtenir rapidement le code d'une couleur donnée.

Dans la librairie MLV, le type d'une couleur est MLV_Color. Il s'agit en fait d'en entier codé sur 4 octets, soit 32 bits. Le premier octet code la la composante rouge de la couleur, le deuxième la composante verte, la troisième la composante bleue et la dernière, la composante alpha (transparence).

Ce programme ne constitue pas en soit un tutoriel.

// This definition are nedded by the nearbyint function
// This definition must appear before #include<stdio.h> and #include<math.h>
// see the manpages documentation of nearbyint for more information
#define _ISOC99_SOURCE

#include <math.h>
#include<stdio.h>

#include <MLV/MLV_all.h>

typedef struct _Color {
        int red;
        int green;
        int blue;
} Color;

typedef struct _Point {
        int x;
        int y;
} Point;

typedef struct _Triangle {
        Point R;
        Point G;
        Point B;
} Triangle;

typedef struct _Graphics {
        int width;
        int height;
        int width_box;
        int height_box;
        int height_bar;
        Triangle triangle;
} Graphics;

void saturate_color(
        const Color* color,
        Color* result 
){
        int max = 1;
        if( (color->red != 0.0 ) || ( color->green != 0.0 ) || ( color->blue != 0.0 ) ){
                max = color->red;
                if( max < color->blue ) max = color->blue;
                if( max < color->green ) max = color->green;
        }
        result->red = (255 * color->red)/max;
        result->green = (255 * color->green)/max;
        result->blue = (255 * color->blue)/max;
}

void determiner_couleur_triangle(
        const Point *cursor, const Triangle * triangle, Color *result
){
        double rx,ry,gx,gy,bx,by;
        double determinant;
        double a,b,c;
        rx = triangle->R.x - cursor->x; 
        gx = triangle->G.x - cursor->x; 
        bx = triangle->B.x - cursor->x; 
        ry = triangle->R.y - cursor->y; 
        gy = triangle->G.y - cursor->y; 
        by = triangle->B.y - cursor->y; 
        determinant = -(by - gy)*rx + (bx - gx)*ry - bx*gy + by*gx;
        a = (-bx*gy + by*gx)/determinant;
        b = (bx*ry - by*rx)/determinant;
        c = (-gx*ry + gy*rx)/determinant;
        if(
                ( a < 0.0 ) || ( b < 0.0 ) || ( c < 0.0 )
        ){
                a = 0.0;
                b = 0.0;
                c = 0.0;
        }

        int nuance = 255;
        result->red = nearbyint( nuance * a );
        result->green = nearbyint( nuance * b );
        result->blue = nearbyint( nuance * c );
}

void determiner_couleur_bar(
        const Point* cursor, const Graphics* graphics,
        const  Color* bar_color, Color* result
){

        Color satured_color;
        saturate_color( bar_color, &satured_color );

        double nuance = (cursor->x)/ (double) graphics->width;
        result->red = nearbyint( nuance * satured_color.red );
        result->green = nearbyint( nuance * satured_color.green );
        result->blue = nearbyint( nuance * satured_color.blue );
}

typedef enum {
        TRIANGLE,
        BAR
} Click_position;

Click_position determiner_couleur(
        const Point* cursor,
        const Graphics* graphics,
        const Color * bar_color,
        Color * result
){
        if( cursor->y >= graphics->height- graphics->height_bar ){
                determiner_couleur_bar( cursor, graphics, bar_color, result     );
                return BAR;
        }else{
                determiner_couleur_triangle( cursor, &(graphics->triangle), result );
                return TRIANGLE;
        }
}

void draw_text(
        const Color *color, const Graphics * graphics, int y_translation
){
        int size_text = 28;
        char text[size_text];
        snprintf( 
                text, size_text, "R:%d, G:%d, B:%d, A:%d ",
                color->red, color->green, color->blue, MLV_ALPHA_OPAQUE
        );
        int text_width,text_height;
        MLV_get_size_of_text( text, &text_width, &text_height );
        
        MLV_draw_text(
                graphics->width - graphics->width_box - text_width,
                (graphics->height_box/2) - (text_height/2) + y_translation ,
                text,
                MLV_COLOR_RED
        );
}


void affichage(
        const Point *cursor, const Graphics * graphics, const Color* bar_color
){
        MLV_load_screen();

        Color cursor_color;

        determiner_couleur( cursor, graphics, bar_color, &cursor_color );

        MLV_draw_filled_rectangle( 
                graphics->width-graphics->width_box,0,
                graphics->width_box,graphics->height_box,
                MLV_rgba(
                        cursor_color.red, cursor_color.green, cursor_color.blue,
                        MLV_ALPHA_OPAQUE 
                )
        );

        draw_text( &cursor_color, graphics, 0 );

        MLV_actualise_window();
}

void generer_fond(
        const Graphics * graphics,
        const Color* bar_color,
        const Color* selection_color
){
        int width = graphics->width;
        int height = graphics->height;
        int height_bar = graphics->height_bar;
        Point point;
        Color color;
        for( point.x = 0; point.x< width; point.x++){
                for( point.y=0; point.y<height;point.y++ ){
                        determiner_couleur_triangle(
                                &point, &(graphics->triangle), &color
                        );
                        MLV_draw_point( 
                                point.x, point.y,
                                MLV_rgba(
                                        color.red, color.green, color.blue,
                                        MLV_ALPHA_OPAQUE
                                )
                        );
                }
        }
        int i;
        
        Color bar_color_satured;
        saturate_color( bar_color, &bar_color_satured );
        
        for( i=0; i<width; i++ ){
                MLV_Color color = MLV_rgba(
                        (bar_color_satured.red*i)/width , 
                        (bar_color_satured.green*i)/width, 
                        (bar_color_satured.blue*i)/width,
                        MLV_ALPHA_OPAQUE 
                ); 
                MLV_draw_line( i, height-height_bar, i, height, color );
        }
        MLV_draw_filled_rectangle(
                graphics->width-graphics->width_box,
                graphics->height_box, graphics->width_box,graphics->height_box,
                MLV_rgba(
                        selection_color->red, selection_color->green, selection_color->blue,
                        MLV_ALPHA_OPAQUE
                )
        );

        draw_text( selection_color, graphics, graphics->height_box );

        MLV_save_screen();
}

void determiner_position_triangle( Graphics * graphics, int rayon ){
        graphics->triangle.R.x = 100;
        graphics->triangle.R.y = 300;
        graphics->triangle.G.x = 200;
        graphics->triangle.G.y = 100;
        graphics->triangle.B.x = 300;
        graphics->triangle.B.y = 300;
}

int main( int argc, char *argv[] ){
        Graphics graphics;
        graphics.width=640; graphics.height=480;
        graphics.width_box=120; graphics.height_box=80;
        graphics.height_bar = 40;
        int rayon = 300;
        Point cursor; cursor.x = 0; cursor.y = 0;
        int state;
        Color bar_color; bar_color.red = 0; bar_color.green = 0; bar_color.blue = 0;
        Color selection_color = bar_color; 

        MLV_Event event;

        MLV_create_window( 
                "medium - 6 - colors", "colors", graphics.width, graphics.height
        );
        
        determiner_position_triangle( &graphics, rayon );

        generer_fond( &graphics, &bar_color, &selection_color );
        
        affichage( &cursor, &graphics, &bar_color );
        while( 1 ){
                event = MLV_get_event( 
                        NULL, NULL, NULL,
                        NULL, NULL,
                        &(cursor.x), &(cursor.y), NULL,
                        &state
                );
                switch( event ){
                        case MLV_MOUSE_MOTION :
                                affichage( &cursor, &graphics, &bar_color );
                                break;
                        case MLV_MOUSE_BUTTON :
                                if( state == MLV_PRESSED ){
                                        if(
                                                determiner_couleur( 
                                                        &cursor, &graphics, &bar_color, &selection_color 
                                                ) == TRIANGLE
                                        ){
                                                bar_color = selection_color;
                                        }
                                        printf(
                                                "MLV_rgba( %d , %d , %d, MLV_ALPHA_OPAQUE )\n",
                                                selection_color.red, selection_color.green, 
                                                selection_color.blue
                                        );

                                        generer_fond( &graphics, &bar_color, &selection_color );
                                        affichage( &cursor, &graphics, &bar_color );
                                };
                                break;
                        default:;
                }
        }
        MLV_free_window();

        return 0;
}
Généré le Thu Sep 16 18:36:15 2010 pour MLV-0.5 par  doxygen 1.6.3