1/* PROJECT: 3Dmov 2 AUTHORS: Zenja Solaja 3 COPYRIGHT: 2009 Haiku Inc 4 DESCRIPTION: Haiku version of the famous BeInc demo 3Dmov 5 Just drag'n'drop media files to the 3D objects 6*/ 7 8#include <stdio.h> 9#include <assert.h> 10 11#include <Bitmap.h> 12#include <TranslationUtils.h> 13 14#include "GLUtility.h" 15#include "ViewSphere.h" 16 17// Local definitions 18 19// Local functions 20 21// Local variables 22 23/******************************** 24 Sphere scene 25*********************************/ 26class Sphere 27{ 28public: 29 Sphere(const float radius, const int stacks = 10, const int slices = 10); 30 ~Sphere(); 31 void Render(); 32 void SetMediaSource(MediaSource *source) {fMediaSource = source;} 33 void SetAngle(float angle_y, float angle_z); 34 35private: 36 MediaSource *fMediaSource; 37 int fNumberVertices; 38 float *fGeometry; 39 float *fTextureCoords; 40 float fRotationY, fRotationZ; 41}; 42 43/* FUNCTION: Sphere :: Sphere 44 ARGUMENTS: radius 45 stacks vertical stacks 46 slices horizontal slices 47 RETURN: n/a 48 DESCRIPTION: Constructor 49*/ 50Sphere :: Sphere(const float radius, const int stacks, const int slices) 51{ 52 fGeometry = 0; 53 fTextureCoords = 0; 54 fMediaSource = 0; 55 fRotationY = 0; 56 fRotationZ = 0; 57 58 fNumberVertices = 2*stacks*(slices+1); 59 fGeometry = new float [fNumberVertices*3]; 60 fTextureCoords = new float [fNumberVertices*2]; 61 62 float *v = fGeometry; 63 float *t = fTextureCoords; 64 65 float z0, z1, r0, r1; 66 float x, y, z; 67 //YVector3 normal; // not used in 3Dmov, but useful to know 68 69 for (int i=0; i < stacks; i++) 70 { 71 z0 = (float)i/(float)stacks; 72 z1 = (float)(i+1)/(float)stacks; 73 r0 = radius * sind(180 * (float)i/(float)stacks); 74 r1 = radius * sind(180 * (float)(i+1)/(float)stacks); 75 76 for (int j=0; j < (slices + 1); j++) 77 { 78 x = sind(360.0f * (float)j/(float)slices); 79 y = cosd(360.0f * (float)j/(float)slices); 80 z = radius * cosd(180*z0); 81 82 // Vertices 83 *v++ = x * r0; 84 *v++ = -y * r0; 85 *v++ = z; 86 // Normal not used in 3Dmov, but if you ever need it 87 //normal.Set(x*r0, -y*r0, z); 88 //normal.Normalise(); 89 // Textures 90 *t++ = (float)j/(float)slices; 91 *t++ = z0; 92 93 z = radius * cosd(180*z1); 94 // Vertices 95 *v++ = x * r1; 96 *v++ = -y * r1; 97 *v++ = z; 98 // Normals not used in 3Dmov, but if you ever need it 99 //normal.Set(x*r1, -y*r1, z); 100 //normal.Normalise(); 101 // Textures 102 *t++ = (float)j/(float)slices; 103 *t++ = z1; 104 } 105 } 106} 107 108/* FUNCTION: Sphere :: ~Sphere 109 ARGUMENTS: n/a 110 RETURN: n/a 111 DESCRIPTION: Destructor. fMediaSource destroyed by ViewSphere 112*/ 113Sphere :: ~Sphere() 114{ 115 delete [] fGeometry; 116 delete [] fTextureCoords; 117} 118 119/* FUNCTION: Sphere :: SetAngle 120 ARGUMENTS: angle_y 121 angle_z 122 RETURN: n/a 123 DESCRIPTION: Rotate sphere by Euler angles 124*/ 125void Sphere :: SetAngle(float angle_y, float angle_z) 126{ 127 fRotationY = angle_y; 128 fRotationZ = angle_z; 129} 130 131/* FUNCTION: Sphere :: Render 132 ARGUMENTS: none 133 RETURN: n/a 134 DESCRIPTION: Draw sphere 135*/ 136void Sphere :: Render() 137{ 138 glColor4f(1,1,1,1); 139 glBindTexture(GL_TEXTURE_2D, fMediaSource->mTextureID); 140 141 glPushMatrix(); 142 glRotatef(-30, 1, 0, 0); 143 glRotatef(fRotationY, 0, 1, 0); 144 glRotatef(fRotationZ, 0, 0, 1); 145 glTexCoordPointer(2, GL_FLOAT, 0, fTextureCoords); 146 glVertexPointer(3, GL_FLOAT, 0, fGeometry); 147 glDrawArrays(GL_TRIANGLE_STRIP, 0, fNumberVertices); 148 glPopMatrix(); 149} 150 151/******************************** 152 ViewSphere 153*********************************/ 154 155/* FUNCTION: ViewSphere :: ViewSphere 156 ARGUMENTS: frame 157 RETURN: n/a 158 DESCRIPTION: Constructor 159*/ 160ViewSphere :: ViewSphere(BRect frame) 161 : ViewObject(frame) 162{ 163 fStartTime = real_time_clock_usecs(); 164 fSphere = 0; 165 fMediaSource = 0; 166 fSpeedZ = 10.0f; 167 fSpeedY = 0.0f; 168 fAngleY = 0; 169 fAngleZ = 0; 170} 171 172/* FUNCTION: ViewSphere :: ~ViewSphere 173 ARGUMENTS: n/a 174 RETURN: n/a 175 DESCRIPTION: Destructor 176*/ 177ViewSphere :: ~ViewSphere() 178{ 179 delete fSphere; 180 if (fMediaSource != GetDefaultMediaSource()) 181 delete fMediaSource; 182} 183 184/* FUNCTION: ViewSphere :: AttachedToWindow 185 ARGUMENTS: none 186 RETURN: n/a 187 DESCRIPTION: Hook function called when view attached to window (looper) 188*/ 189void ViewSphere :: AttachedToWindow(void) 190{ 191 ViewObject::AttachedToWindow(); 192 193 LockGL(); 194 glClearColor(0,0,0,1); 195 196 fSphere = new Sphere(0.1f, 10, 10); 197 fMediaSource = GetDefaultMediaSource(); 198 fSphere->SetMediaSource(fMediaSource); 199 200 UnlockGL(); 201} 202 203/* FUNCTION: ViewSphere :: Render 204 ARGUMENTS: none 205 RETURN: n/a 206 DESCRIPTION: Draw view contents 207*/ 208void ViewSphere :: Render(void) 209{ 210 LockGL(); 211 212 bigtime_t current_time = real_time_clock_usecs(); 213 bigtime_t delta = current_time - fStartTime; 214 fStartTime = current_time; 215 216 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 217 218 fAngleY += fSpeedY*(float)delta/1000000.0f; 219 fAngleZ += fSpeedZ*(float)delta/1000000.0f; 220 fSphere->SetAngle(fAngleY, fAngleZ); 221 222 glPushMatrix(); 223 glTranslatef(0.0f, 0.0f, 0.15f); 224 fSphere->Render(); 225 glPopMatrix(); 226 227 glFlush(); 228 SwapBuffers(); 229 230 // Display frame rate 231 /* 232 static int fps = 0; 233 static int time_delta = 0; 234 fps++; 235 time_delta += delta; 236 if (time_delta > 1000000) 237 { 238 printf("%d fps\n", fps); 239 fps = 0; 240 time_delta = 0; 241 } 242 */ 243 UnlockGL(); 244} 245 246/* FUNCTION: ViewSphere :: MouseDown 247 ARGUMENTS: p 248 RETURN: n/a 249 DESCRIPTION: Hook function called when mouse down detected 250*/ 251void ViewSphere :: MouseDown(BPoint p) 252{ 253 // Determine mouse button 254 BMessage* msg = Window()->CurrentMessage(); 255 uint32 buttons; 256 257 msg->FindInt32("buttons", (int32*)&buttons); 258 259 if (buttons & B_PRIMARY_MOUSE_BUTTON) 260 { 261 SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); 262 fMouseTracking = true; 263 fMousePosition = p; 264 } 265} 266 267/* FUNCTION: ViewSphere :: MouseMoved 268 ARGUMENTS: p 269 transit 270 message 271 RETURN: n/a 272 DESCRIPTION: Hook function called when mouse move detected. 273 This demo is succeptable to Gimbal lock, but it doesn't really matter. 274*/ 275void ViewSphere :: MouseMoved(BPoint p, uint32 transit, const BMessage *message) 276{ 277 if (fMouseTracking) 278 { 279 if (transit == B_INSIDE_VIEW) 280 { 281 fSpeedY = 5*(p.y - fMousePosition.y); 282 fSpeedZ = 5*(p.x - fMousePosition.x); 283 fMousePosition = p; 284 } 285 } 286} 287 288/* FUNCTION: ViewSphere :: MouseUp 289 ARGUMENTS: p 290 RETURN: n/a 291 DESCRIPTION: Hook function called when mouse up detected 292*/ 293void ViewSphere :: MouseUp(BPoint p) 294{ 295 fMouseTracking = false; 296} 297 298/* FUNCTION: ViewSphere :: DragDropImage 299 ARGUMENTS: texture_id 300 mouse_x 301 mouse_y 302 RETURN: true if source ownership acquired 303 DESCRIPTION: Hook function called when user drags/drops image to app window 304*/ 305bool ViewSphere :: SurfaceUpdate(MediaSource *source, float mouse_x, float mouse_y) 306{ 307 LockGL(); 308 309 if (fMediaSource != GetDefaultMediaSource()) 310 delete fMediaSource; 311 fMediaSource = source; 312 fSphere->SetMediaSource(source); 313 314 UnlockGL(); 315 316 return true; 317 318} 319 320 321 322 323