* Made compilation under MacOSX 10.6 (Snow Leopard) possible, but breaks 10.4 (Tiger), to be fixedtags/v0.99.beta17
| @@ -338,6 +338,14 @@ __extern int caca_draw_thin_triangle(caca_canvas_t *, int, int, int, int, | |||
| int, int); | |||
| __extern int caca_fill_triangle(caca_canvas_t *, int, int, int, int, int, | |||
| int, uint32_t); | |||
| __extern int caca_fill_triangle_textured(caca_canvas_t *, | |||
| int , int , | |||
| int , int , | |||
| int , int , | |||
| float , float , | |||
| float , float , | |||
| float , float , | |||
| caca_canvas_t *); | |||
| /* @} */ | |||
| /** \defgroup caca_frame libcaca canvas frame handling | |||
| @@ -155,6 +155,202 @@ int caca_fill_triangle(caca_canvas_t *cv, int x1, int y1, int x2, int y2, | |||
| return 0; | |||
| } | |||
| /** \brief Fill a triangle on the canvas using an arbitrary-sized texture. | |||
| * | |||
| * This function fails if one or both the canvas are missing | |||
| * | |||
| * \param cv The handle to the libcaca canvas. | |||
| * \param x1 X coordinate of the first point. | |||
| * \param y1 Y coordinate of the first point. | |||
| * \param x2 X coordinate of the second point. | |||
| * \param y2 Y coordinate of the second point. | |||
| * \param x3 X coordinate of the third point. | |||
| * \param y3 Y coordinate of the third point. | |||
| * \param u1 U texture coordinate of the first point. | |||
| * \param v1 V texture coordinate of the first point. | |||
| * \param u2 U texture coordinate of the second point. | |||
| * \param v2 V texture coordinate of the second point. | |||
| * \param u3 U texture coordinate of the third point. | |||
| * \param v3 V texture coordinate of the third point. | |||
| * \param tex The handle of the canvas texture. | |||
| * \return This function return 0 if ok, -1 if canvas or texture are missing. | |||
| */ | |||
| int caca_fill_triangle_textured(caca_canvas_t *cv, | |||
| int x1, int y1, | |||
| int x2, int y2, | |||
| int x3, int y3, | |||
| float u1, float v1, | |||
| float u2, float v2, | |||
| float u3, float v3, | |||
| caca_canvas_t *tex) | |||
| { | |||
| #define SWAP_F(a, b) {float c = a; a = b; b = c; } | |||
| /* (very) Naive and | |||
| * (very) float-based affine and | |||
| * (very) non-clipped and | |||
| * (very) non-corrected triangle mapper | |||
| * | |||
| * Accepts arbitrary texture sizes | |||
| * Coordinates clamped to [0.0 - 1.0] (no repeat) | |||
| */ | |||
| if(!cv || !tex) return -1; | |||
| /* Bubble-sort y1 <= y2 <= y3 */ | |||
| if(y1 > y2) | |||
| return caca_fill_triangle_textured(cv, | |||
| x2, y2, x1, y1, x3, y3, | |||
| u2, v2, u1, v1, u3, v3, | |||
| tex); | |||
| if(y2 > y3) | |||
| return caca_fill_triangle_textured(cv, | |||
| x1, y1, x3, y3, x2, y2, | |||
| u1, v1, u3, v3, u2, v2, | |||
| tex); | |||
| /* Clip texture coordinates */ | |||
| if(u1<0.0f) u1 = 0.0f; if(v1<0.0f) v1 = 0.0f; | |||
| if(u2<0.0f) u2 = 0.0f; if(v2<0.0f) v2 = 0.0f; | |||
| if(u3<0.0f) u3 = 0.0f; if(v3<0.0f) v3 = 0.0f; | |||
| if(u1>1.0f) u1 = 1.0f; if(v1>1.0f) v1 = 1.0f; | |||
| if(u2>1.0f) u2 = 1.0f; if(v2>1.0f) v2 = 1.0f; | |||
| if(u3>1.0f) u3 = 1.0f; if(v3>1.0f) v3 = 1.0f; | |||
| /* Convert relative tex coordinates to absolute */ | |||
| int tw = caca_get_canvas_width(tex); | |||
| int th = caca_get_canvas_height(tex); | |||
| u1*=(float)tw; u2*=(float)tw; u3*=(float)tw; | |||
| v1*=(float)th; v2*=(float)th; v3*=(float)th; | |||
| float x = (float) x1, y = (float) y1; | |||
| float y2y1 = y2-y1; | |||
| float y3y1 = y3-y1; | |||
| float y3y2 = y3-y2; | |||
| /* Compute slopes, making sure we don't divide by zero */ | |||
| /* (in this case, we don't need the value anyway) */ | |||
| /* FIXME : only compute needed slopes */ | |||
| float sl12 = ((float)x2 - x1) / (y2y1==0?1:y2y1); | |||
| float sl13 = ((float)x3 - x1) / (y3y1==0?1:y3y1); | |||
| float sl23 = ((float)x3 - x2) / (y3y2==0?1:y3y2); | |||
| float usl12 = (u2 - u1) / (y2y1==0?1:y2y1); | |||
| float usl13 = (u3 - u1) / (y3y1==0?1:y3y1); | |||
| float usl23 = (u3 - u2) / (y3y2==0?1:y3y2); | |||
| float vsl12 = (v2 - v1) / (y2y1==0?1:y2y1); | |||
| float vsl13 = (v3 - v1) / (y3y1==0?1:y3y1); | |||
| float vsl23 = (v3 - v2) / (y3y2==0?1:y3y2); | |||
| float xa = (float) x1, xb = (float) x1; | |||
| float ua = u1, ub = u1; | |||
| float va = v1, vb = v1; | |||
| float u, v; | |||
| int s = 0; | |||
| /* Top */ | |||
| for(y = y1 ; y < y2; y++) | |||
| { | |||
| if(xb < xa) { | |||
| SWAP_F(xb, xa); | |||
| SWAP_F(sl13, sl12); | |||
| SWAP_F(ua, ub); | |||
| SWAP_F(va, vb); | |||
| SWAP_F(usl13, usl12); | |||
| SWAP_F(vsl13, vsl12); | |||
| s=1; | |||
| } | |||
| float tus = (ub - ua) / (xb - xa); | |||
| float tvs = (vb - va) / (xb - xa); | |||
| v = va; u = ua; | |||
| /* scanline */ | |||
| for(x = xa ; x < xb; x++) | |||
| { | |||
| u+=tus; | |||
| v+=tvs; | |||
| /* FIXME: use caca_get_canvas_attrs / caca_get_canvas_chars */ | |||
| uint32_t attr = caca_get_attr(tex, u, v); | |||
| uint32_t c = caca_get_char(tex, u, v); | |||
| caca_set_attr(cv, attr); | |||
| caca_put_char(cv, x, y, c); | |||
| } | |||
| xa+=sl13; | |||
| xb+=sl12; | |||
| ua+=usl13; va+=vsl13; | |||
| ub+=usl12; vb+=vsl12; | |||
| } | |||
| if(s) | |||
| { | |||
| SWAP_F(xb, xa); | |||
| SWAP_F(sl13, sl12); | |||
| SWAP_F(ua, ub); | |||
| SWAP_F(va, vb); | |||
| SWAP_F(usl13, usl12); | |||
| SWAP_F(vsl13, vsl12); | |||
| } | |||
| /* Bottom */ | |||
| xb = (float) x2; | |||
| /* These variables are set by 'top' routine | |||
| * and are in an incorrect state if we only draw the bottom part | |||
| */ | |||
| if(y1 == y2) { | |||
| ua = u1; | |||
| ub = u2; | |||
| va = v1; | |||
| vb = v2; | |||
| } | |||
| for(y = y2 ; y < y3; y++) | |||
| { | |||
| if(xb <= xa) | |||
| { | |||
| SWAP_F(xb, xa); | |||
| SWAP_F(sl13, sl23); | |||
| SWAP_F(ua, ub); | |||
| SWAP_F(va, vb); | |||
| SWAP_F(usl13, usl23); | |||
| SWAP_F(vsl13, vsl23); | |||
| } | |||
| float tus = (ub - ua) / ((float)xb - xa); | |||
| float tvs = (vb - va) / ((float)xb - xa); | |||
| u = ua; v = va; | |||
| /* scanline */ | |||
| for(x = xa ; x < xb; x++) | |||
| { | |||
| u+=tus; | |||
| v+=tvs; | |||
| /* FIXME, can be heavily optimised */ | |||
| uint32_t attr = caca_get_attr(tex, u, v); | |||
| uint32_t c = caca_get_char(tex, u, v); | |||
| caca_set_attr(cv, attr); | |||
| caca_put_char(cv, x, y, c); | |||
| } | |||
| xa+=sl13; | |||
| xb+=sl23; | |||
| ua+=usl13; va+=vsl13; | |||
| ub+=usl23; vb+=vsl23; | |||
| } | |||
| return 0; | |||
| } | |||
| /* | |||
| * XXX: The following functions are aliases. | |||
| */ | |||
| @@ -258,7 +258,7 @@ if test "${enable_cocoa}" != "no"; then | |||
| MACOSX_SDK_CXXFLAGS="${MACOSX_SDK_CXXFLAGS:-${MACOSX_SDK_CFLAGS}}" | |||
| ;; | |||
| x*86*darwin*) | |||
| MACOSX_SDK="${MACOSX_SDK:-/Developer/SDKs/MacOSX10.4u.sdk}" | |||
| MACOSX_SDK="${MACOSX_SDK:-/Developer/SDKs/MacOSX10.6.sdk}" | |||
| GCC_VERSION="${GCC_VERSION:-4.0}" | |||
| ARCH="${ARCH:--arch i386}" | |||
| MACOSX_SDK_CFLAGS="${MACOSX_SDK_CFLAGS:--isysroot ${MACOSX_SDK}}" | |||
| @@ -2,12 +2,15 @@ | |||
| AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/caca -I$(top_builddir)/caca | |||
| noinst_PROGRAMS = blit canvas colors conio $(conio_snake) demo demo0 dithering driver event export figfont font font2tga frames fullwidth gamma hsv input spritedit swallow text transform truecolor unicode import | |||
| noinst_PROGRAMS = trifiller blit canvas colors conio $(conio_snake) demo demo0 dithering driver event export figfont font font2tga frames fullwidth gamma hsv input spritedit swallow text transform truecolor unicode import | |||
| if USE_CXX | |||
| conio_snake = conio-snake | |||
| endif | |||
| trifiller_SOURCES = trifiller.c ../src/common-image.c | |||
| trifiller_LDADD = ../caca/libcaca.la | |||
| blit_SOURCES = blit.c | |||
| blit_LDADD = ../caca/libcaca.la | |||
| @@ -0,0 +1,239 @@ | |||
| /* | |||
| * trifiller texture mapping features | |||
| * Copyright (c) 2009 Jean-Yves Lamoureux <jylam@lnxscene.org> | |||
| * All Rights Reserved | |||
| * | |||
| * $Id: trifiller.c 2821 2008-09-27 13:12:46Z sam $ | |||
| * | |||
| * This program is free software. It comes without any warranty, to | |||
| * the extent permitted by applicable law. You can redistribute it | |||
| * and/or modify it under the terms of the Do What The Fuck You Want | |||
| * To Public License, Version 2, as published by Sam Hocevar. See | |||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||
| */ | |||
| #include "config.h" | |||
| #if !defined(__KERNEL__) | |||
| # include <stdio.h> | |||
| # include <string.h> | |||
| #endif | |||
| /* libcaca header */ | |||
| #include "caca.h" | |||
| /* Image loading functions */ | |||
| #include "../src/common-image.h" | |||
| /* M_PI / cos / sin */ | |||
| #include <math.h> | |||
| #define SQUARE_SIZE 20 | |||
| int main(int argc, char *argv[]) | |||
| { | |||
| /* libcaca/libcaca contexts */ | |||
| caca_canvas_t *cv; caca_display_t *dp; | |||
| caca_canvas_t *tex; | |||
| /* cached canvas size */ | |||
| int ww, wh, tw, th; | |||
| /* logic */ | |||
| int quit = 0; | |||
| int update = 1; | |||
| int px, py; | |||
| float angle = 0; | |||
| float square[4][2] = { | |||
| {-SQUARE_SIZE, -SQUARE_SIZE}, | |||
| { SQUARE_SIZE, -SQUARE_SIZE}, | |||
| { SQUARE_SIZE, SQUARE_SIZE}, | |||
| {-SQUARE_SIZE, SQUARE_SIZE}, | |||
| }; | |||
| float rotated[4][2]; | |||
| /* Create displayed canvas */ | |||
| cv = caca_create_canvas(0, 0); | |||
| if(!cv) | |||
| { | |||
| fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); | |||
| return 1; | |||
| } | |||
| /* Create texture holding canvas */ | |||
| tex = caca_create_canvas(16, 16); | |||
| if(!tex) | |||
| { | |||
| fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); | |||
| return 1; | |||
| } | |||
| /* Open window */ | |||
| dp = caca_create_display(cv); | |||
| if(!dp) | |||
| { | |||
| fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); | |||
| return 1; | |||
| } | |||
| /* Set the window title */ | |||
| caca_set_display_title(dp, "trifiller"); | |||
| /* Frame duration */ | |||
| caca_set_display_time(dp, 10000); | |||
| /* Get displayed canvas size */ | |||
| ww = caca_get_canvas_width(cv); | |||
| wh = caca_get_canvas_height(cv); | |||
| /* Texture size */ | |||
| tw = caca_get_canvas_width(tex); | |||
| th = caca_get_canvas_height(tex); | |||
| /* Load texture if any */ | |||
| if(argc == 2) | |||
| { | |||
| struct image *im = load_image(argv[1]); | |||
| if(!im) | |||
| { | |||
| fprintf(stderr, "%s: unable to load image '%s'\n", argv[0], argv[1]); | |||
| return 1; | |||
| } | |||
| caca_set_dither_algorithm(im->dither, | |||
| caca_get_dither_algorithm_list(NULL)[4]); | |||
| caca_dither_bitmap(tex, | |||
| 0, 0, | |||
| tw, th, | |||
| im->dither, im->pixels); | |||
| unload_image(im); | |||
| } | |||
| /* or generate one */ | |||
| else | |||
| { | |||
| int i; | |||
| for(i = 0; i < 16; i ++) | |||
| { | |||
| caca_set_color_ansi(tex, (i+1)%0xF, i); | |||
| caca_put_str(tex, 0, i, "123456789ABCDEF"); | |||
| } | |||
| } | |||
| px = 0; | |||
| py = 0; | |||
| while(!quit) | |||
| { | |||
| caca_event_t ev; | |||
| unsigned int const event_mask = CACA_EVENT_KEY_PRESS | |||
| | CACA_EVENT_RESIZE | |||
| | CACA_EVENT_QUIT; | |||
| int event; | |||
| if(update) | |||
| event = caca_get_event(dp, event_mask, &ev, 0); | |||
| else | |||
| event = caca_get_event(dp, event_mask, &ev, -1); | |||
| while(event) | |||
| { | |||
| if(caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS) | |||
| switch(caca_get_event_key_ch(&ev)) | |||
| { | |||
| case 'q': | |||
| case 'Q': | |||
| case CACA_KEY_ESCAPE: | |||
| quit = 1; | |||
| break; | |||
| case CACA_KEY_UP: | |||
| py--; | |||
| break; | |||
| case CACA_KEY_DOWN: | |||
| py++; | |||
| break; | |||
| case CACA_KEY_LEFT: | |||
| px--; | |||
| break; | |||
| case CACA_KEY_RIGHT: | |||
| px++; | |||
| break; | |||
| case 'a': | |||
| angle+=1.0f; | |||
| break; | |||
| case 's': | |||
| angle-=1.0f; | |||
| break; | |||
| } | |||
| else if(caca_get_event_type(&ev) == CACA_EVENT_RESIZE) | |||
| { | |||
| caca_refresh_display(dp); | |||
| ww = caca_get_event_resize_width(&ev); | |||
| wh = caca_get_event_resize_height(&ev); | |||
| update = 1; | |||
| } | |||
| else if(caca_get_event_type(&ev) & CACA_EVENT_QUIT) | |||
| quit = 1; | |||
| event = caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 0); | |||
| } | |||
| /* 2D Rotation around screen center */ | |||
| int p; | |||
| for(p=0; p<4; p++) | |||
| { | |||
| rotated[p][0] = square[p][0] * cos(angle*M_PI/180.0f) - square[p][1] * sin(angle*M_PI/180.0f); | |||
| rotated[p][1] = square[p][0] * sin(angle*M_PI/180.0f) + square[p][1] * cos(angle*M_PI/180.0f); | |||
| rotated[p][0] += ww/2 + px; | |||
| rotated[p][1] += wh/2 + py; | |||
| } | |||
| angle+=1.0f; | |||
| /* Display two triangles */ | |||
| caca_fill_triangle_textured(cv, | |||
| /* triangle screen coordinates */ | |||
| rotated[0][0], rotated[0][1], | |||
| rotated[1][0], rotated[1][1], | |||
| rotated[2][0], rotated[2][1], | |||
| /* texture coordinates */ | |||
| 0, 0, | |||
| 1, 0, | |||
| 1, 1, | |||
| tex); | |||
| caca_fill_triangle_textured(cv, | |||
| /* triangle screen coordinates */ | |||
| rotated[0][0], rotated[0][1], | |||
| rotated[2][0], rotated[2][1], | |||
| rotated[3][0], rotated[3][1], | |||
| /* texture coordinates */ | |||
| 0, 0, | |||
| 1, 1, | |||
| 0, 1, | |||
| tex); | |||
| /* Refresh display and clear for next frame */ | |||
| caca_refresh_display(dp); | |||
| caca_clear_canvas(cv); | |||
| } | |||
| caca_free_display(dp); | |||
| caca_free_canvas(cv); | |||
| caca_free_canvas(tex); | |||
| return 0; | |||
| } | |||