diff old/framebuffer/fb_test.c @ 977:eb704fa22d05 akira

add frame buffer utitilties
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 01 Oct 2010 22:01:53 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/old/framebuffer/fb_test.c	Fri Oct 01 22:01:53 2010 +0900
@@ -0,0 +1,198 @@
+// fb_test.c 
+// Simple test application. Draw something to the frame buffer. 
+//
+// Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+// documentation files (the "Software"), to deal in the Software without restriction, including without
+// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial
+// portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
+// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+// OR OTHER DEALINGS IN THE SOFTWARE.
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "cp_vt.h"
+#include "cp_fb.h"
+
+void write_hline_gouraud_ABGR8888( int32_t x0, int32_t x1, uint32_t left_rgba, uint32_t right_rgba, void* dest_buffer, uint16_t stride );
+
+int 
+main( void )
+{
+    cp_vt vt;
+    cp_fb fb;
+
+    cp_vt_open_graphics(&vt);
+    cp_fb_open(&fb);
+
+    uint32_t frame_ndx        = 0;
+    float    sprite_t         = 0.0f;
+    float    sprite_prev_t[2] = { 0.0f, 0.0f }; 
+
+    // A little example display.
+ 
+    for (uint32_t y_last = 1; y_last < fb.h; y_last++)
+    {
+        uint32_t* const restrict frame_top = (uint32_t*)fb.draw_addr[ frame_ndx ];
+
+        // Clear the background
+
+        memset( frame_top, 0x00, fb.h * fb.stride * 4 );
+
+        // Draw a rectangle that grows from top to bottom
+
+        for (uint32_t y = 0; y < y_last; y++ )
+        {
+            uint32_t* const restrict next_line = frame_top + ( fb.stride * y );
+
+            write_hline_gouraud_ABGR8888( 0,       64-1,      0x00ff0000, 0x00f0f000, next_line, fb.w );
+            write_hline_gouraud_ABGR8888( 64,      fb.w-64-1, 0x0000ff00, 0x000000ff, next_line, fb.w );
+            write_hline_gouraud_ABGR8888( fb.w-64, fb.w-1,    0x00ff00ff, 0x0000f0f0, next_line, fb.w );
+        }
+
+        // Draw a little sprite on a sine wave. 
+
+        sprite_t                    += 0.08f; // Update position
+        sprite_prev_t [ frame_ndx ]  = sprite_t; 
+
+        {
+            float    sprite_amp    = sinf( sprite_t );
+            uint32_t sprite_left   = (uint32_t)(sprite_t * 0.03f * (float)fb.w);
+            uint32_t sprite_top    = (fb.h>>1) + (uint32_t)(sprite_amp * (float)((fb.h-128)>>1));
+            uint32_t sprite_right  = sprite_left + 64;
+            uint32_t sprite_bottom = sprite_top  + 64;
+            uint32_t sprite_middle = sprite_left + (( sprite_right - sprite_left ) >> 1);
+            uint32_t sprite_cr      = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff;
+            uint32_t sprite_cg      = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff;
+            uint32_t sprite_cb      = ( (uint32_t)(sprite_amp * 127.0f) + 128 ) & 0x000000ff;
+            uint32_t sprite_crgb    = sprite_cr | ( sprite_cg << 8 ) | ( sprite_cb << 16 );
+
+            for (uint32_t y = sprite_top;y < sprite_bottom;y++)
+            {
+                uint32_t* const restrict next_line = frame_top + ( fb.stride * y );
+
+                write_hline_gouraud_ABGR8888( sprite_left,   sprite_middle-1, 0x007f1e00,  sprite_crgb, next_line, fb.w );
+                write_hline_gouraud_ABGR8888( sprite_middle, sprite_right-1,  sprite_crgb, 0x001e7f00,  next_line, fb.w );
+            }
+
+        }
+
+        // At the vsync, the previous frame is finished sending to the CRT
+        cp_fb_wait_vsync( &fb );
+
+        // Send the frame just drawn to the CRT by the next vblank
+        cp_fb_flip( &fb, frame_ndx );
+
+        frame_ndx  = frame_ndx ^ 0x01;
+    }
+
+    cp_vt_close(&vt);
+    cp_fb_close(&fb);
+
+    return (0);
+}
+
+void 
+write_hline_gouraud_ABGR8888( int32_t x0, int32_t x1, uint32_t left_rgba, uint32_t right_rgba, void* dest_buffer, uint16_t width )
+{
+  uint32_t left_r;
+  uint32_t left_g;
+  uint32_t left_b;
+  uint32_t left_a;
+
+  uint32_t step_r;
+  uint32_t step_g;
+  uint32_t step_b;
+  uint32_t step_a;
+
+  if ( (x1-x0+1) == 0 )
+  {
+    return;
+  }
+
+  /* Setup rgbas */
+  {
+    uint32_t right_r;
+    uint32_t right_g;
+    uint32_t right_b;
+    uint32_t right_a;
+    uint32_t step_scale;
+
+    left_r     = ( ( left_rgba       ) & 0x000000ff );
+    left_g     = ( ( left_rgba >> 8  ) & 0x000000ff );
+    left_b     = ( ( left_rgba >> 16 ) & 0x000000ff );
+    left_a     = ( ( left_rgba >> 24 ) & 0x000000ff );
+
+    right_r    = ( ( right_rgba       ) & 0x000000ff );
+    right_g    = ( ( right_rgba >> 8  ) & 0x000000ff );
+    right_b    = ( ( right_rgba >> 16 ) & 0x000000ff );
+    right_a    = ( ( right_rgba >> 24 ) & 0x000000ff );
+
+    step_scale = (1<<16) / (x1-x0+1);
+    step_r     = ( ( right_r - left_r ) * step_scale );
+    step_g     = ( ( right_g - left_g ) * step_scale );
+    step_b     = ( ( right_b - left_b ) * step_scale );
+    step_a     = ( ( right_a - left_a ) * step_scale );
+
+    left_r   <<= 16;
+    left_g   <<= 16;
+    left_b   <<= 16;
+    left_a   <<= 16;
+
+    left_r    += (1<<16)>>1;
+    left_g    += (1<<16)>>1;
+    left_b    += (1<<16)>>1;
+    left_a    += (1<<16)>>1;
+  }
+
+  /* Write to buffer */
+  {
+    uint32_t* restrict dest_pixel;
+    int32_t            x;
+
+    if ( x0 < 0 )
+    {
+      left_r += step_r * (-x0);
+      left_g += step_g * (-x0);
+      left_b += step_b * (-x0);
+      left_a += step_a * (-x0);
+      x0 = 0;
+    }
+
+    if ( x1 >= (int32_t)width )
+    {
+      x1 = width-1;
+    }
+
+    dest_pixel = (uint32_t*)dest_buffer + x0;
+
+    for (x=x0;x<=x1;x++)
+    {
+      uint32_t rgba;
+
+      rgba  = ( ( left_b >> 16 ) & 0x000000ff );
+      rgba |= ( ( left_g >> 16 ) & 0x000000ff ) << 8;
+      rgba |= ( ( left_r >> 16 ) & 0x000000ff ) << 16;
+      rgba |= ( ( left_a >> 16 ) & 0x000000ff ) << 24;
+
+      *dest_pixel = rgba;
+      dest_pixel++;
+
+      left_r += step_r;
+      left_g += step_g;
+      left_b += step_b;
+      left_a += step_a;
+    }
+  }
+}