# PureBasic Forum

 It is currently Sun May 19, 2013 7:03 pm

 All times are UTC + 1 hour

 Page 1 of 1 [ 12 posts ]
 Print view Previous topic | Next topic
Author Message
 Post subject: General 3D RotationPosted: Fri Jan 28, 2011 10:43 am

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
Okay, this isn't a question about code, but of math!

This is my problem. I am at (0,0,0), and I'm looking down the Z axis. When I pitch up or down, I rotate the X axis, and I look up and down. If I then roll, I rotate the Z axis and then I roll accordingly.

My issue is this: if I pitch up or down first, and then try to roll, I can no longer roll on the Z axis as the rotation doesn't work. Another axis needs to be involved, but by how much, and which axis... I do not know.

So, just using pitch and roll, how do I sort out the local rotations?

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 11:15 am
 Enthusiast

Joined: Wed Sep 24, 2008 12:21 am
Posts: 255
Im not absolutly sure what youre problem exactly is. Maybe its just a matter of my bad english skills
However it seems that you try to do different yaw-pitch-roll's in a row and now youre stuck, because the rotation is everytime along the local rotations.
I think its much easier if you dont rpw from the last local point. Instead try to sum up the different angles and use an absolute ypr at every frame.
It may help you too, that the matrice multiplication is not commutative, so it does matter in which order you rotate.
For a rotation along the local axis, you should go by this: rot1 * rot2 * rot3
For a rotation along the fixed axis, you should go by this: rot3 * rot2 * rot1

It would help (me ) much, if you could explain in more detail what youre doing.

_________________
pb 5.11

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 11:34 am

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
Ok, heres some example code, note that you will have to set the subsystem to opengl:

Code:
Global WallTexture

Structure POINTZ
x.f
y.f
z.f
EndStructure

Global NewList StarField.POINTZ()

For i = 1 To 2500
StarField()\x = Random(200) - 100
StarField()\y = Random(200) - 100
StarField()\z = Random(200) - 100
Next

Global Speed.f = 1

Global Pitch.f = 0
Global Roll.f = 0

Global Position.POINTZ
Position\x = 0
Position\y = 0
Position\z = 0

;{--- OpenGL Setup
CompilerIf Subsystem("OpenGL")
CompilerElse
MessageRequester("ERROR", "Set the subsystem To OpenGL")
End
CompilerEndIf

; pb workaround fix
Import ""
PB_Screen_Target
EndImport
#GL_TEXTURE_RECTANGLE_ARB        =  \$84F5
;----------------------------
#GL_BLEND = \$0BE2
#GL_COLOR_BUFFER_BIT = \$00004000
#GL_DEPTH_BUFFER_BIT = \$00000100
#GL_DEPTH_TEST = \$0B71
#GL_LEQUAL = \$0203
#GL_LINEAR = \$2601
#GL_LINEAR_MIPMAP_NEAREST = \$2701
#GL_LUMINANCE = \$1909

#GL_UNSIGNED_INT = \$1405
#GL_UNSIGNED_INT_8_8_8_8   = \$8035
#GL_BGRA = \$80E1
#GL_RGBA = \$1908
#GL_RGBA8 = \$8058

#GL_MODELVIEW = \$1700
#GL_MODULATE = \$2100
#GL_NICEST = \$1102
#GL_PERSPECTIVE_CORRECTION_HINT = \$0C50
#GL_PROJECTION = \$1701
#GL_SMOOTH = \$1D01
#GL_TEXTURE_2D = \$0DE1
#GL_TEXTURE_ENV = \$2300
#GL_TEXTURE_ENV_MODE = \$2200
#GL_TEXTURE_MAG_FILTER = \$2800
#GL_TEXTURE_MIN_FILTER = \$2801
#GL_TEXTURE_WRAP_S = \$2802
#GL_TEXTURE_WRAP_T = \$2803
#GL_TRUE = 1
#GL_UNSIGNED_BYTE = \$1401

#GL_SRC_ALPHA = \$0302
#GL_ONE = 1
#GL_UNPACK_ALIGNMENT = \$0CF5

;  BeginMode
#GL_POINTS                         = \$0000
#GL_LINES                          = \$0001
#GL_LINE_LOOP                      = \$0002
#GL_LINE_STRIP                     = \$0003
#GL_TRIANGLES                      = \$0004
#GL_TRIANGLE_STRIP                 = \$0005
#GL_TRIANGLE_FAN                   = \$0006
#GL_POLYGON                        = \$0009

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC "/usr/lib/libX11.a"+Chr('"')+" -l"+Chr('"')+"GL"
CompilerElse
Import "Opengl32.lib"
CompilerEndIf
;{-
glBegin(a.l)
glBindTexture(a.l,b.l)
glClear(a.l)
glClearColor(a.f,b.f,c.f,d.f)
glClearDepth(a.d)
glDepthFunc(a.l)
glDisable(a.l)
glEnable(a.l)
glEnd()
glGenTextures(a.l,b.l)
glGetError()
glHint(a.l,b.l)
glMatrixMode(a.l)
glTexCoord2f(a.f,b.f)
glTexEnvf(a.l,b.l,c.f)
glTexParameterf(a.l,b.l,c.f)
glTexParameteri(a.l,b.l,c.i)
glTranslatef(a.f,b.f,c.f)
glVertex3f(a.f,b.f,c.f)
glVertex2f(a.f,b.f)
glViewport(a.l,b.l,c.l,d.l)

glBlendFunc(a.l,b.l) ; As "glBlendFunc@8"
glPixelStorei(a.l,b.l) ; As "glPixelStorei@8"
glColor3f(r.f, g.f, b.f)
glColor4f(r.f, g.f, b.f, a.f)
glRotatef(degrees.f, x.f, y.f, z.f)

glPushMatrix()
glPopMatrix()

glMultMatrixf(*matrix)
;}
EndImport

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC "/usr/lib/libGLU.a"
CompilerElse
Import "Glu32.lib"
CompilerEndIf
;{-
gluBuild2DMipmaps(a.l,b.l,c.l,d.l,e.l,f.l,g.l)
gluErrorString(a.l)
gluPerspective(a.d,b.d,c.d,d.d)
gluLookAt(CameraX.f, CameraY.f, CameraZ.f, LookAtX.f, LookAtY.f, LookAtZ.f, UpX.f, UpY.f, UpZ.f)
;}
EndImport
;}

Procedure Noise(x, y)
Static salt = 0
salt = salt ! x & y
ProcedureReturn salt
EndProcedure

Procedure.i GenerateTexture(pWidth.i, pHeight.i)
Protected img = CreateImage(#PB_Any, pWidth, pHeight, 32)

StartDrawing(ImageOutput(img))
Protected *mem = DrawingBuffer()

For y = 0 To pHeight-1
For x = 0 To pWidth-1
n = Noise(x, y) * 4
If n < 0   : n = 0   : EndIf
If n > 255 : n = 255 : EndIf
Plot(x, y, RGBA(n, n, n, n))
Next
Next

DrawingMode(#PB_2DDrawing_Transparent  )
DrawText(10,10,"Hello", RGBA(255,255,255,255))

StopDrawing()

Protected TexID = 0
glGenTextures(1, @TexID)
glBindTexture(#GL_TEXTURE_2D, TexID)

glTexEnvf(#GL_TEXTURE_ENV, #GL_TEXTURE_ENV_MODE, #GL_MODULATE )

; when texture area is small, bilinear filter the closest mipmap
glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR_MIPMAP_NEAREST );
; when texture area is large, bilinear filter the original
glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR );

rv = gluBuild2DMipmaps(#GL_TEXTURE_2D, 4, pWidth, pHeight, #GL_RGBA, #GL_UNSIGNED_BYTE, *mem ) ;

If rv <> 0
Debug Str(rv) + " :: " + PeekS(gluErrorString(rv))
ProcedureReturn 0
EndIf

ProcedureReturn TexID
EndProcedure

Procedure InitGL()
glClearColor(0.0, 0.0, 0.0, 0.0)

glEnable(#GL_TEXTURE_2D)
glEnable(#GL_BLEND)

glBlendFunc(#GL_SRC_ALPHA, #GL_ONE);
glPixelStorei(#GL_UNPACK_ALIGNMENT, 1);

glClearDepth(1.0)
glEnable(#GL_DEPTH_TEST)
glDepthFunc(#GL_LEQUAL)
glHint(#GL_PERSPECTIVE_CORRECTION_HINT, #GL_NICEST)
EndProcedure

Procedure ResizeScene(width, height)
If height < 1 : height = 1 : EndIf
If width < 1 : width = 1 : EndIf

glViewport(0, 0, width, height)
glMatrixMode(#GL_PROJECTION)

gluPerspective(45, width / height, 0,  100)

glMatrixMode(#GL_MODELVIEW)
EndProcedure

Procedure DrawScene()
glClear(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

glRotatef(Pitch, 1, 0, 0)
glRotatef(Roll, 0, 0, 1)

glEnable(#GL_TEXTURE_2D)
glBindTexture(#GL_TEXTURE_2D, WallTexture)

glPushMatrix()

glTranslatef(0, 0, -5)

glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0,  1.0);   // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0);
glVertex3f( 1.0, 0.0,  1.0);   // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0);
glVertex3f( 1.0,  1.0,  1.0);   // Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0,  1.0,  1.0);   // Top Left Of The Texture and Quad

glEnd( );
glPopMatrix()

glDisable(#GL_TEXTURE_2D);

glPushMatrix()
glBegin(#GL_POINTS)
ForEach StarField()
c.f = 1
glColor4f(c,c,c,c)
glVertex3f( StarField()\x, StarField()\y, StarField()\z )
Next
glEnd()
glPopMatrix()

With Position
glTranslatef(\x, \y, \z)
EndWith

EndProcedure

InitSprite() : InitKeyboard()
OpenWindow (0, 100, 100, 512, 512, "OpenGL Window")
OpenWindowedScreen(WindowID(0), 0, 0, 512, 512, 0, 0, 0, #PB_Screen_WaitSynchronization)

glDisable(#GL_TEXTURE_RECTANGLE_ARB)
PB_Screen_Target = #GL_TEXTURE_2D

#width = 64
#height = 64

WallTexture = GenerateTexture(#width, #height)

InitGL()

Repeat
TimerStart = ElapsedMilliseconds()

Select WindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect

ExamineKeyboard()
If KeyboardReleased(#PB_Key_Escape)
Break
EndIf

If KeyboardPushed(#PB_Key_Up)
Pitch + 1
EndIf
If KeyboardPushed(#PB_Key_Down)
Pitch - 1
EndIf

If KeyboardPushed(#PB_Key_Left)
Roll - 1
EndIf
If KeyboardPushed(#PB_Key_Right)
Roll + 1
EndIf

If Pitch < 0
Pitch = 359.9
EndIf
If Pitch > 359.9
Pitch = 0
EndIf

If Roll < 0
Roll = 359.9
EndIf
If Roll > 359.9
Roll = 0
EndIf

DrawScene()

FlipBuffers()
ResizeScene(WindowWidth(0), WindowHeight(0))

Repeat
glError = glGetError()
Select glError
Case 0
Break
Default
Debug glError ; + " :: " + PeekS(gluErrorString(glError))
EndSelect
ForEver

Pausing = Int((1000.0 / 60.0) - (ElapsedMilliseconds() - TimerStart))
If Pausing < 1 : Pausing = 1 : EndIf
Delay( Pausing )

ForEver

Ok, now if you pitch up and down and return to the centre, and then roll and return to the centre, that is how I want it to look, regardless of which way I am pointing.

However, if I pitch down and then roll, you will see that I am still rotating about on the global axis.

How do I solve that?

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 12:06 pm

Joined: Mon Jun 02, 2003 9:16 am
Posts: 1917
Location: Germany
The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)

_________________
bye,
Daniel

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 12:18 pm
 Enthusiast

Joined: Wed Sep 24, 2008 12:21 am
Posts: 255
DarkDragon wrote:
The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)

Hm runs fine with WinXP PB4.51, did you enable "opengl" subsystem?

I think I found your problem:
glRotatef(angle,x,y,z) seems to rotate around the given vector. Youre given vector is one time the x, one time the z axis. So you rotate allways around the global axis.
If you want to rotate around the local axis, you have to look for a command for local axis rotation (I dont know the gl commands, sry) or compute the rotational vector on your own. (just a guess, but I think the coloumns of your rotation matrix should contain the local x/y/z axis)

_________________
pb 5.11

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 12:56 pm

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
yeah, it's the local rotate that's screwing me over - from what I can see, I have to implement it myself, but I'm lacking the necessary maths to calculate it - hence the question.

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 1:06 pm
 Enthusiast

Joined: Wed Sep 24, 2008 12:21 am
Posts: 255
if there is no local rotation or something like that, I would instantly switch the 3d engine... That are absolutly basic commands.

_________________
pb 5.11

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 2:11 pm

Joined: Mon Jun 02, 2003 9:16 am
Posts: 1917
Location: Germany
gnasen wrote:
DarkDragon wrote:
The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)

Hm runs fine with WinXP PB4.51, did you enable "opengl" subsystem?

Yes I did. I even updated PureBasic to PB 4.51 and it still crashes.
With x86 it works well.

Btw.: OpenGL is not a 3d engine but a renderer. Its on the same level as direct3d.

_________________
bye,
Daniel

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 2:15 pm

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
That sounds like a 32 bit/64 bit pointer conflict. Hmmm. I'll look at that when I get home.

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 2:22 pm

Joined: Mon Jun 02, 2003 9:16 am
Posts: 1917
Location: Germany
But the compiler shouldn't crash.

Nevertheless you may want to have a look at "Rotation about an arbitrary axis" - a topic discussed in many books and on many websites. Or you should use gluLookAt instead. The mathematics are essential and you won't get around it.

_________________
bye,
Daniel

Top

 Post subject: Re: General 3D RotationPosted: Fri Jan 28, 2011 3:53 pm

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
Well, I've fixed it. It's taken 3 days of head smashing and now something clicked. I wasn't keeping a track of my current rotation. And how should one keep a track of 3D rotations? Enter Quaternion's.

Simply put, whenever I need to rotate, I have to apply it to the my previous rotation, and Quaternion's do this very well. That and most of the Quaternion code was previously written on the forums by someone else.

I am sure that there are other (probably better) ways of doing this, and if you can, please tell all!

Code:
Global WallTexture

Structure Matrix4
W1.f
X1.f
Y1.f
Z1.f
W2.f
X2.f
Y2.f
Z2.f
W3.f
X3.f
Y3.f
Z3.f
W4.f
X4.f
Y4.f
Z4.f
EndStructure

Structure QUATERNION
X.f
Y.f
Z.f
w.f
EndStructure

Procedure Quaternion_ToMatrix(*ReturnMatrix.Matrix4, *q.QUATERNION)
*ReturnMatrix\W1 = 1.0 - 2.0 * ( *q\Y * *q\Y + *q\Z * *q\Z );
*ReturnMatrix\X1 = 2.0 * (*q\X * *q\Y + *q\Z * *q\w);
*ReturnMatrix\Y1 = 2.0 * (*q\X * *q\Z - *q\Y * *q\w);
*ReturnMatrix\Z1 = 0.0;

; Second row
*ReturnMatrix\W2 = 2.0 * ( *q\X * *q\Y - *q\Z * *q\w );
*ReturnMatrix\X2 = 1.0 - 2.0 * ( *q\X * *q\X + *q\Z * *q\Z );
*ReturnMatrix\Y2 = 2.0 * (*q\Z * *q\Y + *q\X * *q\w );
*ReturnMatrix\Z2 = 0.0;

; Third row
*ReturnMatrix\W3 = 2.0 * ( *q\X * *q\Z + *q\Y * *q\w );
*ReturnMatrix\X3 = 2.0 * ( *q\Y * *q\Z - *q\X * *q\w );
*ReturnMatrix\Y3 = 1.0 - 2.0 * ( *q\X * *q\X + *q\Y * *q\Y );
*ReturnMatrix\Z3 = 0.0;

; Fourth row
*ReturnMatrix\W4 = 0;
*ReturnMatrix\X4 = 0;
*ReturnMatrix\Y4 = 0;
*ReturnMatrix\Z4 = 1.0;
EndProcedure

Procedure.f Quaternion_Length(*TempQuat.QUATERNION)
ProcedureReturn Sqr(Pow(*TempQuat\X,2) + Pow(*TempQuat\Y,2) + Pow(*TempQuat\Z,2) + Pow(*TempQuat\w,2))
EndProcedure

Procedure Quaternion_Multiply(*NewQuat.QUATERNION, *Quat1.QUATERNION, *Quat2.QUATERNION)
*NewQuat\w = *Quat1\w * *Quat2\w - *Quat1\X * *Quat2\X - *Quat1\Y * *Quat2\Y - *Quat1\Z * *Quat2\Z
*NewQuat\X = *Quat1\w * *Quat2\X + *Quat1\X * *Quat2\w + *Quat1\Y * *Quat2\Z - *Quat1\Z * *Quat2\Y
*NewQuat\Y = *Quat1\w * *Quat2\Y + *Quat1\Y * *Quat2\w + *Quat1\Z * *Quat2\X - *Quat1\X * *Quat2\Z
*NewQuat\Z = *Quat1\w * *Quat2\Z + *Quat1\Z * *Quat2\w + *Quat1\X * *Quat2\Y - *Quat1\Y * *Quat2\X
EndProcedure

Procedure Quaternion_Normalize(*TempQuat.QUATERNION)
TEMP_length.f = Quaternion_Length(*TempQuat)
*TempQuat\X = *TempQuat\X / TEMP_length
*TempQuat\Y = *TempQuat\Y / TEMP_length
*TempQuat\Z = *TempQuat\Z / TEMP_length
*TempQuat\w = *TempQuat\w / TEMP_length
EndProcedure

Procedure Quaternion_FromAngleAxis(*TempQuat.QUATERNION, X.f, Y.f, Z.f, angleDegrees.f)
If X = 0 And Y = 0 And Z = 0
*TempQuat\X = 0
*TempQuat\Y = 0
*TempQuat\Z = 0
*TempQuat\w = 1
ProcedureReturn 0
EndIf

TEMP_angle.f = angleDegrees * 0.01745329
TEMP_angle = TEMP_angle / 2
TEMP_scale.f = Sin(TEMP_angle)

*TempQuat\X = X * TEMP_scale
*TempQuat\Y = Y * TEMP_scale
*TempQuat\Z = Z * TEMP_scale
*TempQuat\w = Cos(TEMP_angle)

Quaternion_Normalize(*TempQuat)
EndProcedure

Structure POINTZ
x.f
y.f
z.f
EndStructure

Global NewList StarField.POINTZ()

For i = 1 To 2500
StarField()\x = Random(200) - 100
StarField()\y = Random(200) - 100
StarField()\z = Random(200) - 100
Next

Global Speed.f = 1

Global Pitch.f = 0
Global Roll.f = 0

Global Position.POINTZ
Position\x = 0
Position\y = 0
Position\z = 0

Global qRotation.QUATERNION
qRotation\w = 1
qRotation\X = 0
qRotation\Y = 0
qRotation\Z = 0

;{--- OpenGL Setup
CompilerIf Subsystem("OpenGL")
CompilerElse
MessageRequester("ERROR", "Set the subsystem To OpenGL")
End
CompilerEndIf

; pb workaround fix
Import ""
PB_Screen_Target
EndImport
#GL_TEXTURE_RECTANGLE_ARB        =  \$84F5
;----------------------------
#GL_BLEND = \$0BE2
#GL_COLOR_BUFFER_BIT = \$00004000
#GL_DEPTH_BUFFER_BIT = \$00000100
#GL_DEPTH_TEST = \$0B71
#GL_LEQUAL = \$0203
#GL_LINEAR = \$2601
#GL_LINEAR_MIPMAP_NEAREST = \$2701
#GL_LUMINANCE = \$1909

#GL_UNSIGNED_INT = \$1405
#GL_UNSIGNED_INT_8_8_8_8   = \$8035
#GL_BGRA = \$80E1
#GL_RGBA = \$1908
#GL_RGBA8 = \$8058

#GL_MODELVIEW = \$1700
#GL_MODULATE = \$2100
#GL_NICEST = \$1102
#GL_PERSPECTIVE_CORRECTION_HINT = \$0C50
#GL_PROJECTION = \$1701
#GL_SMOOTH = \$1D01
#GL_TEXTURE_2D = \$0DE1
#GL_TEXTURE_ENV = \$2300
#GL_TEXTURE_ENV_MODE = \$2200
#GL_TEXTURE_MAG_FILTER = \$2800
#GL_TEXTURE_MIN_FILTER = \$2801
#GL_TEXTURE_WRAP_S = \$2802
#GL_TEXTURE_WRAP_T = \$2803
#GL_TRUE = 1
#GL_UNSIGNED_BYTE = \$1401

#GL_SRC_ALPHA = \$0302
#GL_ONE = 1
#GL_UNPACK_ALIGNMENT = \$0CF5

;  BeginMode
#GL_POINTS                         = \$0000
#GL_LINES                          = \$0001
#GL_LINE_LOOP                      = \$0002
#GL_LINE_STRIP                     = \$0003
#GL_TRIANGLES                      = \$0004
#GL_TRIANGLE_STRIP                 = \$0005
#GL_TRIANGLE_FAN                   = \$0006
#GL_POLYGON                        = \$0009

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC "/usr/lib/libX11.a"+Chr('"')+" -l"+Chr('"')+"GL"
CompilerElse
Import "Opengl32.lib"
CompilerEndIf
;{-
glBegin(a.l)
glBindTexture(a.l,b.l)
glClear(a.l)
glClearColor(a.f,b.f,c.f,d.f)
glClearDepth(a.d)
glDepthFunc(a.l)
glDisable(a.l)
glEnable(a.l)
glEnd()
glGenTextures(a.l,b.l)
glGetError()
glHint(a.l,b.l)
glMatrixMode(a.l)
glTexCoord2f(a.f,b.f)
glTexEnvf(a.l,b.l,c.f)
glTexParameterf(a.l,b.l,c.f)
glTexParameteri(a.l,b.l,c.i)
glTranslatef(a.f,b.f,c.f)
glVertex3f(a.f,b.f,c.f)
glVertex2f(a.f,b.f)
glViewport(a.l,b.l,c.l,d.l)

glBlendFunc(a.l,b.l) ; As "glBlendFunc@8"
glPixelStorei(a.l,b.l) ; As "glPixelStorei@8"
glColor3f(r.f, g.f, b.f)
glColor4f(r.f, g.f, b.f, a.f)
glRotatef(degrees.f, x.f, y.f, z.f)

glPushMatrix()
glPopMatrix()

glMultMatrixf(*matrix)
;}
EndImport

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC "/usr/lib/libGLU.a"
CompilerElse
Import "Glu32.lib"
CompilerEndIf
;{-
gluBuild2DMipmaps(a.l,b.l,c.l,d.l,e.l,f.l,g.l)
gluErrorString(a.l)
gluPerspective(a.d,b.d,c.d,d.d)
gluLookAt(CameraX.f, CameraY.f, CameraZ.f, LookAtX.f, LookAtY.f, LookAtZ.f, UpX.f, UpY.f, UpZ.f)
;}
EndImport
;}

Procedure Noise(x, y)
Static salt = 0
salt = salt ! x & y
ProcedureReturn salt
EndProcedure

Procedure.i GenerateTexture(pWidth.i, pHeight.i)
Protected img = CreateImage(#PB_Any, pWidth, pHeight, 32)

StartDrawing(ImageOutput(img))
Protected *mem = DrawingBuffer()

For y = 0 To pHeight-1
For x = 0 To pWidth-1
n = Noise(x, y) * 4
If n < 0   : n = 0   : EndIf
If n > 255 : n = 255 : EndIf
Plot(x, y, RGBA(n, n, n, n))
Next
Next

DrawingMode(#PB_2DDrawing_Transparent  )
DrawText(10,10,"Hello", RGBA(255,255,255,255))

StopDrawing()

Protected TexID = 0
glGenTextures(1, @TexID)
glBindTexture(#GL_TEXTURE_2D, TexID)

glTexEnvf(#GL_TEXTURE_ENV, #GL_TEXTURE_ENV_MODE, #GL_MODULATE )

; when texture area is small, bilinear filter the closest mipmap
glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MIN_FILTER, #GL_LINEAR_MIPMAP_NEAREST );
; when texture area is large, bilinear filter the original
glTexParameterf(#GL_TEXTURE_2D, #GL_TEXTURE_MAG_FILTER, #GL_LINEAR );

rv = gluBuild2DMipmaps(#GL_TEXTURE_2D, 4, pWidth, pHeight, #GL_RGBA, #GL_UNSIGNED_BYTE, *mem ) ;

If rv <> 0
Debug Str(rv) + " :: " + PeekS(gluErrorString(rv))
ProcedureReturn 0
EndIf

ProcedureReturn TexID
EndProcedure

Procedure InitGL()
glClearColor(0.0, 0.0, 0.0, 0.0)

glEnable(#GL_TEXTURE_2D)
glEnable(#GL_BLEND)

glBlendFunc(#GL_SRC_ALPHA, #GL_ONE);
glPixelStorei(#GL_UNPACK_ALIGNMENT, 1);

glClearDepth(1.0)
glEnable(#GL_DEPTH_TEST)
glDepthFunc(#GL_LEQUAL)
glHint(#GL_PERSPECTIVE_CORRECTION_HINT, #GL_NICEST)
EndProcedure

Procedure ResizeScene(width, height)
If height < 1 : height = 1 : EndIf
If width < 1 : width = 1 : EndIf

glViewport(0, 0, width, height)
glMatrixMode(#GL_PROJECTION)

gluPerspective(45, width / height, 0,  100)

glMatrixMode(#GL_MODELVIEW)
EndProcedure

Procedure DrawScene()
glClear(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)

If Roll <> 0 Or Pitch <> 0
Protected qResult.QUATERNION
Protected qPitch.QUATERNION
Protected qRoll.QUATERNION
Quaternion_FromAngleAxis(@qRoll, 0,0,1, Roll)
Quaternion_Multiply(@qResult, @qRoll, @qRotation)
CopyStructure(@qResult, @qRotation, QUATERNION)

Quaternion_FromAngleAxis(@qPitch, 1,0,0, Pitch)
Quaternion_Multiply(@qResult, @qPitch, @qRotation)
CopyStructure(@qResult, @qRotation, QUATERNION)

Roll = 0
Pitch = 0
EndIf

Protected m.Matrix4
Quaternion_ToMatrix(@m, @qRotation)
glMultMatrixf(@m)

glEnable(#GL_TEXTURE_2D)
glBindTexture(#GL_TEXTURE_2D, WallTexture)

glPushMatrix()

glTranslatef(0, 0, -5)

glTexCoord2f(0.0, 0.0);
glVertex3f(0.0, 0.0,  1.0);   // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0, 0.0);
glVertex3f( 1.0, 0.0,  1.0);   // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0, 1.0);
glVertex3f( 1.0,  1.0,  1.0);   // Top Right Of The Texture and Quad
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0,  1.0,  1.0);   // Top Left Of The Texture and Quad

glEnd( );
glPopMatrix()

glDisable(#GL_TEXTURE_2D);

glPushMatrix()
glBegin(#GL_POINTS)
ForEach StarField()
c.f = 1
glColor4f(c,c,c,c)
glVertex3f( StarField()\x, StarField()\y, StarField()\z )
Next
glEnd()
glPopMatrix()

EndProcedure

InitSprite() : InitKeyboard()
OpenWindow (0, 100, 100, 512, 512, "OpenGL Window")
OpenWindowedScreen(WindowID(0), 0, 0, 512, 512, 0, 0, 0, #PB_Screen_WaitSynchronization)

glDisable(#GL_TEXTURE_RECTANGLE_ARB)
PB_Screen_Target = #GL_TEXTURE_2D

#width = 64
#height = 64

WallTexture = GenerateTexture(#width, #height)

InitGL()

Repeat
TimerStart = ElapsedMilliseconds()

Select WindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect

ExamineKeyboard()
If KeyboardReleased(#PB_Key_Escape)
Break
EndIf

If KeyboardPushed(#PB_Key_Up)
Pitch + 1
EndIf
If KeyboardPushed(#PB_Key_Down)
Pitch - 1
EndIf

If KeyboardPushed(#PB_Key_Left)
Roll - 1
EndIf
If KeyboardPushed(#PB_Key_Right)
Roll + 1
EndIf

DrawScene()

FlipBuffers()
ResizeScene(WindowWidth(0), WindowHeight(0))

Repeat
glError = glGetError()
Select glError
Case 0
Break
Default
Debug glError ; + " :: " + PeekS(gluErrorString(glError))
EndSelect
ForEver

Pausing = Int((1000.0 / 60.0) - (ElapsedMilliseconds() - TimerStart))
If Pausing < 1 : Pausing = 1 : EndIf
Delay( Pausing )

ForEver

Top

 Post subject: Re: General 3D RotationPosted: Sat Jan 29, 2011 9:48 pm

Joined: Tue Nov 13, 2007 12:42 pm
Posts: 1307
Location: Manchester, UK
I cannot get the compiler to crash using this program and the x64 version. I don't know if it's my "hacks" that I'm doing to override some PB internal settings (namely "PB_Screen_Target") or if it's some setting that you have by default on the compiler options.

Anyone else getting a compiler error? And what is the error you get?

Top

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 12 posts ]

 All times are UTC + 1 hour

#### Who is online

Users browsing this forum: No registered users and 2 guests

 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forum

Search for:
 Jump to:  Select a forum ------------------ PureBasic    Coding Questions    Game Programming    3D Programming    Assembly Programming    The PureBasic Editor    The PureBasic Form Designer    General Discussion    Feature Requests and Wishlists    Tricks 'n' Tips Bug Reports    Bugs - Windows    Bugs - Linux    Bugs - Mac OSX    Bugs - Documentation OS Specific    AmigaOS    Linux    Windows    Mac OSX Miscellaneous    Announcement    Off Topic Showcase    Applications - Feedback and Discussion    PureFORM & JaPBe    TailBite