[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Improve MyGL a bit
From: |
oren |
Subject: |
Improve MyGL a bit |
Date: |
Mon, 23 Mar 2009 23:28:28 -0700 (PDT) |
User-agent: |
G2/1.0 |
Hi, Here is a patch for cleaning up MyGL in
http://svn.gna.org/svn/gnustep/tests/examples/trunk/gui/MyGL
Thanks!
Index: AppController.m
===================================================================
--- AppController.m (revision 28119)
+++ AppController.m (working copy)
@@ -9,26 +9,16 @@
#include <math.h>
-static GLfloat _rtx = 0;
-static GLfloat _rty = 0;
-static GLfloat _rtz = 0;
-static GLfloat _artx = 0;
-static GLfloat _arty = 0;
-static GLfloat _artz = 0;
-static GLfloat _artl = 50;
+static float light_source[3] = {1.0, 1.0, 1.0};
typedef struct _Vector
{
- float X;
- float Y;
- float Z;
+ float co[3];
} Vector;
typedef struct _Tri
{
- int p1;
- int p2;
- int p3;
+ int p[3];
} Tri;
@@ -37,7 +27,144 @@
float Data[16];
} MATRIX;
+/* Shamelessly stolen from Blender's */
+void Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4])
+{
+ /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
+
+ m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]
+ m2[0][3]*m3[3][0];
+ m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]
+ m2[0][3]*m3[3][1];
+ m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]
+ m2[0][3]*m3[3][2];
+ m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3]
+ m2[0][3]*m3[3][3];
+
+ m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]
+ m2[1][3]*m3[3][0];
+ m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]
+ m2[1][3]*m3[3][1];
+ m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]
+ m2[1][3]*m3[3][2];
+ m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3]
+ m2[1][3]*m3[3][3];
+
+ m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]
+ m2[2][3]*m3[3][0];
+ m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]
+ m2[2][3]*m3[3][1];
+ m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]
+ m2[2][3]*m3[3][2];
+ m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3]
+ m2[2][3]*m3[3][3];
+
+ m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0]
+ m2[3][3]*m3[3][0];
+ m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1]
+ m2[3][3]*m3[3][1];
+ m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2]
+ m2[3][3]*m3[3][2];
+ m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3]
+ m2[3][3]*m3[3][3];
+
+}
+
+void Mat4Transp(float mat[][4])
+{
+ float t;
+
+ t = mat[0][1] ;
+ mat[0][1] = mat[1][0] ;
+ mat[1][0] = t;
+ t = mat[0][2] ;
+ mat[0][2] = mat[2][0] ;
+ mat[2][0] = t;
+ t = mat[0][3] ;
+ mat[0][3] = mat[3][0] ;
+ mat[3][0] = t;
+
+ t = mat[1][2] ;
+ mat[1][2] = mat[2][1] ;
+ mat[2][1] = t;
+ t = mat[1][3] ;
+ mat[1][3] = mat[3][1] ;
+ mat[3][1] = t;
+
+ t = mat[2][3] ;
+ mat[2][3] = mat[3][2] ;
+ mat[3][2] = t;
+}
+
+
+void VecRotToMat3( float *vec, float phi, float mat[][3])
+{
+ /* rotation of phi radials around vec */
+ float vx, vx2, vy, vy2, vz, vz2, co, si;
+
+ vx= vec[0];
+ vy= vec[1];
+ vz= vec[2];
+ vx2= vx*vx;
+ vy2= vy*vy;
+ vz2= vz*vz;
+ co= (float)cos(phi);
+ si= (float)sin(phi);
+
+ mat[0][0]= vx2+co*(1.0f-vx2);
+ mat[0][1]= vx*vy*(1.0f-co)+vz*si;
+ mat[0][2]= vz*vx*(1.0f-co)-vy*si;
+ mat[1][0]= vx*vy*(1.0f-co)-vz*si;
+ mat[1][1]= vy2+co*(1.0f-vy2);
+ mat[1][2]= vy*vz*(1.0f-co)+vx*si;
+ mat[2][0]= vz*vx*(1.0f-co)+vy*si;
+ mat[2][1]= vy*vz*(1.0f-co)-vx*si;
+ mat[2][2]= vz2+co*(1.0f-vz2);
+
+}
+
+void Mat4One(float m[][4])
+{
+
+ m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0;
+ m[0][1]= m[0][2]= m[0][3]= 0.0;
+ m[1][0]= m[1][2]= m[1][3]= 0.0;
+ m[2][0]= m[2][1]= m[2][3]= 0.0;
+ m[3][0]= m[3][1]= m[3][2]= 0.0;
+}
+
+
+void Mat4CpyMat3(float m1[][4], float m2[][3]) /* no clear */
+{
+ m1[0][0]= m2[0][0];
+ m1[0][1]= m2[0][1];
+ m1[0][2]= m2[0][2];
+
+ m1[1][0]= m2[1][0];
+ m1[1][1]= m2[1][1];
+ m1[1][2]= m2[1][2];
+
+ m1[2][0]= m2[2][0];
+ m1[2][1]= m2[2][1];
+ m1[2][2]= m2[2][2];
+
+ /* Reevan's Bugfix */
+ m1[0][3]=0.0F;
+ m1[1][3]=0.0F;
+ m1[2][3]=0.0F;
+
+ m1[3][0]=0.0F;
+ m1[3][1]=0.0F;
+ m1[3][2]=0.0F;
+ m1[3][3]=1.0F;
+}
+
+void VecRotToMat4( float *vec, float phi, float mat[][4])
+{
+ float tmat[3][3];
+
+ VecRotToMat3(vec, phi, tmat);
+ Mat4One(mat);
+ Mat4CpyMat3(mat, tmat);
+}
+
+void VecMat4MulVecfl(float *in, float mat[][4], float *vec)
+{
+ float x,y;
+
+ x=vec[0];
+ y=vec[1];
+ in[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0];
+ in[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1];
+ in[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2];
+}
+
+
@interface Mesh : NSObject
{
@public
@@ -56,74 +183,56 @@
@implementation Mesh
-static float DotProduct (Vector *v1, Vector *v2)
+static float DotProduct (float v1[], float v2[])
{
- return v1->X * v2->X + v1->Y * v2->Y + v1->Z * v2->Z;
+ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}
-static float Magnitude (Vector *v)
+static float Magnitude (float v[])
{
- return sqrtf(v->X * v->X + v->Y * v->Y + v->Z * v->Z);
+ return sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
-static void Normalize (Vector *v)
+static void Normalize (float v[])
{
float m = Magnitude(v);
if (m != 0.0f)
{
- v->X /= m;
- v->Y /= m;
- v->Z /= m;
+ v[0] /= m;
+ v[1] /= m;
+ v[2] /= m;
}
}
- (void) drawCelShade
{
- int t;
- Vector light;
+ int t,i;
Vector vv;
- light.X = 1.0f + _rtx;
- light.Y = 1.0f + _rty;
- light.Z = 1.0f + _rtz;;
- Normalize(&light);
float xx;
for(t = 0; t < pcount; t++)
{
glBegin( GL_TRIANGLES );
- vv = nvertices[pnormals[t].p1];
- Normalize(&vv);
- xx = DotProduct(&light,&vv);
- if (xx < 0.0f) xx = 0;
- glColor3f(xx,xx,xx);
- glVertex3f(vertices[polygons[t].p1].X,
- vertices[polygons[t].p1].Y,
- vertices[polygons[t].p1].Z);
+ for (i = 0; i < 3; i++)
+ {
+ vv = nvertices[pnormals[t].p[i]];
+ Normalize(&vv.co);
+ xx = DotProduct(light_source, &vv.co);
+ if (xx < 0.0f) xx = 0;
+ glColor3f(xx,xx,xx);
+ glVertex3f(vertices[polygons[t].p[i]].co[0],
+ vertices[polygons[t].p[i]].co[1],
+ vertices[polygons[t].p[i]].co[2]);
+ }
- vv = nvertices[pnormals[t].p2];
- Normalize(&vv);
- xx = DotProduct(&light,&vv);
- if (xx < 0.0f) xx = 0;
- glColor3f(xx,xx,xx);
- glVertex3f(vertices[polygons[t].p2].X,
- vertices[polygons[t].p2].Y,
- vertices[polygons[t].p2].Z);
-
- vv = nvertices[pnormals[t].p3];
- Normalize(&vv);
- xx = DotProduct(&light,&vv);
- if (xx < 0.0f) xx = 0;
- glColor3f(xx,xx,xx);
- glVertex3f(vertices[polygons[t].p3].X,
- vertices[polygons[t].p3].Y,
- vertices[polygons[t].p3].Z);
-
glEnd( );
}
}
+
+#if 0
- (void) draw
{
int t;
@@ -140,18 +249,19 @@
glBegin( GL_TRIANGLES );
for(t = 0; t < pcount; t++)
{
- glVertex3f(vertices[polygons[t].p1].X,
- vertices[polygons[t].p1].Y,
- vertices[polygons[t].p1].Z);
- glVertex3f(vertices[polygons[t].p2].X,
- vertices[polygons[t].p2].Y,
- vertices[polygons[t].p2].Z);
- glVertex3f(vertices[polygons[t].p3].X,
- vertices[polygons[t].p3].Y,
- vertices[polygons[t].p3].Z);
+ glVertex3f(vertices[polygons[t].p1].co[0],
+ vertices[polygons[t].p1].co[1],
+ vertices[polygons[t].p1].co[2]);
+ glVertex3f(vertices[polygons[t].p2].co[0],
+ vertices[polygons[t].p2].co[1],
+ vertices[polygons[t].p2].co[2]);
+ glVertex3f(vertices[polygons[t].p3].co[0],
+ vertices[polygons[t].p3].co[1],
+ vertices[polygons[t].p3].co[2]);
}
glEnd( );
}
+#endif
@end
@@ -205,9 +315,9 @@
ar = [str componentsSeparatedByString:@" "];
if ([ar count] == 3)
{
- mesh->vertices[p].X = [[ar objectAtIndex:0]
floatValue];
- mesh->vertices[p].Y = [[ar objectAtIndex:1]
floatValue];
- mesh->vertices[p].Z = [[ar objectAtIndex:2]
floatValue];
+ mesh->vertices[p].co[0] = [[ar objectAtIndex:0]
floatValue];
+ mesh->vertices[p].co[1] = [[ar objectAtIndex:1]
floatValue];
+ mesh->vertices[p].co[2] = [[ar objectAtIndex:2]
floatValue];
p++;
}
}
@@ -231,9 +341,9 @@
ar = [str componentsSeparatedByString:@" "];
if ([ar count] == 3)
{
- mesh->nvertices[p].X = [[ar objectAtIndex:0]
floatValue];
- mesh->nvertices[p].Y = [[ar objectAtIndex:1]
floatValue];
- mesh->nvertices[p].Z = [[ar objectAtIndex:2]
floatValue];
+ mesh->nvertices[p].co[0] = [[ar
objectAtIndex:0] floatValue];
+ mesh->nvertices[p].co[1] = [[ar
objectAtIndex:1] floatValue];
+ mesh->nvertices[p].co[2] = [[ar
objectAtIndex:2] floatValue];
p++;
}
}
@@ -241,13 +351,13 @@
else if (trackPolygons)
{
NSArray *parray = [str componentsSeparatedByString:@" "];
- mesh->polygons[idx].p1 = [[parray objectAtIndex:0] intValue];
- mesh->polygons[idx].p2 = [[parray objectAtIndex:2] intValue];
- mesh->polygons[idx].p3 = [[parray objectAtIndex:4] intValue];
+ mesh->polygons[idx].p[0] = [[parray objectAtIndex:0] intValue];
+ mesh->polygons[idx].p[1] = [[parray objectAtIndex:2] intValue];
+ mesh->polygons[idx].p[2] = [[parray objectAtIndex:4] intValue];
- mesh->pnormals[idx].p1 = [[parray objectAtIndex:1] intValue];
- mesh->pnormals[idx].p2 = [[parray objectAtIndex:3] intValue];
- mesh->pnormals[idx].p3 = [[parray objectAtIndex:5] intValue];
+ mesh->pnormals[idx].p[0] = [[parray objectAtIndex:1] intValue];
+ mesh->pnormals[idx].p[1] = [[parray objectAtIndex:3] intValue];
+ mesh->pnormals[idx].p[2] = [[parray objectAtIndex:5] intValue];
idx ++;
}
}
@@ -316,6 +426,15 @@
@interface MyGLView : NSOpenGLView
{
NSMutableArray *meshArray;
+ double cam_location[3];
+ double cam_direction[3];
+ double cam_udir[3];
+ double cam_rdir[3];
+
+ float model_trans[16];
+ float model_itrans[16];
+
+ float ls[3];
}
@end
@@ -324,7 +443,7 @@
- (void) scrollWheel:(NSEvent *)theEvent
{
- _artl += [theEvent deltaY];
+ cam_location[2] += [theEvent deltaY];
[self reshape];
}
@@ -332,28 +451,82 @@
{
NSRect bounds = [self bounds];
- _arty = [theEvent deltaX]/NSWidth(bounds) * 180;
- _artx = -[theEvent deltaY]/NSHeight(bounds) * 180;
- _artz = sqrtf(_arty * _artz);
+ /* object rotation */
+ float temp[16];
+ float rotation[16];
+ Vector v;
- _rtz += _artz;
- _rty += _arty;
- _rtx += _artx;
+ v.co[0] = -[theEvent deltaY]/NSHeight(bounds);
+ v.co[1] = [theEvent deltaX]/NSWidth(bounds);
+ v.co[2] = 0.0;
+
+ Normalize(&v.co);
+
+ VecRotToMat4(&v, 0.05, rotation);
+ memcpy(temp, model_trans, sizeof(float) * 16) ;
+ Mat4MulMat4(model_trans, temp, rotation);
+
+ Mat4Transp(rotation);
+ memcpy(temp, model_itrans, sizeof(float) * 16) ;
+ Mat4MulMat4(model_itrans, rotation, temp);
+
+ [self reshape];
}
- (void) prepareOpenGL
{
meshArray = [NSMutableArray new];
+ cam_location[0] = 0.0;
+ cam_location[1] = 0.0;
+ cam_location[2] = 4.0;
+
+ cam_direction[0] = 0.0;
+ cam_direction[1] = 0.0;
+ cam_direction[2] = -1.0;
+
+ cam_udir[0] = 0.0;
+ cam_udir[1] = 1.0;
+ cam_udir[2] = 0.0;
+
+ cam_rdir[0] = 1.0;
+ cam_rdir[1] = 0.0;
+ cam_rdir[2] = 0.0;
+
+ model_trans[0] = 1.0;
+ model_trans[1] = 0.0;
+ model_trans[2] = 0.0;
+ model_trans[3] = 0.0;
+
+ model_trans[4] = 0.0;
+ model_trans[5] = 1.0;
+ model_trans[6] = 0.0;
+ model_trans[7] = 0.0;
+
+ model_trans[8] = 0.0;
+ model_trans[9] = 0.0;
+ model_trans[10] = 1.0;
+ model_trans[11] = 0.0;
+
+ model_trans[12] = 0.0;
+ model_trans[13] = 0.0;
+ model_trans[14] = 0.0;
+ model_trans[15] = 1.0;
+
+ memcpy(model_itrans, model_trans, sizeof(float) * 16);
+
+ ls[0] = 1.0;
+ ls[1] = 1.0;
+ ls[2] = 1.0;
+
glShadeModel(GL_SMOOTH);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClearColor(0.8f, 0.7f, 0.6f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- glMatrixMode(GL_MODELVIEW);
[self reshape];
}
@@ -367,34 +540,79 @@
ratio = NSWidth(sceneBounds)/ NSHeight(sceneBounds);
- glViewport(0, 0, NSWidth(sceneBounds), NSHeight(sceneBounds));
+ // set background color
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- gluPerspective(_artl, ratio, 0.1f, 100.0f);
+ // left, right, bottom, top, near far
+ glFrustum(-0.5f, 0.5f, -0.4f, 0.4f, 1.0f, 100.0f);
+ glViewport(0, 0, NSWidth(sceneBounds), NSHeight(sceneBounds));
+
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+
+ gluLookAt(cam_location[0], cam_location[1], cam_location[2],
+ cam_location[0]+cam_direction[0],
cam_location[1]+cam_direction
[1], cam_location[2]+cam_direction[2],
+ cam_udir[0], cam_udir[1], cam_udir[2]);
+
[self setNeedsDisplay:YES];
}
+
- (void) drawRect:(NSRect)r
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ /*
glLoadIdentity();
+ */
- glTranslatef(-1.5f, 0.0f, -6.0f);
- glRotatef(_rtx,1.0f,0.0f,0.0f);
- glRotatef(_rty,0.0f,1.0f,0.0f);
- glRotatef(_rtz,0.0f,0.0f,1.0f);
+ VecMat4MulVecfl(light_source, model_itrans, ls);
+
+ glDisable(GL_CULL_FACE);
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glBegin(GL_LINES);
+ glColor3f(1.0, 0.0, 0.0);
+ glVertex3f(-10.0, 0.0, 0.0);
+ glVertex3f(10.0, 0.0, 0.0);
+ glColor3f(0.0, 1.0, 0.0);
+ glVertex3f(0.0, -10.0, 0.0);
+ glVertex3f(0.0, 10.0, 0.0);
+ glColor3f(0.0, 0.0, 1.0);
+ glVertex3f(0.0, 0.0, -10.0);
+ glVertex3f(0.0, 0.0, 10.0);
+ glEnd();
+
+ glPushMatrix();
+
+ glMultMatrixf(model_trans);
+
+ glPointSize(10.0);
+ glBegin(GL_POINTS);
+ glColor3f(1.0, 1.0, 0.0);
+ glVertex3f(light_source[0], light_source[1], light_source[2]);
+ glEnd();
+
+ glScalef(0.2f,0.2f,0.2f);
+
+
[meshArray makeObjectsPerform:@selector(drawCelShade)];
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+
[[self openGLContext] flushBuffer];
}
+
+
-(void) refresh
{
+
[self setNeedsDisplay:YES];
}
@@ -419,11 +637,11 @@
static id glview;
-(void) applicationDidFinishLaunching: (NSNotification *)not
{
- [NSTimer scheduledTimerWithTimeInterval:0.05 //(1.0 / 30)
-
target:glview
-
selector:@selector(refresh)
- userInfo:nil
-
repeats:YES];
+ [NSTimer scheduledTimerWithTimeInterval:0.1 //(1.0 / 30)
+ target:glview
+ selector:@selector(refresh)
+ userInfo:nil
+ repeats:YES];
[glview loadModel];
}
- Improve MyGL a bit,
oren <=