Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: QB: Optica3D-moottori

Sivun loppuun

hunajavohveli [05.08.2004 18:23:27]

#

Moni varmasti muistaa noin puoli vuotta sitten julkaisemani The Linkku3D-moottorin joka saavutti vastoin kaikkia odotuksiani melko suuren suosion. Sen takia "vastoin odotuksiani", että se on omasta mielestäni suoraan sanottuna surkea buginen härpäke.
Päätinpä kuitenkin aloittaa uudestaan aivan puhtaalta pöydältä, ja tulokseksi sain tämän moottorin, joka lähti alkuun siitä kun Gwaur ja Peki kertoivat eräänlaisesta perspektiivikorjauksesta. Arvasin tietysti, että eihän tuo nyt vielä riitä mihinkään, mutta sitten keksinkin, että jos kerran kameraa ei voi pyörittää niin kuin Linkussa, ilman että syntyy buginen linkkumoottori, niin täytyy näin ollen pyörittää maailmaa kameran ympärillä, jolloin syntyy illuusio, joka näyttää siltä kuin kamera pyörisi päinvastaiseen suuntaan kuin maailma. Irkissä jotkut neuvoivat minua käyttämään matriiseja ja verteksipyörityksiä tjsp., mutta halusin edelleen kokeilla, voisinko tehdä moottorin alusta alkaen itse, opettelematta mitään mistään manuaaleista, tai muista valmiista kaavoista. Ja perspektiivikorjaus (eli tasan kaksi lyhyttä riviä koodia) on edelleenkin ainoa asia tässä moottorissa, jota en itse keksinyt. Tavallaan se on pohja, josta lähdin liikkeelle. Huomasin kuitenkin, että Gwaurin ja Pekin näyttämä korjaus oli epätäydellinen, joten jouduin tekemään siihen paljon parannuksia, jotta se toimisi täydellisesti. Myöhemmin huomasin tavallaan käyttäneenikin perspektiivikorjausta aikaisemmin ensimmäisessä koodivinkissäni, mutten ollut vielä silloin tajunnut sen merkitystä.
Aloitin tämän uuden moottorin 18.6 ja sain valmiiksi 21.7, eli reilussa kuukaudessa. Bugeja saattaa löytyä, mutta nyt kaavojen pitäisi ainakin olla kunnollisia, eikä mitään linkkuun menemistä ainakaan omasta mielestäni tapahdu.
Nimi "Optica" kuulostaa kenties vähän liian hienolta tavallisesta rautalanka-moottorista, ja googlettamalla selvisi, että nimeä on jo ennestään käytetty jossain toisessa 3d-moottorissa, mutta keksin nimen kuvastamaan sitä, että se on eräänlainen optinen korjaus verrattuna Linkkuun, ja nimi toimiikin vain etupäässä vain koodinimenä, eikä minään virallisena merkkinä.

Lisäsin koodiin kaksi esimerkki-maailmaa, jotka demonstroivat moottorin toimintaa. Ohjelma kysyy alussa kunpaa maailmaa haluaa kokeilla.
Lisäksi ohjelma kysyy, halutaanko mukaan lisähidastusta. Tämä sen vuoksi, että nopeimmilla koneilla moottori pyörisi aivan liian nopeasti.

Näppäimet, joilla liikutat kameraa:
4,6 käännä vasemmalle ja oikealle
9,3 käännä ylös ja alas
8,5 liikuta eteenpäin ja taaksepäin

Koodissa ei omasta mielestäni ole samaa purkkamaisuutta kuin Linkussa, ja se on tällä kertaa sisennetty, paremmin kommentoitu, ja muutenkin paljon selkeämpää.
Verteksit ja matriisit ovat luultavasti kuitenkin se parempi tapa 3d:n luomiseen, joten tästä ei kannata aivan vakavasti mallia ottaa, jos 3d:tä haluaa luoda. 3d:n luominen QB:llä vain on askarruttanut niin monia, eikä 3d-kirjastoja QB:lle juuri ole, niin että saattaa tästä jopa jotain hyötyä olla. Tästedes teen 3d:tä kuitekin luultavasti C:llä tai C++:lla, kunhan saan OpenGL:n, tai DirectX:n toimimaan. Näillä QB-moottoreilla pyrin siis vain kokeilemaan, kuinka paljon pystyisin tekemään alusta alkaen itse.

Niin kauan kuin en pysty C:tä, tai C++:aa käyttämään, koodailen VB:llä Eternity-nimistä peliä, jossa käytän Optica3D:tä.
Eternityn päivitykset (ja myös monet muut tekeleeni, mm. Linkku3D:llä tehty 3D-räiskintä) ovat saatavilla kotisivuiltani:
http://koodaa.mine.nu/~vohveli/

Suurkiitos tejeezille kotisivutilasta!

DECLARE SUB DrawBg (YA AS SINGLE)
DECLARE SUB GenerateWorld ()
DECLARE FUNCTION Rndl! (ScWidth AS INTEGER)

TYPE Camera       'Kamera
  X AS SINGLE   'ulottuvuudet
  Y AS SINGLE   '...
  Z AS SINGLE   '...
  XA AS SINGLE  'kulmat
  YA AS SINGLE  '...
END TYPE

TYPE Vertex       '3D-piste
  X AS SINGLE   'ulottuvuudet
  Y AS SINGLE   '...
  Z AS SINGLE   '...
END TYPE

TYPE Monitor       '2D-piste
  X AS LONG     'ulottuvuudet
  Y AS LONG     '...
  V AS INTEGER  'n?kyvyys-lippu
END TYPE

COMMON SHARED DataMode AS INTEGER
COMMON SHARED Dot() AS Vertex, DAm AS INTEGER
ON ERROR RESUME NEXT


CLS
PRINT "Optica3D engine 0.4.0"
PRINT "Programmed by Hunajavohveli"
PRINT
PRINT "1=suorakulmioita 2=avaruus ?"
INPUT "", DataMode
PRINT "Lis?hidastusta? 0=ei 1=kyll?"
INPUT "", SlowMode


DIM Cam AS Camera              'Kamera
DIM Dot(1 TO 1000) AS Vertex   'Pisteiden absoluttiset koordinaatit
DIM Rot(1 TO 1000) AS Vertex   'Kameran arvojen mukaan absoluuttisista koordinaateista generoidut koordinaatit
DIM Scr(1 TO 1000) AS Monitor  'N?yt?lle piirrett?v?t 2d-koordinaatit

RANDOMIZE TIMER
GenerateWorld    'Generoidaan maailma


'Kameran ominaisuudet
    Scale = 320     'Skaala (kokeile muuttaa)
      Cam.X = 0       'ulottuvuudet
      Cam.Y = -5      '...
      Cam.Z = 0       '...


'Vaihdetaan n?ytt?tilaa
    SCREEN 7, 0, , 1    'Kaksoispuskurointi
      CenterX = 160       'N?yt?n keskipiste
      CenterY = 100       '...


'K?ynnistet??n moottori...

DO

DrawBg Cam.YA     'Piirret??n tausta

'Projektoidaan 3d-koordinaatit 2d-tasoon

FOR a = 1 TO DAm
 Scr(a).X = 0   'nollataan edelliset 2d-koordinaatit
 Scr(a).Y = 0   '...
 Scr(a).V = 0   '...

   'suhteutetaan pisteiden absoluuttiset koordinaatit kameran koordinaatteihin
  rx = Dot(a).X - Cam.X
  ry = Dot(a).Y - Cam.Y
  rz = Dot(a).Z - Cam.Z

   'generoidaan suhteutetuista koordinaateista uudet kameran kulmien mukaan
  Rot(a).X = COS(Cam.XA) * rx + SIN(Cam.XA) * rz
  Rot(a).Z = COS(Cam.XA) * COS(Cam.YA) * rz - SIN(Cam.XA) * COS(Cam.YA) * rx + SIN(Cam.YA) * ry
  Rot(a).Y = COS(Cam.YA) * ry - SIN(Cam.YA) * COS(Cam.XA) * rz - SIN(Cam.YA) * -SIN(Cam.XA) * rx

   't?ysin suhteutetut 3d-koordinaatit
  rz = Rot(a).Z
  rx = Rot(a).X
  ry = Rot(a).Y


   'perspektiivikorjaus

  IF rz > 0 THEN                      'jos piste kameran edess?...
    sx = rx * Scale / rz + CenterX
    sy = ry * Scale / rz + CenterY
    Scr(a).V = -1                      'n?kyvyys p??lle
    IF DataMode = 2 THEN PSET (sx, sy)   'pisteen piirto
  ELSEIF rz < 0 THEN                           'takana...
    sx = -(rx * Scale / rz) * -rz + CenterX
    sy = -(ry * Scale / rz) * -rz + CenterY
  ELSE                                             'samalla syvyystasolla...
    IF ry <> 0 AND rx <> 0 THEN
      sx = rx * (200 / rx) * SGN(rx) + CenterX
      sy = ry * (200 / ry) * SGN(ry) + CenterY
    ELSEIF rx <> 0 THEN
      sx = CenterX + CenterX * SGN(rx)
      sy = CenterY
    ELSEIF ry <> 0 THEN
      sx = CenterX
      sy = CenterY + CenterY * SGN(ry)
    ELSE
      sx = CenterX
      sy = CenterY
    END IF
  END IF      't?h?n loppuu perspektiivikorjaus

    'tallennetaan generoidut 2d-koordinaatit taulukkoon
  Scr(a).X = sx
  Scr(a).Y = sy

NEXT a


'Piirret??n viivat n?yt?lle

IF DataMode = 1 THEN
FOR a = 1 TO DAm STEP 8
  x1 = Scr(a).X: x2 = Scr(a + 1).X: x3 = Scr(a + 2).X: x4 = Scr(a + 3).X
  y1 = Scr(a).Y: y2 = Scr(a + 1).Y: y3 = Scr(a + 2).Y: y4 = Scr(a + 3).Y
  v1 = Scr(a).V: v2 = Scr(a + 1).V: v3 = Scr(a + 2).V: v4 = Scr(a + 3).V
  x5 = Scr(a + 4).X: x6 = Scr(a + 5).X: x7 = Scr(a + 6).X: x8 = Scr(a + 7).X
  y5 = Scr(a + 4).Y: y6 = Scr(a + 5).Y: y7 = Scr(a + 6).Y: y8 = Scr(a + 7).Y
  v5 = Scr(a + 4).V: v6 = Scr(a + 5).V: v7 = Scr(a + 6).V: v8 = Scr(a + 7).V

  IF v1 OR v2 THEN LINE (x1, y1)-(x2, y2), 0
  IF v2 OR v3 THEN LINE (x2, y2)-(x3, y3), 0
  IF v3 OR v4 THEN LINE (x3, y3)-(x4, y4), 0
  IF v4 OR v1 THEN LINE (x4, y4)-(x1, y1), 0
  IF v5 OR v6 THEN LINE (x5, y5)-(x6, y6), 0
  IF v6 OR v7 THEN LINE (x6, y6)-(x7, y7), 0
  IF v7 OR v8 THEN LINE (x7, y7)-(x8, y8), 0
  IF v8 OR v5 THEN LINE (x8, y8)-(x5, y5), 0
  IF v1 OR v5 THEN LINE (x1, y1)-(x5, y5), 0
  IF v2 OR v6 THEN LINE (x2, y2)-(x6, y6), 0
  IF v3 OR v7 THEN LINE (x3, y3)-(x7, y7), 0
  IF v4 OR v8 THEN LINE (x4, y4)-(x8, y8), 0

NEXT a
END IF


PCOPY 0, 1                       'n?ytet??n piirretty kuva
IF SlowMode THEN WAIT &H3DA, 8     'lis?hidastusta tarpeen mukaan


'N?pp?imet

a$ = INKEY$
 IF a$ = "8" THEN Speed = Speed + 1
 IF a$ = "5" THEN Speed = Speed - 1
 IF a$ = "6" THEN Turn = Turn - .01
 IF a$ = "4" THEN Turn = Turn + .01
 IF a$ = "9" THEN Turn2 = Turn2 - .01
 IF a$ = "3" THEN Turn2 = Turn2 + .01

  Cam.Z = Cam.Z + COS(Cam.XA) * COS(Cam.YA) * Speed  'liikutetaan kameraa
  Cam.X = Cam.X - SIN(Cam.XA) * COS(Cam.YA) * Speed
  Cam.Y = Cam.Y + SIN(Cam.YA) * Speed

  Cam.XA = Cam.XA + Turn     'k??nnet??n kameraa
  Cam.YA = Cam.YA + Turn2

  IF Cam.XA > ATN(1) * 2 THEN Cam.XA = -ATN(1) * 8 + Cam.XA      'ei
   IF Cam.XA < -ATN(1) * 6 THEN Cam.XA = ATN(1) * 8 + Cam.XA     'saa
  IF Cam.YA > ATN(1) * 2 THEN Cam.YA = -ATN(1) * 8 + Cam.YA      'menn?
   IF Cam.YA < -ATN(1) * 6 THEN Cam.YA = ATN(1) * 8 + Cam.YA     'yli

LOOP UNTIL a$ = CHR$(27)   'mit?k?h?n t?m? mahtaa tehd?...
SUB GenerateWorld

'Generoidaan palikoita/t?hti?
'(eli pelkk?? koordinaattien arpomista, ei kaivanne lis?selityksi?)

SELECT CASE DataMode
CASE 1
   DAm = 8 * 40
  FOR a = 1 TO DAm STEP 8
   X = Rndl(300)
   Z = Rndl(300)
   H = -INT(RND * 10 + 20)
      Dot(a).X = -10 + X
      Dot(a).Y = H
      Dot(a).Z = Z
      Dot(a + 1).X = 10 + X
      Dot(a + 1).Y = H
      Dot(a + 1).Z = Z
      Dot(a + 2).X = 10 + X
      Dot(a + 2).Y = 0
      Dot(a + 2).Z = Z
      Dot(a + 3).X = -10 + X
      Dot(a + 3).Y = 0
      Dot(a + 3).Z = Z
        Dot(a + 4).X = -10 + X
        Dot(a + 4).Y = H
        Dot(a + 4).Z = Z + 20
        Dot(a + 5).X = 10 + X
        Dot(a + 5).Y = H
        Dot(a + 5).Z = Z + 20
        Dot(a + 6).X = 10 + X
        Dot(a + 6).Y = 0
        Dot(a + 6).Z = Z + 20
        Dot(a + 7).X = -10 + X
        Dot(a + 7).Y = 0
        Dot(a + 7).Z = Z + 20
  NEXT a
CASE 2
   DAm = 1000
  FOR a = 1 TO DAm
    Dot(a).X = Rndl(300)
    Dot(a).Y = Rndl(300)
    Dot(a).Z = Rndl(300)
  NEXT a
END SELECT

END SUB
SUB DrawBg (YA AS SINGLE)

'piirret??n joko avaruus tai taivas/maa kameran Y-kulman mukaan

SELECT CASE DataMode
CASE 1
  IF YA < ATN(1) * 2 AND YA > -ATN(1) * 2 THEN
    Skyline = 100 - YA * 300
    LINE (0, 0)-(319, Skyline), 3, BF
    LINE (0, Skyline)-(319, 199), 2, BF
  ELSE
    Skyline = 100 - (YA + ATN(1) * 4) * 300
    LINE (0, 0)-(319, Skyline), 2, BF
    LINE (0, Skyline)-(319, 199), 3, BF
  END IF
CASE 2
  LINE (0, 0)-(319, 199), 0, BF
END SELECT

END SUB
FUNCTION Rndl (ScWidth AS INTEGER)

'satunnaislukugeneraatiota v?lilt? -1 - +1

Rndl = -ScWidth + INT(RND * ScWidth * 2)

END FUNCTION

Metabolix [05.08.2004 23:51:17]

#

Miten olisi kommenttien korjaaminen niin, että ääköset olisivat kunnossa?
Kysynpä nyt tässä, mihin näillä 3D-systeemeillä oikeastaan pystyy? Siis mitä kaikkia ominaisuuksia löytyy? Teksturointi? En jaksa tuota QB-koodia käydä läpi niin tarkasti, että saisin sen itse selville.
Sitten vielä, mikä mahtaa olla perspektiivikorjaus?

Blaze [06.08.2004 05:19:05]

#

lainaus:

Irkissä jotkut neuvoivat minua käyttämään matriiseja ja verteksipyörityksiä tjsp.

viznut ^_^

hunajavohveli [06.08.2004 09:42:57]

#

Metabolix kirjoitti:

Kysynpä nyt tässä, mihin näillä 3D-systeemeillä oikeastaan pystyy? Siis mitä kaikkia ominaisuuksia löytyy? Teksturointi?

Teksturointia en itse osaa tällä menetelmällä luoda, mutta pisteiden projektoiminen 2d-tasoon onnistuu (tämä on siis perspektiivikorjaus), joten viivojen piirto onnistuu, vetämällä Linellä pisteestä pisteeseen. Ja Circlellä voi tietysti piirtää myös palloja. Itselleni riittää lähinnä, että maailma näyttää kolmiulotteiselta. Ääkkösten muuttumiselle en voi mitään. Koodivinkkien lähetysboxissa on ilmeisesti eri merkistökoodit ääkkösille kuin notepadissa.

Edit: Joku muuten kuitenkin kysyy taas binarya, joten tässä on:
http://koodaa.mine.nu/~vohveli/Optica3D/OPTIC040.zip

Antti Laaksonen [06.08.2004 11:54:12]

#

Näyttää varsin hyvältä. Matriisit varmaan lähinnä nopeuttaisivat laskuja, kaikki viivathan näkyvät tuossa jo oikeilla paikoilla. Oletko muuten kokeillut täyttää viivojen muodostamia alueita väreillä?

hunajavohveli [06.08.2004 13:24:52]

#

Kokeilin sitä PAINT-käskyllä, mutta sen kanssa tuli ongelmia, ja lisäksi se oli todella hidasta.

Antti Laaksonen [06.08.2004 14:16:25]

#

PAINTia huomattavasti nopeampaa voisi olla tehdä väritys LINEillä - väritettävällä alueella kun on suorat reunat. Jos piirtämisen aloittaa taaimmaisesta kuviosta ja päättää lähimpänä olevaan, värityksen pitäisi mennä oikein.

hunajavohveli [06.08.2004 17:40:59]

#

Täydellisiä suorakulmioita toki saa täytettyä LINEn BF-parametrillä, niin kuin tästä Linkku3D:llä tehdystä pelistä käy ilmi, mutta tässähän kyseinen menetelmä ei kelpaa. Voisin toki värittää LINEllä niin paljon kuin mahdollista, mutta joutuisin silti turvautumaan PAINTiin.

Antti Laaksonen [06.08.2004 20:07:12]

#

Ajattelin siis, että värittäisit nelikulmion sopivalla määrällä viivoja kulmion reunoista toiseen...

hunajavohveli [06.08.2004 22:44:28]

#

Tuota voisin kyllä kokeilla, tosin saattaisi siitäkin tulla melko hidas..

nomic [06.08.2004 23:15:08]

#

näyttää tosi hyvältä, jännää nähdä mihin kaikkiin qb pystyy :) ja hunajavohveli saakos tuota avaruus juttua soveltaa omaan harjoitukseen? olen tässä alkanut koodata samantapaista kolmiuloitteista avaruusmaailmaa vb:llä mutta ongelmana on etäisyydet jne... tai no tästähän nyt opin nekin asiat jne... mutta hienoja ovat, täytyy myöntää, ja mitä siellä ylhäällä vinetään ääkkösistä, ennenkin annettu anteeksi koodivinkeissä se että ääkköset ei ole tule mukaan, ja kai nyt jokainen joka osaa lukea, ymmärtää että mitä sanotaan missäkin kohtaa...
ja vielä mihin näillä 3d-jutuilla pystyy? voit oppia niistä itse jotain, olen käsittänyt että koodivinkkien tarkoitus täällä on se että näytetään oma osaaminen, saadaan palautetta ja koodin testaajat vielä samalla voivat oppiakin jotain uutta, olet melko varmasti oppinut jotain silloin jos osaat tehdä samantyylisen vaikka rumemmankin toisella kielellä, kunhan idea on sama...

minä opin tästä muutamia asioita eikä koskaan voi oppia liikaa (paitsi kun aivokapasiteetti tulee vastaan ;) )

noni, vineminen loppui :) en löytänyt mitään elämää suurempaa bugia, jouduin vaan itse tekemään lisäyksen koodiin että kun painaa spacee niin se nollaa kaikki että paljon käännytään mihin suuntaan jne... kun kone on niin ärhäkkä et alkoi simu riehumaan niin että oli vaikeaa kontrolloida suuntaa jne... :)

Latska [07.08.2004 06:23:53]

#

Taas yksi syy lisää, miksi kannattaa aloittaa koodaus. Toivottavasti hamassa tulevaisuudessa voisi käydä näin:
Eieiei! Ei tuota pysty suorittamaan tekstitilassa. Lisäät tuohon SCREENin. Hyvä. Eikä INPUTtia voi laittaa tuohon tai voihan sen mutta ei siinä ole mitään järkeä... :)

Asiallista koodaustyötä jälleen kerran.

hunajavohveli [07.08.2004 10:05:11]

#

nomic kirjoitti:

saakos tuota avaruus juttua soveltaa omaan harjoitukseen?

Sitähän varten tämä koodivinkeissä on. :)
Olisi kiva, jos kuitenkin mainitsisit ohjelmissasi moottorin alkuperäisen suunnittelijan, jos esim. levität niitä netissä.

nomic kirjoitti:

olen tässä alkanut koodata samantapaista kolmiuloitteista avaruusmaailmaa vb:llä

Täältä löytyy VB:lle portattu käännetty avaruuspeli. Lähdekoodin julkaisen luultavasti, kun/jos se valmistuu.

nomic kirjoitti:

ja vielä mihin näillä 3d-jutuilla pystyy?

Vastasin tähän tuossa ylempänä. Mitään sen tarkempaa en osaa sanoa, mutta ainakin pystyisin samaan kuin tuossa Linkku3D-pelissä, ja paremmin.

nomic kirjoitti:

jouduin vaan itse tekemään lisäyksen koodiin että kun painaa spacee niin se nollaa kaikki että paljon käännytään mihin suuntaan jne...

Joo, on totta kai täysin suotavaa, että koodaa itse peliin paremman ohjauksen, jos se tuntuu helpommalla. Toivon todella, että koodin soveltaminen on nyt helpompaa kuin Linkussa.

comi [07.08.2004 21:08:47]

#

ei pysty just nyt kokeilemaan, ku jotain häikkää dos ohjelmia käyttäessä, mutta kuulostaa loistavalta, ja kuhan saan taas koneen toimimaan kunnolla on tätä pakko testata heti :D

nomic [08.08.2004 04:19:52]

#

hunajavohveli, jooh, siis tottakai jos sovellan koodia omiin projektiini niin mainitsen alkuperäisen tekijän ja jos se julkaistaan oman koneen ulkopuolella jossain tai menee jotain reittiä levitykseen niin sitten otan yhteyttä sähköpostitse alkuperäiseen tekijään jne... :)

mutta mahtava koodivinkki, ei tästä mihinkään pääse :)

makeuu [09.08.2004 13:01:58]

#

tästä on _varmasti_ hyötyä jollekkin ;)

Puhveli [16.04.2005 21:34:44]

#

Aika nätti on. Tajusin miksei nimi ollu Linkku 2 - en löytäny tästä mitään linkkua, kaikki näyttää toimivan mainiosti :). Ainut mikä jäi kalvamaan on näppäimet: ennemminkin ysillä jos kattois alas ja kolmosella ylös ni olis lentosimumpi.
edit: Vielä jos olisi spin-mahdollisuus, että voisi keinuttaa kameraa puolelta toiselle...

temu92 [22.04.2006 22:27:27]

#

en jaksa testailla varsinkin kun ei oo ees qb:n kääntäjää nyt koneella. binääri olis kiva tai vaikka shotteja

Kaape [08.10.2006 15:20:12]

#

En olis arvannu, et qb:llä pystyy mitään 3d-grafiikkaa tekemään. Tuli aika hyvä kun tein tosta joystickillä ohjattavan.

Juhko [23.10.2006 14:50:13]

#

Wautsi wau!

Dude [20.03.2007 17:45:16]

#

Tuoshan tulee vaan kuva joka ei liiku mihinkää. Eikö tuota sais nopeutettua? Tämä kone on 366 mhz.

moptim [06.05.2007 08:56:50]

#

Siis hei, tämähän on aivan mahtava! Dude, kai muistat oikeat näppäimet (löytyvät Numpadista).

Dude [04.07.2007 12:30:49]

#

Hups en käyttänyt näppäimiä. hieno on.
Edit: Tein tuosta UGLlän avulla nopiamman version :).


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta