Camera and Polyvector

Previous topic - Next topic

Slydog

Quote from: erico on 2014-May-23
But why can´t you do just that in GLB with 3d? That is what I´m not getting.
Create 3d rectangular flat objects and map your sprite to it, wouldn´t it solve the issues with z?

That's how it's done in Unity, even with their new 2D mode.  Everything is a 3D object in a 3D world, and sprites are simple quads.
Layering / ordering is handled by the z value of the quad's vertices.  (The new method may (also?) use layers for this instead, not sure).

GLBasic's attraction isn't it's complete list of features.  I'd say it's the language itself.  Small learning curve.  You can get something mocked up and running quickly.  Plus it supports a lot of platforms, not just the top popular ones.  It allows you to program in a low level, even directly working in OpenGL if you desire.  You can create your own libraries to do basically whatever you want.  I just wish physics was built-in.  But you are free to add your own, or an existing library if you can make it GLBasic compatible.  Oh, and the dedicated community!  We are the best.  And most humble.  =D
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

kanonet

I dont buy an engine because of its potential future development, I buy it because it does (in its current state) what I want it to do - and I believe that it will at least not become worse in the future. But this aside.

I dont think that 2D Polyvector is wrong for this kind of game, but as a developer its your choice, if you prefer to do it in 3D, you can. So why dont you simply create a quad with X_OBJSTART etc. and render and texture this? GLBasic has all the things that you need for this - and if you are not totally happy with this, then you can still easily expand this with C++ and native OpenGL.

Bugs are something totally different and hopefully those know ones will get fixed in a not-so-far-future.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Kyo

#62
I'm trying to use X_OBJSTART, but I wish they would change the Quad normal size, depending on the size of the image.

but I can not.

It's possible or am I doing wrong????

Code (glbasic) Select

FUNCTION CreateQuad: id,num,scale,col=0xFFFFFF

GETSPRITESIZE num,w,h

    X_OBJSTART id
X_OBJADDVERTEX   0*scale,    0*scale, 0,  0,1, col
X_OBJADDVERTEX   0*scale,    h*scale, 0,  0,0, col
X_OBJADDVERTEX   w*scale,    0*scale, 0,  1,1, col
X_OBJADDVERTEX   w*scale,    h*scale, 0,  1,0, col
X_OBJEND

ENDFUNCTION // sz



The texture not maintains the size of the Quad.....

kanonet

You can use X_AUTONORMALS to define how it creates normals for the quad, or you use X_OBJADDVERTEX_NORMAL to set it manually. If you set it manually, keep in mind, that  (nx^2 + ny^2 + nz ^2) = 1 if you break this you can get wired results, since GLBasic does not automatically correct it (at least I think so).

BTW you could also just model the quad in external software and import it into GLBasic - but for a quad that does not really make sense. :P
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Slydog

Maybe if you arbitrarily set a world unit to be so many pixels.
For example, say you want 64 pixels to be a world unit, so a 64x128 pixel sprite would appear 1x2 world units big.

Change your code to something like:

Code (glbasic) Select
FUNCTION CreateQuad: id, num, scale, col=0xFFFFFF
    LOCAL pixelsInWorldUnit# = 64;
    GETSPRITESIZE num, w, h
    w = w / pixelsInWorldUnit;
    h = h / pixelsInWorldUnit;
    X_OBJSTART id
                X_OBJADDVERTEX   0,    0, 0,  0,1, col
                X_OBJADDVERTEX   0,    h, 0,  0,0, col
                X_OBJADDVERTEX   w,    0, 0,  1,1, col
                X_OBJADDVERTEX   w,    h, 0,  1,0, col
        X_OBJEND
ENDFUNCTION


This should make the quad proportionally sized to your source sprite size.
(If I understood your question!)
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kyo

A practical example, because the documentation only says:

Code (glbasic) Select

X_OBJADDVERTEX_NORMAL nx#, ny#, nz#
Sets the normal vectors for comming calls to X_OBJADDVERTEX if you previously set X_AUTONORMALS 0.


Quote from: kanonet on 2014-May-23
BTW you could also just model the quad in external software and import it into GLBasic - but for a quad that does not really make sense. :P

Nope, i want to change te size of the quad at runtime:

Slydog

#66
Are you asking about vertice 'NORMALS'?
ie. a NORMAL is a vector pointing away from a single vertice, used generally to indicate which direction the vertice is considered to be 'facing', used for lighting, etc.
So for a quad, the normals should be facing away from the quad, towards the camera.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kyo

I'have this image (w:198 h:291):




If I use this code:

Code (glbasic) Select

X_OBJSTART num
X_OBJADDVERTEX   -20*sz, -20*sz, 0,  0,1, col
X_OBJADDVERTEX   -20*sz,  20*sz, 0,  0,0, col
X_OBJADDVERTEX    20*sz, -20*sz, 0,  1,1, col
X_OBJADDVERTEX    20*sz,  20*sz, 0,  1,0, col
X_OBJEND


I get:


The image is square, so it is deformed
if I Use this code:

Code (glbasic) Select

FUNCTION CreateQuad: id, num, scale, col=0xFFFFFF
    LOCAL pixelsInWorldUnit# = 64;
    GETSPRITESIZE num, w, h
    w = w / pixelsInWorldUnit;
    h = h / pixelsInWorldUnit;
    X_OBJSTART id
                X_OBJADDVERTEX   0,    0, 0,  0,1, col
                X_OBJADDVERTEX   0,    h, 0,  0,0, col
                X_OBJADDVERTEX   w,    0, 0,  1,1, col
                X_OBJADDVERTEX   w,    h, 0,  1,0, col
        X_OBJEND
ENDFUNCTION


I have this result:


The rectangle is correct, but the texture does not fill the rectangle.

Slydog

#68
I wonder if it's an integer / float conversion round?
You could add a print to see what numbers you're getting:
Code (glbasic) Select
PRINT "w: "+ w + ", h:" + h, 0,0
They should have decimals at the end (unless your sprite *is* evenly divided into 64).

But either way this is strange, your UV mapping is from 0 to 1 (3rd and 2nd last values in the X_OBJADDVERTEX command).
So no matter what size your sprite texture is, it should stretch to fill the entire quad.  And no red areas.

[Edit] You could place that line before, then after the 'w = w / pixelsInWorldUnits' to see the before value to verify the actual sprite size in pixels is returned.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Slydog

Ha, I've been working with C# too much!

Try taking out the semi-colons ( ; ) at the end of the 3 lines I added! Oops! :-[
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

kanonet

#70
Like Slydog said normals are for lighting, since you program a fake 2D you wont use the 3D lighting at all - so you probably can ignore normals. X_AUTONORMALS 0 should be enough for your use case, if its not, try 2.

I would suggest that you just create a quad with the size of 1x1 and then when you want to render it, set the actual size that you need with X_SCALING. 3D Objects are like sprites, you load or create them one time (at program start) and then you can render and manipulate them hundreds of times. Do not create the quad at runtime, this is slow!

Try something like this:
Code (glbasic) Select
// at program start create the 1x1 quad:
GLOBAL quadID%
X_AUTONORMALS 0
X_OBJSTART quadID
    X_OBJADDVERTEX 0, 0, 0,  0,1,  RGB(255,255,255)
    X_OBJADDVERTEX 0, 1, 0,  0,0,  RGB(255,255,255)
    X_OBJADDVERTEX 1, 0, 0,  1,1,  RGB(255,255,255)
    X_OBJADDVERTEX 1, 1, 0,  1,0,  RGB(255,255,255)
X_OBJEND


// at render time you can draw it with this function:
FUNCTION DrawQuad%: spriteID%, x#,y#,z#
    LOCAL pixelsInWorldUnit# = 64, w#, h#;
    GETSPRITESIZE spriteID, w, h
    w = w / pixelsInWorldUnit;
    h = h / pixelsInWorldUnit;
   
X_SCALING w,h,1
X_SETTEXTURE spriteID, -1
X_MOVEMENT x,y,z
X_DRAWOBJ quadID, 1
ENDFUNCTION

Just a quick mockuo, sorry if its not 100% perfect. Personally i would not like that it automatically scales, but if its that what you need here you go. BTW its suggested that your sprites are quads of the power of 2 like 128x128 - but of cause this would break the automatically scaling.
(I borrowed your code Slydog  8) )

EDIT: so many new posts since I began to write this, you guys post to fast. :D
EDIT2: I just realized that it was me, that did introduce the talk about normals, I did just read your post about 'quad normal size' wrong. Sorry, but this post here should still help you.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Kyo

Don't work correctly ...
Download the test file and use 1 or 2 for zoom in e out..

if you look you see on top of the image and at the right of the image two red line, that are the correct size of the quad, but the texture does not fill it.

Kyo

Only with power^2 work the Quad Texture????

kanonet

Yes seems like this problem is cause by your image being no square of the power of 2. I tried to create a little demo how to work around this:
Code (glbasic) Select
GLOBAL SpriteQuadG AS TQuadMesh
TYPE TQuadMesh
id% = -1
p2wX# = 64.0
p2wY# = 64.0

FUNCTION Init%: PixelsInWorldUnitX#, PixelsInWorldUnitY#
X_AUTONORMALS 0
self.id = GENX_OBJ()
X_OBJSTART self.id
X_OBJADDVERTEX 0, -1, 0,  0,1,  RGB(255,255,255)
X_OBJADDVERTEX 0, 0, 0,  0,0,  RGB(255,255,255)
X_OBJADDVERTEX 1, -1, 0,  1,1,  RGB(255,255,255)
X_OBJADDVERTEX 1, 0, 0,  1,0,  RGB(255,255,255)
X_OBJEND
self.p2wX = PixelsInWorldUnitX#
self.p2wY = PixelsInWorldUnitY#
ENDFUNCTION
ENDTYPE

TYPE TQuadSprite
id% = -1
w#; h#
QuadInPixel%
pivotX#
pivotY#

FUNCTION Load%: path$
LOCAL sprite% = GENSPRITE()
LOADSPRITE path$, sprite
GETSPRITESIZE sprite, self.w, self.h

LOCAL u%, v%, t# = LOGN(self.w)/LOGN(2)
u = t
IF t<>u THEN INC u
t = LOGN(self.h)/LOGN(2)
v = t
IF t<>v THEN INC v
IF u<v THEN u=v
u=POW(2,u)
self.QuadInPixel = u
IF u=self.w AND u=self.h
self.id = sprite
ELSE
LOCAL screen% = GENSCREEN()
self.id = GENSPRITE()
CREATESCREEN screen, self.id, u,u
USESCREEN screen
STRETCHSPRITE sprite, 0,0, u,u
USESCREEN -1
CREATESCREEN screen, -1, 0,0
LOADSPRITE "", sprite
ENDIF

self.w = self.w / SpriteQuadG.p2wX
self.h = self.h / SpriteQuadG.p2wY
ENDFUNCTION

FUNCTION Pivot%: PivX%, PivY% // Input in Pixel on original sized image; (0,0) is top left
self.pivotX = -PivX / SpriteQuadG.p2wX
self.pivotY = PivY / SpriteQuadG.p2wY
ENDFUNCTION

FUNCTION Draw%: x#, y#, z#=0
X_SETTEXTURE self.id, -1
X_SCALING self.w, self.h, 1
X_MOVEMENT x+self.pivotX, y+self.pivotY, z
X_DRAWOBJ SpriteQuadG.id, 1
ENDFUNCTION

FUNCTION RotoDraw%: x#, y#, z#=0, phi#=0.0
X_SETTEXTURE self.id, -1
X_SCALING self.w, self.h, 1
X_MOVEMENT x, y, z
X_ROTATION phi,0,0,1
X_PUSHMATRIX
X_MOVEMENT self.pivotX/self.w, self.pivotY/self.h, 0
X_DRAWOBJ SpriteQuadG.id, 1
X_POPMATRIX
ENDFUNCTION

FUNCTION ZoomDraw%: x#, y#, z#=0, relx#=1.0, rely#=1.0
X_SETTEXTURE self.id, -1
X_SCALING self.w*relx, self.h*rely, 1
X_MOVEMENT x+self.pivotX*relx, y+self.pivotY*rely, z
X_DRAWOBJ SpriteQuadG.id, 1
ENDFUNCTION

FUNCTION RotoZoomDraw%: x#, y#, z#=0, phi#=0.0, relx#=1.0, rely#=1.0
X_SETTEXTURE self.id, -1
X_SCALING self.w*relx, self.h*rely, 1
X_MOVEMENT x, y, z
X_ROTATION phi,0,0,1
X_PUSHMATRIX
X_MOVEMENT self.pivotX/self.w, self.pivotY/self.h, 0
X_DRAWOBJ SpriteQuadG.id, 1
X_POPMATRIX
ENDFUNCTION

ENDTYPE

How to use it:
Code (glbasic) Select
// 1st Initilize the system and tell it how many pixels you have in one world unit (x and y)
SpriteQuadG.Init(64,64)

// now you can create as many sprites as you want (of cause you could also use arrays of this type):
GLOBAL fighter1 AS TQuadSprite
GLOBAL fighter2 AS TQuadSprite

// now its time to load the images:
fighter1.Load("1/1.png")
fighter2.Load("2/1.png")

// feel free to change the sprites pivot:
fighter1.Pivot(50,0)

// like in 2D you can use/draw every sprite as often as you want:
fighter1.Draw(5,0)
fighter1.Draw(7,0)
fighter1.ZoomDraw(7,2,0, 0.5,0.5)
fighter2.RotoDraw(-2,0,0, 45)
fighter2.RotoZoomDraw(-5,2,0, 78, 2.0)


This internally stretches your sprite to the next square of the power of two - please be aware, that this can cause visible artefacts, try of SMOOTHSHADING on or off is better for your needs. This was the best that I could get out fast with pure GLBasic, if we would use INLINE and native OpenGL results would be better and faster. But still maybe that helps you, even though its not commented.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Kyo

Requiered Power of 2 Texture??? (128x128 etc) ?