General 3D Rotation
General 3D Rotation
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?
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?
Re: General 3D Rotation
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.
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
pb 5.11
Re: General 3D Rotation
Ok, heres some example code, note that you will have to set the subsystem to opengl:
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?
Code: Select all
Global WallTexture
Structure POINTZ
x.f
y.f
z.f
EndStructure
Global NewList StarField.POINTZ()
For i = 1 To 2500
AddElement(StarField())
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_QUADS = $0007
#GL_QUAD_STRIP = $0008
#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)
glDepthMask(a.c)
glDisable(a.l)
glEnable(a.l)
glEnd()
glGenTextures(a.l,b.l)
glGetError()
glHint(a.l,b.l)
glLoadIdentity()
glMatrixMode(a.l)
glShadeModel(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);
glShadeModel(#GL_SMOOTH)
glClearDepth(1.0)
glEnable(#GL_DEPTH_TEST)
glDepthMask(#GL_TRUE);
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)
glLoadIdentity()
gluPerspective(45, width / height, 0, 100)
glMatrixMode(#GL_MODELVIEW)
glLoadIdentity()
EndProcedure
Procedure DrawScene()
glClear(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glRotatef(Pitch, 1, 0, 0)
glRotatef(Roll, 0, 0, 1)
glEnable(#GL_TEXTURE_2D)
glBindTexture(#GL_TEXTURE_2D, WallTexture)
glPushMatrix()
glTranslatef(0, 0, -5)
glBegin(#GL_QUADS);
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
; load textures
#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 )
ForEverHowever, 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?
-
DarkDragon
- Addict

- Posts: 2348
- Joined: Mon Jun 02, 2003 9:16 am
- Location: Germany
- Contact:
Re: General 3D Rotation
The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)
bye,
Daniel
Daniel
Re: General 3D Rotation
Hm runs fine with WinXP PB4.51, did you enable "opengl" subsystem?DarkDragon wrote:The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)
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
Re: General 3D Rotation
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.
Re: General 3D Rotation
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
-
DarkDragon
- Addict

- Posts: 2348
- Joined: Mon Jun 02, 2003 9:16 am
- Location: Germany
- Contact:
Re: General 3D Rotation
Yes I did. I even updated PureBasic to PB 4.51 and it still crashes.gnasen wrote:Hm runs fine with WinXP PB4.51, did you enable "opengl" subsystem?DarkDragon wrote:The compiler crashes here when trying to run this. (Windows 7, PB 4.50 x64)
With x86 it works well.
Btw.: OpenGL is not a 3d engine but a renderer. Its on the same level as direct3d.
bye,
Daniel
Daniel
Re: General 3D Rotation
That sounds like a 32 bit/64 bit pointer conflict. Hmmm. I'll look at that when I get home.
-
DarkDragon
- Addict

- Posts: 2348
- Joined: Mon Jun 02, 2003 9:16 am
- Location: Germany
- Contact:
Re: General 3D Rotation
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.
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
Daniel
Re: General 3D Rotation
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!
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: Select all
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
AddElement(StarField())
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_QUADS = $0007
#GL_QUAD_STRIP = $0008
#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)
glDepthMask(a.c)
glDisable(a.l)
glEnable(a.l)
glEnd()
glGenTextures(a.l,b.l)
glGetError()
glHint(a.l,b.l)
glLoadIdentity()
glMatrixMode(a.l)
glShadeModel(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);
glShadeModel(#GL_SMOOTH)
glClearDepth(1.0)
glEnable(#GL_DEPTH_TEST)
glDepthMask(#GL_TRUE);
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)
glLoadIdentity()
gluPerspective(45, width / height, 0, 100)
glMatrixMode(#GL_MODELVIEW)
glLoadIdentity()
EndProcedure
Procedure DrawScene()
glClear(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
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)
glBegin(#GL_QUADS);
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
; load textures
#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 )
ForEverRe: General 3D Rotation
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?
Anyone else getting a compiler error? And what is the error you get?
