• Print

Author Topic: Simple 3D triangle library  (Read 843 times)

SkyCharger001

  • Hero Member
  • *****
  • Posts: 1594
Simple 3D triangle library
« on: January 05, 2013, 09:04:04 AM »
https://dl.dropbox.com/u/37382196/triangle.zip
an attempt to give QB64-SDL 3D support

This library offers the following TYPES:
Code: [Select]
*ZBUFFER:
-.A: 32-bit color image.
-.B: actual z-buffer (8/16/24/32 bits)
-.C: 8-bit hotspot image. (reading from this image makes it easy to do point-and-click)
-.MODE:
--0 uninitialized (can trigger INVALID HANDLE error)
--1 TO 4: pixel-size of zbuffer in Bytes.
--ELSE: error-code (can trigger INVALID HANDLE error)

*RGB: 3 unsigned bytes (.R,.G,.B)

*VECTOR
-.col: RGB type (doubles as texture coordinates)
-- texture-modes
--.R: X09-X08-X07-X06-X05-X04-X03-X02
--.G: Y09-Y08-Y07-Y06-Y05-Y04-Y03-Y02
--.B: Y01-Y00-X01-X00-S03-S02-S01-S00 S=SCALE
-.X
-.Y
-.Z
-.TEXTURE: IMAGE HANDLE OF TEXTURE

and the following functions/subs
Code: [Select]
*zin (zbuffer,xsize,ysize,mode)
 initialize zbuffer
-xsize: width of zbuffer
-ysize: height of zbuffer
-mode:
-- 0: 8 bits zbuffer
-- 1: 16 bits zbuffer
-- 2: 24 bits zbuffer
-- 3: 32 bits zbuffer
-- ELSE: set zbuffer.mode to -1

*dest3d(zbuffer): set active zbuffer

*triangle(vector a,vector b,vector c, hot[_unsigned _byte],rendermode[_unsigned _byte])
-vector a,b,c (start-/end-points of the triangle)
--vector a.texture serves as the texture for the triangle in the texture-modes
-hot: hotspot value of triangle.
-rendermode:
--0,3,6... Goraud shading
--1,4,7... Texture
--2,5,8... Super-Imposed texture (allows for portal effect)

*dtriangle(vector a,vector b,vector c, hot[_unsigned _byte],rendermode[_unsigned _byte],zbuffer)
-like triangle but allows you to tell what zbuffer to use (slower due to increased overhead)

*zcls(zbuffer) clears a zbuffer

*checkvec(vector,index)
*checkz (zbuffer,index)
-functions for reading the values of a vector/zbuffer (obsolete: used to verify proper connection between wrapper and library)
EDIT: minor bugfix
« Last Edit: January 05, 2013, 12:58:22 PM by SkyCharger001 »

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #1 on: January 18, 2013, 03:44:22 PM »
Looks cool, except for the fact that it depends on a C header file. I know there are speed advantages to doing it that way, but I personally prefer to stick to pure QB64.

Also, will this work with QB64-GL?

SkyCharger001

  • Hero Member
  • *****
  • Posts: 1594
Re: Simple 3D triangle library
« Reply #2 on: January 19, 2013, 02:24:23 AM »
Quote from: fluffrabbit on January 18, 2013, 03:44:22 PM
Looks cool, except for the fact that it depends on a C header file. I know there are speed advantages to doing it that way, but I personally prefer to stick to pure QB64.

Also, will this work with QB64-GL?
it may or may not work in QB64-GL, but THAT already has 3D support built-in, which would definitely beat this library on any benchmark.
As for PURE QB64, this library is a port of such a library... which had a maximum frame-rate of 2 frames per second for an image of relatively low complexity.

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #3 on: January 19, 2013, 12:09:00 PM »
Quote from: SkyCharger001 on January 19, 2013, 02:24:23 AM
Quote from: fluffrabbit on January 18, 2013, 03:44:22 PM
Looks cool, except for the fact that it depends on a C header file. I know there are speed advantages to doing it that way, but I personally prefer to stick to pure QB64.

Also, will this work with QB64-GL?
it may or may not work in QB64-GL, but THAT already has 3D support built-in, which would definitely beat this library on any benchmark.
As for PURE QB64, this library is a port of such a library... which had a maximum frame-rate of 2 frames per second for an image of relatively low complexity.

Wow, that is slow! Do you have a demo to show the speed and graphical quality of this library?

SkyCharger001

  • Hero Member
  • *****
  • Posts: 1594
Re: Simple 3D triangle library
« Reply #4 on: January 20, 2013, 04:39:28 AM »
I only have a proper demo for THIS library, the only demo I still have for the old library simply draws triangles at random positions.
NOTE: I suspect that on most systems this will run slower than on my system.
Code: [Select]
CONST zmode = 0
CONST zmax~&& = (256 ^ (zmode + 1)) - 1
PRINT zmax
CONST zsize = zmax / 4
'$include:'triangle.bi'
DIM SHARED texture AS LONG, atexture AS LONG
DIM SHARED tz(-(zmax * 8) TO (zmax * 8))
DIM p AS _INTEGER64
DIM zp AS _FLOAT
zp = .1 ^ (1 / (zmax * 8))
PRINT zp
FOR p = -(zmax * 8) TO zmax * 8
    tz(p) = zp ^ p
NEXT p
atexture = _SCREENIMAGE
tw = _WIDTH(atexture)
th = _HEIGHT(atexture)
xsize = (tw / 3) + 1
ysize = xsize * 9 / 16
texsize = (tw / 1)
teysize = (th / 1)
texture = _NEWIMAGE(texsize, teysize, 32)
tsx = _WIDTH(atexture) / 2
tsy = _HEIGHT(atexture) / 2
CONST NODES = 65
CONST SUBNODES = 65
CONST RINGSIZE = 300
'CONST DIAMETER = 400
CONST CentY = 0
CONST centz = zmax / 4
CONST centx = 0 'RINGSIZE
CONST twist = 0
CONST ptwist = 1
CONST qrot = 3
CONST prot = 1
CONST mrot = 8
CONST refrate = 1

CONST VD = RINGSIZE + DIAMETER


rad = ATN(1) * 4 / 180
DIM SHARED n(NODES, SUBNODES) AS vector


FOR p = 0 TO NODES - 1
    ap = (180 * p / (NODES - 1)) + 180
    FOR q = 0 TO SUBNODES - 1
        cp = (180 * q / (SUBNODES - 1)) - 90
        caa = COS(cp * rad)
        saa = SIN(cp * rad) * RINGSIZE
        n(p, q).x = COS(ap * rad) * RINGSIZE * caa
        n(p, q).z = SIN(ap * rad) * RINGSIZE * caa
        n(p, q).y = saa
        n(p, q).z = (zsize * n(p, q).z / VD) + centz
        n(p, q).x = (xsize / 2) + ((n(p, q).x - centx) * tz(n(p, q).z * 8))
        n(p, q).y = (ysize / 2) + ((n(p, q).y - CentY) * tz(n(p, q).z * 8))
        cp = ((360 * p * INT(ptwist) / NODES) + (360 * q * INT(twist) / SUBNODES)) MOD 360
        ar = h(cp)
        ag = h((cp + 120) MOD 360)
        ab = h((cp + 240) MOD 360)
        n(p, q).col.r = ar
        n(p, q).col.g = ag
        n(p, q).col.b = ab
        n(p, q).t = texture
    NEXT q
NEXT p


maxrot = 45
DIM testvec AS vector
testvec.x = 128
testvec.y = 128
testvec.z = 128
testvec.col.r = 128
testvec.col.g = 128
testvec.col.b = 128
testvec.t = 128

DIM target AS zbuffer
zin target, xsize, ysize, zmode

DIM a AS vector, b AS vector, c AS vector, d AS vector
DIM ta AS trivec
SCREEN target.a
_SCREENMOVE _MIDDLE
texture = _SCREENIMAGE
PRINT testvec.x
PRINT testvec.y
PRINT testvec.z
PRINT testvec.col.r
PRINT testvec.col.g
PRINT testvec.col.b
PRINT testvec.t
PRINT
DIM vt AS DOUBLE
FOR u = 0 TO 6
    vt = checkvec(testvec, u)
    PRINT vt
NEXT u
PRINT
PRINT target.a
PRINT target.b
PRINT target.c
DIM stime AS _FLOAT, etime AS _FLOAT
stime = TIMER(.001)
FOR t = 0 TO 512 * 8 / mrot
    zcls target
    IF t MOD refrate = 0 THEN
        IF atexture <> 0 THEN _FREEIMAGE (atexture)
        atexture = _SCREENIMAGE

        _PUTIMAGE , atexture, texture, (tsx - (texsize / 2), tsy - (teysize / 2))-(tsx + (texsize / 2), tsy + (teysize / 2))
    END IF
    _PUTIMAGE , texture, target.a
    FOR p = 0 TO NODES - 2
        FOR q = 0 TO SUBNODES - 2
            ap = (p + 1) MOD NODES
            aq = (q + 1) MOD SUBNODES
            a = n(p, q)
            b = n(ap, q)
            c = n(p, aq)
            d = n(ap, aq)
            ap = (p + 1)
            aq = (q + 1)
            ax = INT(511 * p / NODES / 2) + (t * prot * mrot)
            bx = INT(511 * ap / NODES / 2) + (t * prot * mrot)
            ay = INT(511 * q / SUBNODES) + (t * qrot * mrot)
            by = INT(511 * aq / SUBNODES) + (t * qrot * mrot)
            ax = ax MOD 512
            bx = bx MOD 512
            ay = ay MOD 512
            by = by MOD 512
            IF bx < ax THEN bx = bx + 512
            IF by < ay THEN by = by + 512
            a.col.r = ax \ 4
            b.col.r = bx \ 4
            c.col.r = ax \ 4
            d.col.r = bx \ 4
            a.col.g = ay \ 4
            b.col.g = ay \ 4
            c.col.g = by \ 4
            d.col.g = by \ 4
            a.col.b = 7 + ((ax MOD 4) * 16) + ((ay MOD 4) * 64)
            b.col.b = 7 + ((bx MOD 4) * 16) + ((ay MOD 4) * 64)
            c.col.b = 7 + ((ax MOD 4) * 16) + ((by MOD 4) * 64)
            d.col.b = 7 + ((bx MOD 4) * 16) + ((by MOD 4) * 64)
            a.t = texture
            b.t = texture
            c.t = texture
            d.t = texture

            triangle a, b, c, 0, 1
            triangle d, b, c, 0, 1
        NEXT q
    NEXT p
    _DISPLAY
    ft = t
NEXT t
etime = TIMER(.001)
_DEST 0
fps = ft / (etime - stime)
PRINT fps
PRINT fps * NODES * SUBNODES
_DISPLAY
SLEEP
SYSTEM
FUNCTION h (u)
IF u <= 60 THEN h = 255
IF u >= 300 THEN h = 255
IF u > 60 AND u < 120 THEN h = 255 - (255 * (u - 60) / 60)
IF u > 240 AND u < 300 THEN h = (255 * (u - 240) / 60)
END FUNCTION
FUNCTION range (v, min, max)
IF v >= min AND v <= max THEN range = -1
END FUNCTION

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #5 on: January 20, 2013, 01:53:12 PM »
C++ COMPILATION FAILED

OlDosLover

  • Hero Member
  • *****
  • Posts: 3860
  • OlDosLover
    • Email
Re: Simple 3D triangle library
« Reply #6 on: January 20, 2013, 02:09:04 PM »
Hi all,
    It worked for me! Did you download the bi and h. file in the above zip at top of post?
    Works well but does run very slow. Never the less its a very good program!
OlDosLover.

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #7 on: January 20, 2013, 10:32:43 PM »
Quote from: OlDosLover on January 20, 2013, 02:09:04 PM
Hi all,
    It worked for me! Did you download the bi and h. file in the above zip at top of post?
    Works well but does run very slow. Never the less its a very good program!
OlDosLover.

Yep, I did all the computering and it still gave me an error.

SkyCharger001

  • Hero Member
  • *****
  • Posts: 1594
Re: Simple 3D triangle library
« Reply #8 on: January 21, 2013, 09:09:54 AM »
Quote from: fluffrabbit on January 20, 2013, 10:32:43 PM
Quote from: OlDosLover on January 20, 2013, 02:09:04 PM
Hi all,
    It worked for me! Did you download the bi and h. file in the above zip at top of post?
    Works well but does run very slow. Never the less its a very good program!
OlDosLover.

Yep, I did all the computering and it still gave me an error.
If you are using QB64-GL, try running it via QB64-SDL 0.954.

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #9 on: January 21, 2013, 05:01:43 PM »
Quote from: SkyCharger001 on January 21, 2013, 09:09:54 AM
Quote from: fluffrabbit on January 20, 2013, 10:32:43 PM
Quote from: OlDosLover on January 20, 2013, 02:09:04 PM
Hi all,
    It worked for me! Did you download the bi and h. file in the above zip at top of post?
    Works well but does run very slow. Never the less its a very good program!
OlDosLover.

Yep, I did all the computering and it still gave me an error.
If you are using QB64-GL, try running it via QB64-SDL 0.954.

I did use QB64-SDL.

OlDosLover

  • Hero Member
  • *****
  • Posts: 3860
  • OlDosLover
    • Email
Re: Simple 3D triangle library
« Reply #10 on: January 22, 2013, 03:38:30 AM »
Hi all,
    fluffrabbit are you running it on Win or Linux?
OlDosLover.

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #11 on: January 22, 2013, 04:47:38 AM »
Quote from: OlDosLover on January 22, 2013, 03:38:30 AM
Hi all,
    fluffrabbit are you running it on Win or Linux?
OlDosLover.

Windows.

Really, a software rendering library for QB would be great because I don't know if Galleon and everybody else will pull through with all of this OpenGL stuff, plus there's hope that it could be ported to classic QB 4.5. Pure QB would be nice. Importing a C header is an advanced feature that a lot of people don't even want to think about. I am aware that it would be way slower in its original form, but is there perhaps some version of this that could run at an acceptable speed without using any advanced code? Maybe solid colored polygons with flat shading and lighting? When I program 3D, there are 3 main challenges I face:

1) 3D math. Trig is hard.
2) Z-buffering. Do I sort, do I buffer, do I cull? I'm terrible at doing this in a memory-efficient way. I wrote a FreeBASIC voxel library that slows way down when you increase the view distance even when nothing else is rendered. Horrible, isn't it? I've got to learn to stop creating giant arrays every frame, but I'm such a bad programmer that I don't know any other way.
3) Actual polygon rendering. It's laggy enough to make solid shaded polygons, but those don't look very good! Old games like Daggerfall employ flat polygons, raycast walls, limited use of textured triangles, scaled sprites, crappy wraparound sky, and buffer fading. Why so many tricks? Back in the day, it was because computers were slow and Bethesda didn't realy know what they were doing. However, they compiled to asembly while we use the QBASIC model. In the end, we probably have as much CPU time to spare as they did. I'm just used to flashy graphics from all my time using DarkBASIC. RuneScape makes good use of vertex coloring, but it uses polygons sparingly and employs subtle tricks. That's not to say that OpenGL apps don't also use tricks. Hell, 3DzzD looks amazing and it's a Java software rendering library. However, those things took years to develop and I'm just looking for some basic functionality.

Basic functionality includes a 6 degrees of freedom orthographic camera with a controllable FOV. It also includes objects (groups of 3D points) that can be transformed and scaled the same way as the camera. The fastest Z-sorting algorithm possible should be employed. Per-object is fine. Backface culling is a must. Lots of people say they like textures, but I say they're not really necessary. RuneScape and Daggerfall look OK without proper texture mapping. However, 3D lighting is a must. Whether or not that lighting makes use of gourad/phong shading isn't important. What's important is that we can tell tops and bottoms. Even just precalculated directional lighting on flat-shaded polygons would be fine.

My point is, your library is already way outdated, but that's not important. What's important is that the basic functionality of being able to transform and render objects is incredibly easy to use. Now, I can't speak for everyone here, but when I speak for myself, I say that easier is better.

STxAxTIC

  • Newbie
  • *
  • Posts: 42
    • Email
Re: Simple 3D triangle library
« Reply #12 on: January 22, 2013, 09:51:06 PM »
Hey rabbit,

I don't know how to quote text made in a previous post (yours above), but when you said

"I've got to learn to stop creating giant arrays every frame, but I'm such a bad programmer that I don't know any other way."

That problem is solved in my 3D engine that I posted yesterday - the one where you recommended that shaded polygons would be nice. Allow me to explain myself in this forum thread rather than the other: I left my polygons unshaded and unconnected for the express purpose of showing precisely how to do such math! (I will leave shading and lighting for whoever has time for it - I am only intrested in geometry and making 3D stuff for scientific use more than gaming. I consider shading and lighting already solved problems from a 'vector' point of view.)

Back on topic: I have created a unique way of culling invisible panels in 3D. Not solely backface culling (where programmers usually tend to demonstrate just one object in their engines in attempt to fool you into thinking they have the general problem solved)!

I can cull the segment or the whole of any occulted panel. Look more closely at screenshot #3 on http://people.umass.edu/wfbarnes/indexcodelib.html to see it in action. I'm probably going to write up the process nicely into some coherent notes, but in the meantime I can tell you how it was done if the code is less than transparent. My real email address is wfbarnes@physics.umass.edu if interested.

Granted, I have little experience in dealing with the logistics of programming in terms of libraries and all the different compilers - my skill is in the math and physics end - and writing tight loops. I have probably unnecessarily reinvented the wheel in writing that.



« Last Edit: January 22, 2013, 10:00:12 PM by STxAxTIC »

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: Simple 3D triangle library
« Reply #13 on: January 22, 2013, 10:03:22 PM »
Stxaxtic, I see from your email address that you may be a professor of physics at Umass?  Is this correct, and if so, do you have any websites that I and other aspiring physics newbies could visit to learn more?  If not, do you have any sites you would recommend?

fluffrabbit

  • Sr. Member
  • ****
  • Posts: 395
Re: Simple 3D triangle library
« Reply #14 on: January 22, 2013, 10:09:54 PM »
@STxAxTIC-

I notice that you edited your post. Just moments ago, you said that you were open to suggestions beyond the whole "programming" thing. My only suggestion is to add filled triangles. That's it! You could have two rendering modes- wireframe and filled. One could switch between them with the push of a button. You're right, lighting and shading are already taken care of from a vector maths point of view. It would take only a little bit of code to patch it together, but I am not the person to write that code. Maybe someone here could look into that. (I'm looking at you, SkyCharger.)

  • Print