• Welcome to Dark Bit Factory & Gravity.
 

My ideas on the design of a graphics library

Started by Stonemonkey, May 30, 2006

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

Stonemonkey

For the writing of a graphics library I've found encapsulation to be very useful as adding,removing or reworking functions becomes very easy without the need to worry about what variable names have been used elsewhere(particularly when there's more than 1 person contributing I'd imagine).
This is a fairly basic setup which shows one way this could be done and I'm not totally sure about casting pointers to integers which may slow things down slightly (only really a problem for stuff like single pixel operations) and restrict the direct access to buffer data but it does make using it a little simpler (IMO).

Anyway, the basic lib to be included:

option explicit

#define PTC_WIN
#Include Once "tinyptc.bi"

const deg_rad_conv=3.14159265/180.0
#define cs(a) cos(a*deg_rad_conv)
#define sn(a) sin(a*deg_rad_conv)

type graphics_buffer
Ã,  Ã,  wwidth as integer
Ã,  Ã,  height as integer
Ã,  Ã,  argb_buffer as integer pointer
end type

function graphics(byval wwidth as integer,byval height as integer,byval windowname as string="Freebasic")as integerÃ,  
Ã,  Ã,  If( ptc_open( windowname, wwidth, height ) = 0 ) Then
Ã,  Ã,  Ã,  Ã,  End -1
Ã,  Ã,  End If
Ã,  Ã,  dim buffer as graphics_buffer pointer=callocate(len(graphics_buffer))
Ã,  Ã,  buffer->wwidth=wwidth
Ã,  Ã,  buffer->height=height
Ã,  Ã,  buffer->argb_buffer=callocate(len(integer)*wwidth*height)
Ã,  Ã,  function=cast(integer,buffer)
end function

sub close_graphics(byval buffer_i as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  deallocate(buffer->argb_buffer)
Ã,  Ã,  deallocate(buffer)
Ã,  Ã,  ptc_close
end sub

sub flip_buffer(byval buffer_i as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  ptc_update buffer->argb_buffer
end sub

sub write_pixel(byval buffer_i as integer,byval x as integer,byval y as integer,byval argb as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  if (x>=0)and(x<buffer->wwidth)and(y>=0)and(y<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(x+y*buffer->wwidth))=argb
end sub

function read_pixel(byval buffer_i as integer,byval x as integer,byval y as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim argb as integer
Ã,  Ã,  if (x>=0)and(x<buffer->wwidth)and(y>=0)and(y<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  argb=*buffer->argb_buffer+(x+y*buffer->wwidth)
Ã,  Ã,  function=argb
end function

sub draw_line(byval buffer_i as integer,x0 as integer,y0 as integer,x1 as integer,y1 as integer,argb as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim dx as single=x1-x0
Ã,  Ã,  dim dy as single=y1-y0
Ã,  Ã,  dim as single x,y
Ã,  Ã,  dim as integer xi,yi,di,endpoint
Ã,  Ã,  if abs(dx)>abs(dy) then
Ã,  Ã,  Ã,  Ã,  xi=x0
Ã,  Ã,  Ã,  Ã,  endpoint=x1
Ã,  Ã,  Ã,  Ã,  di=sgn(x1-x0)
Ã,  Ã,  Ã,  Ã,  y=y0
Ã,  Ã,  Ã,  Ã,  dy=di*dy/dx
Ã,  Ã,  Ã,  Ã,  while xi<>endpoint
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  yi=y
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (xi>=0)and(xi<buffer->wwidth)and(yi>=0)and(yi<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(xi+yi*buffer->wwidth))=argb
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  y+=dy
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  xi+=di
Ã,  Ã,  Ã,  Ã,  wend
Ã,  Ã,  else
Ã,  Ã,  Ã,  Ã,  yi=y0
Ã,  Ã,  Ã,  Ã,  endpoint=y1
Ã,  Ã,  Ã,  Ã,  di=sgn(y1-y0)
Ã,  Ã,  Ã,  Ã,  x=x0
Ã,  Ã,  Ã,  Ã,  dx=di*dx/dy
Ã,  Ã,  Ã,  Ã,  while yi<>endpoint
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  xi=x
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (xi>=0)and(xi<buffer->wwidth)and(yi>=0)and(yi<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(xi+yi*buffer->wwidth))=argb
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  x+=dx
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  yi+=di
Ã,  Ã,  Ã,  Ã,  wend
Ã,  Ã,  end if
end sub

sub clear_buffer(byval buffer_i as integer,byval argb as integer=0)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim argb_buffer as integer pointer=buffer->argb_buffer
Ã,  Ã,  dim num_ints as integer=buffer->wwidth*buffer->height
Ã,  Ã,  asm
Ã,  Ã,  Ã,  Ã,  mov eax,dword ptr[argb]
Ã,  Ã,  Ã,  Ã,  mov ecx, [num_ints]
Ã,  Ã,  Ã,  Ã,  mov edi, [argb_buffer]
Ã,  Ã,  Ã,  Ã,  cld
Ã,  Ã,  Ã,  Ã,  rep stosd
Ã,  Ã,  end asm
end sub


And a little test:

#include("graphics_lib")

'the following code does not need to be contained within a sub, it could be part of the main code if you wanted (personal preference) but i like it this way
sub main()
Ã,  Ã,  dim my_graphics_buffer as integer=graphics(640,480,"test")
Ã,  Ã,  dim i as integer
Ã,  Ã,  dim angle as single
Ã,  Ã,  while inkey$=""
Ã,  Ã,  Ã,  Ã,  for i=1 to 20000
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  write_pixel my_graphics_buffer,rnd*640,rnd*480,rnd*&hffffff
Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  draw_line my_graphics_buffer,320,240,320+100*sn(angle),240-100*cs(angle),&hff00ff
Ã,  Ã,  Ã,  Ã,  angle+=0.5
Ã,  Ã,  Ã,  Ã,  flip_buffer my_graphics_buffer
Ã,  Ã,  Ã,  Ã,  clear_buffer my_graphics_buffer
Ã,  Ã,  wend
Ã,  Ã,  close_graphics my_graphics_buffer
end sub
main()


If you're thinking of creating some sort of group of functions for everyone to contribute to then something like this would be the way to go although this is just an example.

Sorry there's not any description of what the code here does as I've just writen it up quickly, if there's anything you want to know just ask.

Cheers, Stonemonkey.

Stonemonkey

#1
Oops, originally added the line function here but then decided to put it in the post above. It doesn't fill the final pixel and could do with some work on clipping.

Stonemonkey

Another couple of functions just to show how working this way can be quite useful, they allow you to create images which can be drawn to the screen, the images can be drawn to with the same screen drawing functions and also images can be drawn into other images and if an image is the same dimensions as the screen it can be flipped just like a screen buffer.

functions to add:

function create_image(byval wwidth as integer,byval height as integer,byval windowname as string="Freebasic")as integer 
    dim buffer as graphics_buffer pointer=callocate(len(graphics_buffer))
    buffer->wwidth=wwidth
    buffer->height=height
    buffer->argb_buffer=callocate(len(integer)*wwidth*height)
    function=cast(integer,buffer)
end function

sub draw_image(byval buffer_i as integer,byval image_i as integer,byval x as integer,byval y as integer)
    dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
    dim image as graphics_buffer pointer=cast(graphics_buffer pointer,image_i)
    dim as integer u,v,px,py
    for v=0 to image->height-1
        py=y+v
        if (py>=0)and(py<buffer->height) then
            for u=0 to image->wwidth-1
                px=x+u
                if (px>=0)and(px<buffer->wwidth) then _
                    *(buffer->argb_buffer+px+py*buffer->wwidth)=*(image->argb_buffer+u+v*image->wwidth)
            next
        end if
    next
end sub


and with an example added to the test code:

#include("graphics_lib")
sub main()
    dim my_graphics_buffer as integer=graphics(640,480,"test")
   
    dim image as integer=create_image(20,20)
    draw_line(image,0,0,19,19,&hffffff)
    draw_line(image,19,0,0,19,&hffffff)
    draw_line(image,0,0,19,0,&hffffff)
    draw_line(image,19,0,19,19,&hffffff)
    draw_line(image,19,19,0,19,&hffffff)
    draw_line(image,0,19,0,0,&hffffff)
   
    dim i as integer
    dim angle as single
    while inkey$=""
        for i=1 to 20000
            write_pixel my_graphics_buffer,rnd*640,rnd*480,rnd*&hffffff
        next
        draw_line(my_graphics_buffer,320,240,320+100*sn(angle),240-100*cs(angle),&hff00ff)
        draw_image(my_graphics_buffer,image,320+100*sn(angle),240-100*cs(angle))
        angle+=0.5
        flip_buffer my_graphics_buffer
        clear_buffer my_graphics_buffer
    wend
    close_graphics my_graphics_buffer
end sub


Cheers, Fryer.

TinDragon

Thats a very interesting and informative approach, didn't know that kind of thing was possible in FB, looking over the way you have done it I also start to understand some of the more complex code ideas I have been reading about. It's a very different approach to the way I started the TTDlib which Zawran has help add to, I think the reason we are able to work together on ours is down to having built several libs together before in blitz. Thanks for sharing your ideas and I am sure others will find it useful, perhaps we can make this a community project and extend it with new functions ?  I might have a bash at converting the oval drawing command I have a little later  :)

Stonemonkey

#4
Thanks TinDragon, and no problem at all. It's one of the things that I really like about freebasic, it gives a lot more freedom to code in different ways than blitzbasic does. This is just showing the method I'd use for something like this but to come up with something for a comunity project of this type there should be some discussion about how it should all work along with how peoples contibutions are submitted and stuff like that.

Stonemonkey

#5
Added a bit more functionality to this.
This is the full code so far.

option explicit

#define PTC_WIN
#Include Once "tinyptc.bi"

const deg_rad_conv=3.14159265/180.0
#define cs(a) cos(a*deg_rad_conv)
#define sn(a) sin(a*deg_rad_conv)

type graphics_buffer
Ã,  Ã,  wwidth as integer
Ã,  Ã,  height as integer
Ã,  Ã,  argb_buffer as integer pointer
end type

type sprite
Ã,  Ã,  x as single
Ã,  Ã,  y as single
Ã,  Ã,  handle_x as integer
Ã,  Ã,  handle_y as integer
Ã,  Ã,  image_i as integer
end type

function graphics(byval wwidth as integer,byval height as integer,byval windowname as string="Freebasic")as integerÃ,  
Ã,  Ã,  If( ptc_open( windowname, wwidth, height ) = 0 ) Then
Ã,  Ã,  Ã,  Ã,  End -1
Ã,  Ã,  End If
Ã,  Ã,  dim buffer as graphics_buffer pointer=callocate(len(graphics_buffer))
Ã,  Ã,  buffer->wwidth=wwidth
Ã,  Ã,  buffer->height=height
Ã,  Ã,  buffer->argb_buffer=callocate(len(integer)*wwidth*height)
Ã,  Ã,  function=cast(integer,buffer)
end function

sub close_graphics(byval buffer_i as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  deallocate(buffer->argb_buffer)
Ã,  Ã,  deallocate(buffer)
Ã,  Ã,  ptc_close
end sub

sub flip_buffer(byval buffer_i as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  ptc_update buffer->argb_buffer
end sub

sub write_pixel(byval buffer_i as integer,byval x as integer,byval y as integer,byval argb as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  if (x>=0)and(x<buffer->wwidth)and(y>=0)and(y<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(x+y*buffer->wwidth))=argb
end sub

function read_pixel(byval buffer_i as integer,byval x as integer,byval y as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim argb as integer
Ã,  Ã,  if (x>=0)and(x<buffer->wwidth)and(y>=0)and(y<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  argb=*buffer->argb_buffer+(x+y*buffer->wwidth)
Ã,  Ã,  function=argb
end function

sub draw_line(byval buffer_i as integer,x0 as integer,y0 as integer,x1 as integer,y1 as integer,argb as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim dx as single=x1-x0
Ã,  Ã,  dim dy as single=y1-y0
Ã,  Ã,  dim as single x,y
Ã,  Ã,  dim as integer xi,yi,di,endpoint
Ã,  Ã,  if abs(dx)>abs(dy) then
Ã,  Ã,  Ã,  Ã,  xi=x0
Ã,  Ã,  Ã,  Ã,  endpoint=x1
Ã,  Ã,  Ã,  Ã,  di=sgn(x1-x0)
Ã,  Ã,  Ã,  Ã,  y=y0
Ã,  Ã,  Ã,  Ã,  dy=di*dy/dx
Ã,  Ã,  Ã,  Ã,  while xi<>endpoint
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  yi=y
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (xi>=0)and(xi<buffer->wwidth)and(yi>=0)and(yi<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(xi+yi*buffer->wwidth))=argb
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  y+=dy
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  xi+=di
Ã,  Ã,  Ã,  Ã,  wend
Ã,  Ã,  else
Ã,  Ã,  Ã,  Ã,  yi=y0
Ã,  Ã,  Ã,  Ã,  endpoint=y1
Ã,  Ã,  Ã,  Ã,  di=sgn(y1-y0)
Ã,  Ã,  Ã,  Ã,  x=x0
Ã,  Ã,  Ã,  Ã,  dx=di*dx/dy
Ã,  Ã,  Ã,  Ã,  while yi<>endpoint
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  xi=x
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (xi>=0)and(xi<buffer->wwidth)and(yi>=0)and(yi<buffer->height) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+(xi+yi*buffer->wwidth))=argb
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  x+=dx
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  yi+=di
Ã,  Ã,  Ã,  Ã,  wend
Ã,  Ã,  end if
end sub

sub clear_buffer(byval buffer_i as integer,byval argb as integer=0)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim argb_buffer as integer pointer=buffer->argb_buffer
Ã,  Ã,  dim num_ints as integer=buffer->wwidth*buffer->height
Ã,  Ã,  asm
Ã,  Ã,  Ã,  Ã,  mov eax,dword ptr[argb]
Ã,  Ã,  Ã,  Ã,  mov ecx, [num_ints]
Ã,  Ã,  Ã,  Ã,  mov edi, [argb_buffer]
Ã,  Ã,  Ã,  Ã,  cld
Ã,  Ã,  Ã,  Ã,  rep stosd
Ã,  Ã,  end asm
end sub



function create_image(byval wwidth as integer,byval height as integer,byval windowname as string="Freebasic")as integerÃ,  
Ã,  Ã,  dim buffer as graphics_buffer pointer=callocate(len(graphics_buffer))
Ã,  Ã,  buffer->wwidth=wwidth
Ã,  Ã,  buffer->height=height
Ã,  Ã,  buffer->argb_buffer=callocate(len(integer)*wwidth*height)
Ã,  Ã,  function=cast(integer,buffer)
end function

sub draw_image(byval buffer_i as integer,byval image_i as integer,byval x as integer,byval y as integer)
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  dim image as graphics_buffer pointer=cast(graphics_buffer pointer,image_i)
Ã,  Ã,  dim as integer u,v,px,py
Ã,  Ã,  for v=0 to image->height-1
Ã,  Ã,  Ã,  Ã,  py=y+v
Ã,  Ã,  Ã,  Ã,  if (py>=0)and(py<buffer->height) then
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  for u=0 to image->wwidth-1
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  px=x+u
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (px>=0)and(px<buffer->wwidth) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  *(buffer->argb_buffer+px+py*buffer->wwidth)=*(image->argb_buffer+u+v*image->wwidth)
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  end if
Ã,  Ã,  next
end sub

function create_sprite(byval image_i as integer)as integer
Ã,  Ã,  dim sprite as sprite pointer=callocate(len(sprite))
Ã,  Ã,  sprite->image_i=image_i
Ã,  Ã,  function=cast(integer,sprite)
end function

sub draw_sprite(byval buffer_i as integer,byval sprite_i as integer)
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  draw_image(buffer_i,sprite->image_i,sprite->x-sprite->handle_x,sprite->y-sprite->handle_y)
end sub

sub sprite_handle(byval sprite_i as integer,byval x as integer,byval y as integer)
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  sprite->handle_x=x
Ã,  Ã,  sprite->handle_y=y
end sub

sub move_sprite(byval sprite_i as integer,byval x as single,byval y as single)
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  sprite->x+=x
Ã,  Ã,  sprite->y+=y
end sub

sub position_sprite(byval sprite_i as integer,byval x as single,byval y as single)
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  sprite->x=x
Ã,  Ã,  sprite->y=y
end sub

function sprite_x(byval sprite_i as integer) as single
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  function=sprite->x
end function

function sprite_y(byval sprite_i as integer) as single
Ã,  Ã,  dim sprite as sprite pointer=cast(sprite pointer,sprite_i)
Ã,  Ã,  function=sprite->y
end function

function buffer_width(byval buffer_i as integer)as integer
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  function=buffer->wwidth
end function

function buffer_height(byval buffer_i as integer)as integer
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  function=buffer->height
end function

function buffer_address(byval buffer_i as integer)as integer pointer
Ã,  Ã,  dim buffer as graphics_buffer pointer=cast(graphics_buffer pointer,buffer_i)
Ã,  Ã,  function=buffer->argb_buffer
end function

sub free_image(byval image_i as integer)
Ã,  Ã,  dim image as graphics_buffer pointer=cast(graphics_buffer pointer,image_i)
Ã,  Ã,  deallocate image->argb_buffer
Ã,  Ã,  deallocate image
end sub

sub free_sprite(byval sprite_i as integer)
Ã,  Ã,  deallocate cast(sprite pointer,sprite_i)
end sub


and an example of it.

#include("graphics_lib")


data 4
data &h00000000,&h007f7f7f,&h00ff7faf,&h00ffff00
data 11,21
data 4,2
data 0,0,0,1,0,0,0,0,1,0,0
data 0,0,1,1,0,0,0,1,1,0,0
data 0,1,2,1,1,0,1,1,2,1,0
data 0,1,2,2,1,1,1,2,2,1,0
data 0,1,2,1,1,1,1,1,2,1,0
data 0,0,1,1,2,1,2,1,1,0,0
data 0,0,1,2,3,2,3,2,1,0,0
data 0,1,1,3,3,3,3,3,1,1,0
data 0,1,1,3,1,3,1,3,1,1,0
data 1,2,1,3,3,3,3,3,1,2,1
data 1,2,1,2,3,2,3,2,1,2,1
data 1,2,1,1,2,1,2,1,1,2,1
data 1,2,2,1,1,1,1,1,2,2,1
data 1,2,2,1,2,1,1,1,2,2,1
data 1,2,2,1,1,2,2,1,2,2,1
data 1,2,1,1,1,1,1,1,1,2,1
data 0,1,1,2,1,1,1,2,1,1,0
data 0,1,2,2,1,1,1,2,2,1,0
data 0,1,2,2,2,1,2,2,2,1,0
data 0,1,2,2,1,1,1,2,2,1,0
data 0,1,2,2,2,1,2,2,2,1,0

function create_my_image()as integer
Ã,  Ã,  dim as integer cols,cc,i,x,y,xx,yy
Ã,  Ã,  read cols
Ã,  Ã,  dim c(0 to cols-1) as integer
Ã,  Ã,  for i=0 to cols-1
Ã,  Ã,  Ã,  Ã,  read c(i)
Ã,  Ã,  next
Ã,  Ã,  dim as integer mx,my,sx,sy
Ã,  Ã,  read mx,my,sx,sy
Ã,  Ã,  dim image as integer=create_image(mx*sx,my*sy)
Ã,  Ã,  for y=0 to my-1
Ã,  Ã,  Ã,  Ã,  for x=0 to mx-1
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  read cc
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  for yy=y*sy to y*sy+sy-1
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  for xx=x*sx to x*sx+sx-1
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  write_pixel(image,xx,yy,c(cc))
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  next
Ã,  Ã,  function=image
end function


sub main()
Ã,  Ã,  dim my_graphics_buffer as integer=graphics(640,480,"test")
Ã,  Ã,  
Ã,  Ã,  dim image as integer=create_my_image()

Ã,  Ã,  dim sprite as integer=create_sprite(image),i as integer
Ã,  Ã,  sprite_handle(sprite,20,20)
Ã,  Ã,  dim moving_sprite(0 to 9) as integer,move_x(0 to 9) as single,move_y(0 to 9) as single
Ã,  Ã,  for i=0 to 9
Ã,  Ã,  Ã,  Ã,  moving_sprite(i)=create_sprite(image)
Ã,  Ã,  Ã,  Ã,  sprite_handle(moving_sprite(i),20,20)
Ã,  Ã,  Ã,  Ã,  position_sprite(moving_sprite(i),rnd*540.0+50.0,rnd*380.0+50.0)
Ã,  Ã,  Ã,  Ã,  move_x(i)=rnd*8.0-4.0
Ã,  Ã,  Ã,  Ã,  move_y(i)=rnd*8.0-4.0
Ã,  Ã,  next
Ã,  Ã,  
Ã,  Ã,  dim angle as single
Ã,  Ã,  while inkey$=""
Ã,  Ã,  Ã,  Ã,  for i=1 to 20000
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  write_pixel my_graphics_buffer,rnd*640,rnd*480,rnd*&hffffff
Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  for i=0 to 9
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  move_sprite(moving_sprite(i),move_x(i),move_y(i))
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (sprite_x(moving_sprite(i))<0.0) or (sprite_x(moving_sprite(i))>buffer_width(my_graphics_buffer)) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  move_x(i)=-move_x(i)
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (sprite_y(moving_sprite(i))<0.0) or (sprite_y(moving_sprite(i))>buffer_height(my_graphics_buffer)) then _
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  move_y(i)=-move_y(i)
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  draw_sprite(my_graphics_buffer,moving_sprite(i))
Ã,  Ã,  Ã,  Ã,  next
Ã,  Ã,  Ã,  Ã,  draw_line(my_graphics_buffer,320,240,320+100*sn(angle),240-100*cs(angle),&hff00ff)
Ã,  Ã,  Ã,  Ã,  position_sprite(sprite,320+100*sn(angle),240-100*cs(angle))
Ã,  Ã,  Ã,  Ã,  draw_sprite(my_graphics_buffer,sprite)
Ã,  Ã,  Ã,  Ã,  angle+=0.5
Ã,  Ã,  Ã,  Ã,  flip_buffer my_graphics_buffer
Ã,  Ã,  Ã,  Ã,  clear_buffer my_graphics_buffer
Ã,  Ã,  wend
Ã,  Ã,  free_sprite(sprite)
    for i=0 to 9
        free_sprite(moving_sprite(i))
    next
Ã,  Ã,  free_image(image)
Ã,  Ã,  close_graphics my_graphics_buffer
end sub

main()

Shockwave

Well, it works, which is more than I can say for my line draw command at the moment.
But seriously, I think that a community project where everyone chipped in an made routines for the lib would be an excellent idea, it would certainly make things a lot easier for people to get into freebasic and port their code over. I've been involved in large forum wide projects in the past that have failed (an RPG forum in Yabasic), at least with a project like this, it could never be deemed to be a failure.
People would just add bits to it.

I know for a fact that there are several people on the forum who would be generous enough with their code to contribute to it, but there are others who are protective of their sources (as they have every right to be). Would people involved in the project be pissed off if it was ripped without any credit being given?

If it ever did become a project that had lots of functionality it would be great.

As it is at the moment, it's a really nice example of how to build a library of routines from scratch.
Shockwave ^ Codigos
Challenge Trophies Won:

Stonemonkey

"I know for a fact that there are several people on the forum who would be generous enough with their code to contribute to it, but there are others who are protective of their sources (as they have every right to be). Would people involved in the project be pissed off if it was ripped without any credit being given?"

Like myself, and some others i'd imagine. One possibillity if you wanted to go down that road would be for someone or a few people to have control over it and make it a dll like i did before and have people submit code privately to be included, there could even be some sort of dbf forum logo appear when the graphics function is called.

Shockwave

That would be a good approach, making it a DLL. It wouldn't even be necessary to pop a logo up, detecting a key combination to flash a message to say who created it would do.
Shockwave ^ Codigos
Challenge Trophies Won:

TinDragon

I think for it to work as a community project everyone would have to agree that code they provide would be public domain or have one of those LPGL things or something on it, having it as closed source would make it difficult for people to contribute to as they would need to see how the code was stuctured to make functions that interact with it. Of course it would be open to people ripping it and not giving any credit but they can do that with any code snippet thats been posted already. And if people dont want to share their code they dont have to contribute. Perhaps we should open a debating thread in general discussion on the topic rather than fill Stonemonkeys rather cool thread with more ramblings :)

Stonemonkey

"Perhaps we should open a debating thread in general discussion on the topic rather than fill Stonemonkeys rather cool thread with more ramblings "
I don't mind, that's really why i started this in the first place.

Something i just tried, try remming out the clear_buffer in the main loop of the last code i posted.

As for writing more functions for it if it was a dll, yes it would at times make it more difficult but in the functions ive provided above it can give you direct access to the graphics buffer and any of the existing functions would be called the same way whether the function they're being called from is in the dll or not. I suppose the big problem would be if someone wanted for example to add functionality to the sprite system then they'd need access to the structures.

Shockwave

Well, I for one am interested in starting off a project like this. I know that my FB code is nowhere near up to the standard of yours SM but I'd be willing to add some stuff to it if you feel like optimising my buggy code :)
Shockwave ^ Codigos
Challenge Trophies Won:

Blitz Amateur

I really like the idea. I've been playing with some code. Not had any amazing progress, but I've been needing something to work on :)

Shockwave

This topic seems to be a bit dead in the water though, this is a big shame because it's something that would benefit everyone. I'm still interested in it anyway.
Shockwave ^ Codigos
Challenge Trophies Won:

Clyde

Yes, it is very interesting. Ive not posted as i've been reading with great interest.
Top Dollar StoneMonkey.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Stonemonkey

The stuff i've posted above is just an example of how i would go about it but if anyone wants to use that as a starting point then feel free to continue adding to it.

TinDragon

Haven't been coding much the last few days but I will have a bash at adding some more stuff to this if I can think of something really useful to add :)

Clyde

DrawImageRectangle could be a real nifty thang, especially for Bitmap scrollers / logos used with Sin / Cos.
Still Putting The IT Into Gravy
If Only I Knew Then What I Know Now.


Challenge Trophies Won:

Stonemonkey

It has 'draw_image' and 'draw_sprite' clyde although that could do with being redone to include stuff like alpha,scaling,masking and rotating or anything else like that.