Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

EmbossLight+Spec

Uploader:MitgliedEternal_Pain
Datum/Zeit:19.02.2014 20:57:55

Function Helligkeit(byval RGBvalue as UInteger,byval Helligkeitswert as Integer) as UInteger
    dim as integer RGB_Split(3)'[0]=rot,[1]=grün,[2]=blau,[3]=alpha
    dim as integer RGB_Max,RGB_Min,RGB_Range
    Dim as Double hue, saturation, value
    dim as integer huecase,r,g,b

    hue = 0 : saturation = 0 : value = 0

    RGB_Split(0)=LoByte(HiWord(RGBvalue))
    RGB_Split(1)=HiByte(LoWord(RGBvalue))
    RGB_Split(2)=LoByte(LoWord(RGBvalue))
    RGB_Split(3)=HiByte(HiWord(RGBvalue))

    RGB_Max = 0 : RGB_Min = 255
    for i as integer=0 to 2
        if RGB_Split(i)>RGB_Max then RGB_Max=RGB_Split(i)
        if RGB_Split(i)<RGB_Min then RGB_Min=RGB_Split(i)
    next i
    RGB_Range=RGB_Max-RGB_Min

    if RGB_Range then'keine Grauwerte
        select case RGB_Max
            case RGB_Split(0)                                 'Maximalwert:rot
                hue=60 * (0 + (RGB_Split(1)-RGB_Split(2)) / RGB_Range)
            case RGB_Split(1)                                 'Maximalwert:grün
                hue=60 * (2 + (RGB_Split(2)-RGB_Split(0)) / RGB_Range)
            case RGB_Split(2)                                 'Maximalwert:blau
                hue=60 * (4 + (RGB_Split(0)-RGB_Split(1)) / RGB_Range)
        end select
        if hue<0 then hue += 360
    else'Grauwerte
        hue=0
    end if

    value=(Helligkeitswert/255)'(RGB_Max/255)

    'If Helligkeitswert<245 then
        saturation = (RGB_range/RGB_Max)-value
    'Else
    '    saturation = (RGB_range/RGB_Max)-value
    'End If

    If saturation<0 Then saturation = 0

  huecase=int(hue/60)+1
  select case huecase
    case 1                        'grün steigend
      r=255 : g=255 * hue/60 : b=0
    case 2                        'rot fallend
      r=255 - (255 * (hue-60) / 60) : g=255 : b=0
    case 3                        'blau steigend
      r=0 : g=255 : b=255 * (hue-120)/60
    case 4                        'grün fallend
      r=0 : g=255 - (255 * (hue-180)/60) : b=255
    case 5                        'rot steigend
      r=255 * (hue-240)/60 : g=0 : b=255
    case 6                        'blau fallend
      r=255 : g=0 : b=255 - (255 * (hue-300)/60)
  end select

  r=(255 - (255-r)*saturation) * value
  g=(255 - (255-g)*saturation) * value
  b=(255 - (255-b)*saturation) * value

  Return rgba(r,g,b,RGB_Split(3))
End Function
Const as Single  Deg2Rad   = ATN(1)/45
Const as Single  Rad2Deg   = 45.0/Atn(1)

Type tmap
    as Integer   Width
    as Integer   Height
    as ubyte ptr map
End Type

Type tLight
    as Integer W 'Winkel
    as Integer H 'Höhe
    as Integer S 'Specular
End Type

Function EmbossLight(byref map as tmap ptr,byval Light as tLight) as UByte ptr
    if map=0 then return 0
    Dim as ubyte ptr lightmap = callocate(map->Width*map->Height)
    Dim as ubyte ptr specmap  = callocate(map->Width*map->Height)
    Dim as Integer   pix(0 to 4), nZ 'pixel
    Dim as Single    pLRad           'Azimut des Lichtes
    Dim as Single    pZRad           'Höhenwinkel
    Dim as Single    pSRad
    Dim as Single    pX              'Höhenwinkel bei 0 grd
    Dim as Single    pY              'Höhenwinkel bei 90 grd
    Dim as Single    lx, ly, ls, lw = Light.W*Deg2Rad
    Dim as Single    sx, sy, ss
'    open cons for output as #1
    For y as Integer = 0 to map->Height-1
    For x as Integer = 0 to map->Width-1
        pix(0) = map->map[x+(y*map->Width)]
        If pix(0) = 0 Then Continue For
        If (x-1 >          -1) Then pix(1) = map->map[(x-1)+(y*map->Width)]-Light.H Else pix(1) = -Light.H 'l
        If (x+1 <  map->Width) Then pix(2) = map->map[(x+1)+(y*map->Width)]-Light.H Else pix(2) = -Light.H 'r
        If (y-1 >          -1) Then pix(3) = map->map[x+((y-1)*map->Width)]-Light.H Else pix(3) = -Light.H 'o
        If (y+1 < map->Height) Then pix(4) = map->map[x+((y+1)*map->Width)]-Light.H Else pix(4) = -Light.H 'u

        nZ    = Light.H

        lx    = x+cos(lw)        : ly    = y+sin(lw)
        pX    = (pix(2)-pix(1))
        pY    = (pix(4)-pix(3))

        If pX<>0 orelse pY<>0 Then
            If Light.S Then
                pLRad = atan2(ly-y,lx-x)
                pZRad = atan2(y-(y+pY),x-(x+pX))
                ls    = sin(pLRad-pZRad)
                nZ   += nZ*ls
                'Spec
                If Light.S and ls>0.99f then specmap[x+(y*map->Width)]=255
            End If
        End If

        If (nZ <   1) Then nZ =   1
        If (nZ > 255) Then nZ = 255
        lightmap[x+(y*map->Width)]=nZ
    Next x
    Next y

    If Light.S Then
        ss = Light.S/255
        For s as Integer = 0 to 4
        For y as Integer = 0 to map->Height-1
        For x as Integer = 0 to map->Width-1
            pix(0) = specmap[x+(y*map->Width)]
            If pix(0) = 0 Then Continue For
            If (x-1 >          -1) Then pix(1) = specmap[(x-1)+(y*map->Width)] Else pix(1) = -Light.H 'l
            If (x+1 <  map->Width) Then pix(2) = specmap[(x+1)+(y*map->Width)] Else pix(2) = -Light.H 'r
            If (y-1 >          -1) Then pix(3) = specmap[x+((y-1)*map->Width)] Else pix(3) = -Light.H 'o
            If (y+1 < map->Height) Then pix(4) = specmap[x+((y+1)*map->Width)] Else pix(4) = -Light.H 'u
            specmap[x+(y*map->Width)] = ((pix(0)*2)+pix(1)+pix(2)+pix(3)+pix(4))/6
        Next x
        Next y
        Next s

        For y as Integer = 0 to map->Height-1
        For x as Integer = 0 to map->Width-1

            pix(0) = lightmap[x+(y*map->Width)]
            If pix(0) = 0 Then Continue For
            pix(1) = specmap[x+(y*map->Width)]
            If pix(1) = 0 Then Continue For
            nZ = pix(0)+(pix(1)*ss)
            If nZ>255 Then nZ = 255
            lightmap[x+(y*map->Width)] = nZ
        Next x
        Next y
    End If

    deallocate (specmap)
    return lightmap
End Function

Screenres 640,480,32
Dim as ubyte     z
Dim as tmap ptr  testmap = NEW tmap
Dim as tlight    testlight

testmap->Width  = 640
testmap->Height = 480
testmap->map    = callocate(640*480)

Dim as any ptr zimage = Imagecreate(640,480,0)
BLoad "light_test.bmp",zimage

For y as Integer = 0 to testmap->Height-1
For x as Integer = 0 to testmap->Width-1
    z = point(x,y,zimage) and &hFF
    testmap->map[x+(y*testmap->Width)] = z
Next x
Next y

Dim w as single
Dim lightmap as ubyte ptr
Do
    w  += 2
    if w > 359 then w-=360
    lightmap = EmbossLight(testmap,type(w,60,175))
    if lightmap then
    screenlock
        cls
        line(0,0)-(testmap->Width-1,testmap->Height-1),&h333388,bf

        For y as Integer = 0 to testmap->Height-1
        For x as Integer = 0 to testmap->Width-1
            z = lightmap[x+(y*testmap->Width)]
            if z then pset (x,y),Helligkeit(&hFF0000,z)
    'z = point(x,y,zimage) and &hFF
    'if z then pset(x,y),rgb(z,z,z)'testmap->map[x+(y*testmap->Width)] = z

        Next x
        Next y

        line(250,50)-(250+(cos((w-90)*Deg2Rad)*100),50+(sin((w-90)*Deg2Rad)*100)),&hFF8800
        locate 1,1:?w
    screenunlock
    deallocate(lightmap)
    end if
    lightmap = 0
    sleep 50
Loop until multikey(&h01)


sleep
deallocate(testmap->map)
delete testmap
imagedestroy(zimage)