Results 1 to 9 of 9

Thread: drawing 3d geometrical shapes using opengl , but without glu

  1. #1

    drawing 3d geometrical shapes using opengl , but without glu

    Is there an existing unit for drawing 3d geometrical shapes like cube/sphere/cylinder/cone/capsule etc?

    Glu cannot be used as i want to draw the shapes using an vertex buffer objects with GL_TRIANGLES .

    Also i am trying to write some function doing 3d drawing so far i am only happy with the cube and sphere code, for the cylinder i made several attempts but none of them work like i expect them. My attempt in glmodel is not working nice enough with the sphere shape in order to make a 3d capsule shape.

    So thanks in advance for your help.
    http://3das.noeska.com - create adventure games without programming

  2. #2
    Making actual 3D games is basically impossible without a modelling program. That is why i never generate them runtime. 1) less to code, 2) faster loading times, 3) texture mapping and normals the way i like.

    Anyway because i actually created my own modelling program (no longer developed cause its with Delphi), i do have some code to create different objects. This is cylinder for example, just to maybe give hints. If you want to we may try to see what your functions are doing...
    Don't remember how that code made texture coordinates but there's a different function to generate normals based on smoothing groups.
    Code:
    function TWorld3D.MakeCylinder(radius,sy: single; sides,segs: integer): word;
    var x,y,z: array[1..5] of single; x1,y1,i: integer;
        segA,segY: single;
    begin
      result:=New3DObject;
      if sides<3 then sides:=3;
      if segs<1 then segs:=1;
      segA:=2*PI/sides; segY:=sy/segs;
      with o[result] do
        for x1:=0 to sides-1 do begin
          // Cylinder
          for y1:=0 to segs-1 do begin
            x[2]:=radius*cos(x1*segA);
            z[2]:=radius*sin(x1*segA);
            y[2]:=-sy/2+y1*segY;
            x[3]:=radius*cos(x1*segA);
            z[3]:=radius*sin(x1*segA);
            y[3]:=-sy/2+(y1+1)*segY;
            x[4]:=radius*cos((x1+1)*segA);
            z[4]:=radius*sin((x1+1)*segA);
            y[4]:=-sy/2+(y1+1)*segY;
            x[1]:=radius*cos((x1+1)*segA);
            z[1]:=radius*sin((x1+1)*segA);
            y[1]:=-sy/2+y1*segY;       
            o[result].AddFace(x,y,z,4);
          end;
          // Top - Bottom
          for y1:=0 to 1 do begin
            x[1]:=radius*cos(x1*segA);
            z[1]:=radius*sin(x1*segA);
            x[2]:=radius*cos((x1-y1*2+1)*segA);
            z[2]:=radius*sin((x1-y1*2+1)*segA);
            x[3]:=0; z[3]:=0;
            for i:=1 to 3 do y[i]:=-sy/2+y1*sy;
            TFace(f[o[result].AddFace(x,y,z,3)]).smoothGroup:=1;
          end;
        end;
      o[result].UpdateSize;
    end;

  3. #3
    Here's some old code of mine.

    Code:
    unit mvRenderHelpers;
    {**<
    	@author(Jani Alanen <http://www.projectminiverse.com>)
    	@created(2007-01-27)
    	@lastmod(2009-01-07)
    
    	Miscellaneous helper code for rendering .
    
    	History
    
    	Created:
    		27.01.2007 (JA)
    
    	Modified:
    		07.01.2009 (JA)
    		- Renamed to mvRenderHelpers.pas
    
    }
    interface
    
    uses
    	{$IFDEF USE_SDL}
    	GL, GLU,
    	{$ELSE}
    	dglOpenGL,
    	{$ENDIF}
    	mvMath;
    
    procedure DrawCube(Size: TFloat);
    procedure DrawTorus(MinorRadius, MajorRadius: TFloat; NumMinor, NumMajor: TInt);
    procedure DrawSphere(NumMajor, NumMinor: TInt; Radius: TFloat);
    procedure DrawCylinder(NumMajor, NumMinor: TInt; Height, Radius: TFloat);
    procedure DrawSkewedPyramid(Size: TFloat);
    procedure DrawWireSkewedPyramid(Size: TFloat);
    procedure DrawTetrahedron(Size: TFloat);
    procedure DrawWireTetrahedron(Size: TFloat);
    procedure DrawOctahedron(Size: TFloat);
    procedure DrawWireOctahedron(Size: TFloat);
    
    implementation
    
    uses
    	mvGLUtils, mvGlobal;
    
    
    procedure DrawCube(Size: TFloat);
    const
    	// Texture coordinates from bottom left to top right
    		TexCoord: array [0..3] of TTexel = ((u: 0; v: 0),
    														(u: 1; v: 0),
    														(u: 1; v: 1),
    														(u: 0; v: 1));
    		// Vertices used in cube
    		Vertex: array [0..7] of TVertex = ((v:(-1.0, 1.0, 1.0)),		// 0
    													  (v:( 1.0, 1.0, 1.0)),		// 1
    													  (v:( 1.0,-1.0, 1.0)),		// 2
    													  (v:(-1.0,-1.0, 1.0)),		// 3
    													  (v:(-1.0, 1.0,-1.0)),		// 4
    													  (v:( 1.0, 1.0,-1.0)),		// 5
    													  (v:( 1.0,-1.0,-1.0)),		// 6
    													  (v:(-1.0,-1.0,-1.0)));	// 7
          // Faces of the cube
    		Cube: array [0..5, 0..3] of Integer = ((0, 1, 2, 3),
                                                 (1, 5, 6, 2),
                                                 (4, 5, 1, 0),
                                                 (0, 3, 7, 4),
    															(3, 2, 6, 7),
                                                 (5, 4, 7, 6));
    		// Normals for each face of the cube
          // Angle of normal and face is allways 90 degrees and
          // length is allways 1.0!
    		Normals: array [0..5] of TVertex = ((v:( 0.0, 0.0, 1.0)),
    														(v:( 1.0, 0.0, 0.0)),
    														(v:( 0.0, 1.0, 0.0)),
    														(v:(-1.0, 0.0, 0.0)),
    														(v:( 0.0,-1.0, 0.0)),
    														(v:( 0.0, 0.0,-1.0)));
    var
    	i, j: Integer;
    begin
    	{
    	// Start rendering quads
    	glBegin(GL_QUADS);
    	for i := 0 to 5 do
    	begin
    		// Set normal for this face
    		glNormal3fv(@Normals[i][0]);
    		for j := 0 to 3 do
    		begin
    			// Texture coordinates for this vertex in texels
    			glTexCoord2f(TexCoord[j, 0], TexCoord[j, 1]);
    			// Position for this vertex, object position NOT world position
    			glVertex3fv(@Vertex[Cube[i, j]][0]);
    		end;
    		glCheckForError();
    	end;
    	// End rendering quads
    	glEnd;
    	}
    
    	glBegin(GL_QUADS);
    
    	//glColor3f(1, 1, 1);
    	glNormal3f( 0.0, 0.0, 1.0);
    	glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
    	glTexCoord2f(1, 0); glVertex3f(-Size / 2, Size / 2, Size / 2);
    	glTexCoord2f(1, 1); glVertex3f(-Size / 2,-Size / 2, Size / 2);
    	glTexCoord2f(0, 1); glVertex3f( Size / 2,-Size / 2, Size / 2);
    
    	//glColor3f(1, 0, 0);
    	glNormal3f( 0.0, 0.0,-1.0);
    	glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
    	glTexCoord2f(1, 0);glVertex3f(-Size / 2, Size / 2,-Size / 2);
    	glTexCoord2f(1, 1); glVertex3f( Size / 2, Size / 2,-Size / 2);
    	glTexCoord2f(0, 1); glVertex3f( Size / 2,-Size / 2,-Size / 2);
    
    	//glColor3f(0, 1, 0);
    	glNormal3f( 0.0, 1.0, 0.0);
    	glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
    	glTexCoord2f(1, 0); glVertex3f( Size / 2, Size / 2,-Size / 2);
    	glTexCoord2f(1, 1); glVertex3f(-Size / 2, Size / 2,-Size / 2);
    	glTexCoord2f(0, 1); glVertex3f(-Size / 2, Size / 2, Size / 2);
    
    	//glColor3f(0, 0, 1);
    	glNormal3f( 0.0,-1.0, 0.0);
    	glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
    	glTexCoord2f(1, 0); glVertex3f( Size / 2,-Size / 2,-Size / 2);
    	glTexCoord2f(1, 1); glVertex3f( Size / 2,-Size / 2, Size / 2);
    	glTexCoord2f(0, 1); glVertex3f(-Size / 2,-Size / 2, Size / 2);
    
    	//glColor3f(0, 1, 1);
    	glNormal3f( 1.0, 0.0, 0.0);
    	glTexCoord2f(0, 0); glVertex3f( Size / 2, Size / 2, Size / 2);
    	glTexCoord2f(1, 0); glVertex3f( Size / 2,-Size / 2, Size / 2);
    	glTexCoord2f(1, 1); glVertex3f( Size / 2,-Size / 2,-Size / 2);
    	glTexCoord2f(0, 1); glVertex3f( Size / 2, Size / 2,-Size / 2);
    
    	//glColor3f(1, 1, 0);
    	glNormal3f(-1.0, 0.0, 0.0);
    	glTexCoord2f(0, 0); glVertex3f(-Size / 2,-Size / 2,-Size / 2);
    	glTexCoord2f(1, 0); glVertex3f(-Size / 2,-Size / 2, Size / 2);
    	glTexCoord2f(1, 1); glVertex3f(-Size / 2, Size / 2, Size / 2);
    	glTexCoord2f(0, 1); glVertex3f(-Size / 2, Size / 2,-Size / 2);
    	glEnd();
    
    	{
    	glVertex3f(-Size + x, Size + y, Size + z);
    	glVertex3f( Size + x, Size + y, Size + z);
    	glVertex3f( Size + x,-Size + y, Size + z);
    	glVertex3f(-Size + x,-Size + y, Size + z);
    
    	glVertex3f( Size + x, Size + y, Size + z);
    	glVertex3f( Size + x, Size + y,-Size + z);
    	glVertex3f( Size + x,-Size + y,-Size + z);
       glVertex3f( Size + x,-Size + y, Size + z);
    
    	glVertex3f(-Size + x, Size + y,-Size + z);
       glVertex3f( Size + x, Size + y,-Size + z);
       glVertex3f( Size + x, Size + y,-Size + z);
       glVertex3f(-Size + x, Size + y,-Size + z);
    
       glVertex3f(-Size + x, Size + y,-Size + z);
       glVertex3f(-Size + x,-Size + y, Size + z);
    	glVertex3f(-Size + x,-Size + y,-Size + z);
       glVertex3f(-Size + x, Size + y,-Size + z);
    
       glVertex3f(-Size + x,-Size + y, Size + z);
       glVertex3f( Size + x,-Size + y, Size + z);
       glVertex3f( Size + x,-Size + y,-Size + z);
       glVertex3f(-Size + x,-Size + y,-Size + z);
    
       glVertex3f( Size + x, Size,-Size + z);
       glVertex3f(-Size + x, Size,-Size + z);
       glVertex3f(-Size + x,-Size,-Size + z);
       glVertex3f( Size + x,-Size,-Size + z);
       }
    
       //glEnd;
    end;
    
    procedure DrawTorus(MinorRadius, MajorRadius: TFloat; NumMinor, NumMajor: TInt);
    var
    	MajorStep, MinorStep: TFloat;
    	i, j: Integer;
       a0, a1, b: TFloat;
       x0, y0, x1, y1, c, r, z: TFloat;
    begin
    	MajorStep := 2.7 * PI / NumMajor;
       MinorStep := 2.7 * PI / NumMajor;
       for i := 0 to numMajor do
       begin
       	a0 := i * MajorStep;
       	a1 := a0 + MajorStep;
       	x0 := Cos(a0);
       	y0 := Sin(a0);
       	x1 := Cos(a1);
       	y1 := Sin(a1);
       	glBegin(GL_TRIANGLE_STRIP);
       	for j := 0 to numMinor do
         	begin
          	b := j * MinorStep;
             c := Cos(b);
             r := MinorRadius * c + MajorRadius;
    			z := MinorRadius * Sin(b);
    
             glNormal3f(x0 * c, y0 * c, z / MinorRadius);
             glTexCoord2f(i / NumMajor, j / NumMinor);
             glVertex3f(x0 * r, y0 * r, z);
    
             glNormal3f(x1 * c, y1 * c, z / MinorRadius);
             glTexCoord2f((i + 1) / NumMajor, j / NumMinor);
             glVertex3f(x1 * r, y1 * r, z);
    		end;
          glEnd();
    	end;
    end;
    
    procedure DrawSphere(NumMajor, NumMinor: Integer; Radius: TFloat);
    var
    	MajorStep, MinorStep: TFloat;
    	i, j: Integer;
    	a, b, c, r0, r1: TFloat;
       x, y, z0, z1: TFloat;
    begin
    	MajorStep := (PI / NumMajor);
    	MinorStep  := (2.0 * PI / NumMinor);
    
       for i := 0 to NumMajor do
       begin
       	a := i * MajorStep;
          b := a + MajorStep;
          r0 := radius * Sin(a);
          r1 := radius * Sin(b);
          z0 := radius * Cos(a);
          z1 := radius * Cos(b);
    
          glBegin(GL_TRIANGLE_STRIP);
          for j := 0 to NumMinor do
          begin
          	c := j * MinorStep;
             x := Cos(c);
             y := Sin(c);
    
             glNormal3f((x * r0) / radius, (y * r0) / Radius, z0 / Radius);
             glTexCoord2f(j / NumMinor, i / NumMajor);
             glVertex3f(x * r0, y * r0, z0);
    
             glNormal3f((x * r1) / Radius, (y * r1) / Radius, z1 / Radius);
             glTexCoord2f(j / NumMinor, (i + 1) / NumMajor);
             glVertex3f(x * r1, y * r1, z1);
    		end;
       glEnd();
       end;
    end;
    
    procedure DrawCylinder(NumMajor, NumMinor: TInt; Height, Radius: TFloat);
    var       MajorStep, MinorStep: TFloat;
    			 i, j: Integer;
    			 a, x, y, z0, z1: TFloat;
    begin
    	  MajorStep := Height / NumMajor;
    	  MinorStep := 2.0 * PI / NumMinor;
    
    	  for i := 0 to NumMajor do
    	  begin
    			 z0 := 0.5 * Height - i * MajorStep;
    			 z1 := z0 - MajorStep;
    
    			 glBegin(GL_TRIANGLE_STRIP);
    			 for j := 0 to NumMinor do
    			 begin
    					a := j * MinorStep;
    					x := Radius * Cos(a);
    					y := Radius * Sin(a);
    
    					glNormal3f(x / radius, y / radius, 0.0);
    					glTexCoord2f(j / numMinor, i / numMajor);
    					glVertex3f(x, y, z0);
    
    					glNormal3f(x / radius, y / radius, 0.0);
    					glTexCoord2f(j / numMinor, (i + 1) / numMajor);
    					glVertex3f(x, y, z1);
    			 end;
    			 glEnd();
    	  end;
    end;
    
    procedure DrawSkewedPyramid(Size: TFloat);
    begin
    	glBegin(GL_TRIANGLES);
    	// Back
    	glVertex3f(0, Size, -(Size / 2)); // Top
    	glVertex3f(Size/2, 0, -(Size / 2)); // Bottom right
    	glVertex3f(-Size/2, 0, -(Size / 2)); // Bottom left
    	//glVertex3f(0, Size, -(Size / 2));
    	glEnd;
    
    	// Left
    	glBegin(GL_TRIANGLES);
    	glVertex3f(0, 0, (Size / 2)); // Nose
    	glVertex3f(0, Size, -(Size / 2));
    	glVertex3f(-Size/2, 0, -(Size / 2));
    
    	//glVertex3f(0, 0, (Size / 2));
    	glEnd;
    
    	// Right
    	glBegin(GL_TRIANGLES);
    	glVertex3f(0, Size, -(Size / 2));
    	glVertex3f(0, 0, (Size / 2));
    	glVertex3f(Size/2, 0, -(Size / 2));
    	//glVertex3f(0, Size, -(Size / 2));
    	glEnd();
    
    	// Bottom
    	glBegin(GL_TRIANGLES);
    	glVertex3f(0, 0, (Size / 2));
    	glVertex3f(-Size/2, 0, -(Size / 2));
    	glVertex3f(Size/2, 0, -(Size / 2));
    	//glVertex3f(0, 0, (Size / 2));
    	glEnd();
    end;
    
    procedure DrawWireSkewedPyramid(Size: TFloat);
    begin
    	glBegin(GL_LINE_STRIP);
    	// Back
    	glVertex3f(0, Size, -(Size / 2)); // Top
    	glVertex3f(Size/2, 0, -(Size / 2)); // Bottom right
    	glVertex3f(-Size/2, 0, -(Size / 2)); // Bottom left
    	glVertex3f(0, Size, -(Size / 2));
    	glEnd;
    
    	// Left
    	glBegin(GL_LINE_STRIP);
    	glVertex3f(0, 0, (Size / 2)); // Nose
    	glVertex3f(0, Size, -(Size / 2));
    	glVertex3f(-Size/2, 0, -(Size / 2));
    	glVertex3f(0, 0, (Size / 2));
    	glEnd;
    
    	// Right
    	glBegin(GL_LINE_STRIP);
    	glVertex3f(0, Size, -(Size / 2));
    	glVertex3f(0, 0, (Size / 2));
    	glVertex3f(Size/2, 0, -(Size / 2));
    	glVertex3f(0, Size, -(Size / 2));
    	glEnd();
    
    	// Bottom
    	glBegin(GL_LINE_STRIP);
    	glVertex3f(0, 0, (Size / 2));
    	glVertex3f(-Size/2, 0, -(Size / 2));
    	glVertex3f(Size/2, 0, -(Size / 2));
    	glVertex3f(0, 0, (Size / 2));
    	glEnd();
    end;
    
    procedure DrawTetrahedron(Size: TFloat);
    begin
    	{
    	glBegin(GL_TRIANGLE_STRIP);
    		glVertex3f(0, 2 * (Size / 2), 0);
    		glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(0, 0, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2), 0);
    		glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
    	glEnd();
    	}
    	glBegin(GL_TRIANGLE_STRIP);
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    		glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(0, -0.5, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    		glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
    	glEnd();
    end;
    
    procedure DrawWireTetrahedron(Size: TFloat);
    begin
    	{
    	glBegin(GL_LINE_STRIP);
    		glVertex3f(0, 2 * (Size / 2), 0);
    		glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2), 0);
    
    		glVertex3f(0, 2 * (Size / 2), 0);
    		glVertex3f(-1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(0, 0, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2), 0);
    
    		glVertex3f(0, 0, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2), 0);
    		glVertex3f(1 * (Size / 2), 0, 1 * (Size / 2));
    		glVertex3f(0, 0, -1.4 * (Size / 2));
    
    	glEnd();
    	}
    	glBegin(GL_LINE_STRIP);
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    		glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    		glVertex3f(-1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(0, -0.5, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    
    		glVertex3f(0, -0.5, -1.4 * (Size / 2));
    		glVertex3f(0, 2 * (Size / 2) - 0.5, 0);
    		glVertex3f(1 * (Size / 2), -0.5, 1 * (Size / 2));
    		glVertex3f(0, -0.5, -1.4 * (Size / 2));
    
    	glEnd();
    end;
    
    procedure DrawOctahedron(Size: TFloat);
    const
    	Vertices: array [0..5] of TVector3f = (
    		(v: (0.0, 0.0, 1.0/SQRT2)),
    		(v: ( 0.5, 0.5, 0.0)),
    		(v: (-0.5, 0.5, 0.0)),
    		(v: (-0.5,-0.5, 0.0)),
    		(v: (0.5,-0.5, 0.0)),
    		(v: (0.0, 0.0, -1.0/SQRT2))
    	);
    begin
    	glScalef(Size, Size, Size);
    	glBegin(GL_TRIANGLE_FAN);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[1]);
    		glVertex3fv(@Vertices[2]);
    		glVertex3fv(@Vertices[3]);
    		glVertex3fv(@Vertices[4]);
    		glVertex3fv(@Vertices[1]);
    	 glEnd();
    	 glBegin(GL_TRIANGLE_FAN);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[1]);
    		glVertex3fv(@Vertices[4]);
    		glVertex3fv(@Vertices[3]);
    		glVertex3fv(@Vertices[2]);
    		glVertex3fv(@Vertices[1]);
    	 glEnd();
    end;
    
    procedure DrawWireOctahedron(Size: TFloat);
    const
    	Vertices: array [0..5] of TVector3f = (
    		(v: (0.0, 0.0, 1.0/SQRT2)),
    		(v: ( 0.5, 0.5, 0.0)),
    		(v: (-0.5, 0.5, 0.0)),
    		(v: (-0.5,-0.5, 0.0)),
    		(v: (0.5,-0.5, 0.0)),
    		(v: (0.0, 0.0, -1.0/SQRT2))
    	);
    begin
    	glScalef(Size, Size, Size);
    	glBegin(GL_LINES);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[1]);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[2]);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[3]);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[4]);
    		glVertex3fv(@Vertices[0]);
    		glVertex3fv(@Vertices[1]);
    	glEnd();
    	glBegin(GL_LINES);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[1]);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[4]);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[3]);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[2]);
    		glVertex3fv(@Vertices[5]);
    		glVertex3fv(@Vertices[1]);
    	glEnd();
    	glBegin(GL_LINE_STRIP);
    		glVertex3fv(@Vertices[1]);
    		glVertex3fv(@Vertices[4]);
    		glVertex3fv(@Vertices[3]);
    		glVertex3fv(@Vertices[2]);
    		glVertex3fv(@Vertices[1]);
    	glEnd();
    end;
    
    
    end.

  4. #4
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    Hey there vgo - that is some mighty good code you've got there if I may say so myself. Would you mind awfully if I included this in Prometheus and added your name to the credits? This is non-commercial use, just so you know.
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  5. #5
    You can also take a look at sphere/cylinder/cone/cube -> mesh convertion in my engine. The code doesn't do direct rendering (it only converts to a mesh in TNodeIndexedFaceSet instance), and it's a little involved (I have to deal with texture coords, optional over-triangulating for Gouraud shading and such), but maybe it will be useful for some hints anyway. It's LGPL.

    https://vrmlengine.svn.sourceforge.n...e_cylinder.inc
    https://vrmlengine.svn.sourceforge.n...lnodes_box.inc
    https://vrmlengine.svn.sourceforge.n...des_sphere.inc

  6. #6
    PGD Staff code_glitch's Avatar
    Join Date
    Oct 2009
    Location
    UK (England, the bigger bit)
    Posts
    933
    Blog Entries
    45
    looks like a 3d promethetus is a possibility in the future then. for now though, lets focus on the the three current branches of it
    I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.

  7. #7
    This is what i have sofar (left out all but cylinder related):

    Code:
    unit glShapes;
    
    interface
    
    // Version: MPL 1.1
    
    uses
      DglOpenGL,
      glTypes;
    
    function createPlane(halfExtend: GLfloat;var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GluInt;
    function createCube(ax,ay,az: GLfloat;var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    
    function createSphere(numSlices:GLuint; radius: GLfloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    function createCylinder(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    function createDisk(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    function createClosedCylinder(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    
    implementation
    
    uses math;
    
    {------------------------------------------------------------------}
    {  Function to create a plane shape                                }
    {------------------------------------------------------------------}
    function createPlane(halfExtend: GLfloat;var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GluInt;
    var
      numVertices: Gluint;
      numIndices: Gluint;
      i: GLuint;
    
    const
      xy_vertices: array[0..15] of GLFloat=
        (		-1.0, -1.0, 0.0, +1.0,
    		    +1.0, -1.0, 0.0, +1.0,
    		    -1.0, +1.0, 0.0, +1.0,
    		    +1.0, +1.0, 0.0, +1.0);
      xy_normals: array[0..11] of GLFloat=
        (		0.0, 0.0, 1.0,
    		    0.0, 0.0, 1.0,
    		    0.0, 0.0, 1.0,
    		    0.0, 0.0, 1.0);
      xy_texCoords: array[0..7] of GLFloat=
        (		0.0, 0.0,
    		    1.0, 0.0,
    		    0.0, 1.0,
    		    1.0, 1.0);
      xy_indices: array[0..5] of GLuint=
        (		0, 1, 2,
    		    1, 3, 2);
    
    begin
    	numVertices := 4;
    	numIndices := 6;
    
    	numberVertices := numVertices;
    
      SetLength(vertices, 4*numVertices );
      for i := 0 to (4*numVertices) - 1 do
        vertices[i]:=xy_vertices[i];
    
      for i := 0 to numVertices-1 do
      begin
    			vertices[i*4+0] := vertices[i*4+0] * halfExtend;
    			vertices[i*4+1] := vertices[i*4+1] * halfExtend;
      end;
    
      SetLength(normals, 3*numVertices);
      for i := 0 to (3*numVertices) - 1 do
        normals[i]:=xy_normals[i];
    
      SetLength(texCoords,2*numVertices);
      for i := 0 to (2*numVertices) - 1 do
        texcoords[i]:=xy_texcoords[i];
    
      SetLength(indices, numIndices);
      for i := 0 to numIndices - 1 do
        indices[i]:=xy_indices[i];
    
    	result := numIndices;
    end;
    
    
    function createCylinder(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    var
      i,j: GLuint;
      //CirclePoints: array of TVector3;
      CIRCLE_RESOLUTION : integer;
      WIDTH_RESOLUTION : integer;
      WIDTH : glFloat;
      totalElements : integer;
      MAX_VERTICIES: integer;
      curidx: integer;
      anglestep: GLFloat;
    begin
    
    //pff now renders somewhat ok
    //TODO: add top and botom look at meshgen sources
    //TODO: vary width of circle over height
    //so stop using circlepoints
    
    RADIUS := RADIUS /2; //why div 2 is that because i define with instead of radious
    
      CIRCLE_RESOLUTION := 35;
      WIDTH_RESOLUTION := 10;
      WIDTH := height/2;
      //setlength(CirclePoints,CIRCLE_RESOLUTION);
      
      MAX_VERTICIES := (CIRCLE_RESOLUTION * WIDTH_RESOLUTION);
      numberVertices := MAX_VERTICIES;
    
       	angleStep := (2.0 * PI) / CIRCLE_RESOLUTION;
    
      // Circle end-caps
      //for i:=0 to CIRCLE_RESOLUTION-1 do
      //begin
      //  circlePoints[i].x := cos( degtorad( (360.0 / CIRCLE_RESOLUTION) * i ) * RADIUS);
      //  circlePoints[i].y := sin( degtorad( (360.0 / CIRCLE_RESOLUTION) * i ) * RADIUS);
      //end;
    
      // Vertices
      setlength(vertices, high(vertices) + (CIRCLE_RESOLUTION * WIDTH_RESOLUTION * 4) );
    
      curidx := 0;
    
      //TODO: swap i and j to make cone? also make vertices normals in one step
    
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        for j:=0 to WIDTH_RESOLUTION-1 do
        begin
    
    
          //vertices[curidx + 0] := radius * sin ( angleStep * i ) * sin ( angleStep * j );
          //vertices[curidx + 0] := cos( degtorad( (360.0 / CIRCLE_RESOLUTION) * i )) * RADIUS;// + circlePoints[i].y;
          vertices[curidx + 0] := cos( ( anglestep * i )) * RADIUS;// + circlePoints[i].y;
    
          vertices[curidx + 1] := (WIDTH*j) / (WIDTH_RESOLUTION);//(WIDTH*2) / (WIDTH_RESOLUTION * j);//circlePoints[i].y;//WIDTH / (WIDTH_RESOLUTION * j);
          //vertices[curidx + 2] := sin( degtorad( (360.0 / CIRCLE_RESOLUTION) * i )) * RADIUS;//WIDTH / (WIDTH_RESOLUTION * j);////circlePoints[i].y*WIDTH_RESOLUTION*j; //i * WIDTH_RESOLUTION+j;
          vertices[curidx + 2] := sin( ( anglestep * i )) * RADIUS;//WIDTH / (WIDTH_RESOLUTION * j);////circlePoints[i].y*WIDTH_RESOLUTION*j; //i * WIDTH_RESOLUTION+j;
    
          vertices[curidx + 3] := 1.0;
    
    
    
          curidx := curidx + 4;
    
    
    
        end;
    
    
        //radius := radius - 0.1; //make an spiral ake tape dispensen when on
    
      end;
    
      // Indices
      totalElements := CIRCLE_RESOLUTION * WIDTH_RESOLUTION * 6;
      setlength(indices, high(indices) + totalElements);
    
      curidx :=0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        for j:=0 to WIDTH_RESOLUTION-1 do
        begin
          indices[curidx+0]:=(i*WIDTH_RESOLUTION + j + 1) mod MAX_VERTICIES;
          indices[curidx+1]:=(i*WIDTH_RESOLUTION + j) mod MAX_VERTICIES;
          indices[curidx+2]:=((i+1) * WIDTH_RESOLUTION + j) mod MAX_VERTICIES;
    
          indices[curidx+3]:=(i*WIDTH_RESOLUTION + j + 1) mod MAX_VERTICIES;
          indices[curidx+4]:=((i+1) * WIDTH_RESOLUTION + j) mod MAX_VERTICIES;
          indices[curidx+5]:=((i+1) * WIDTH_RESOLUTION + j + 1) mod MAX_VERTICIES;
    
          curidx := curidx +6;
        end;
      end;
    
      // Normals
      setlength(normals, high(normals) + CIRCLE_RESOLUTION * WIDTH_RESOLUTION * 3 );
    
      curidx := 0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        for j:=0 to WIDTH_RESOLUTION-1 do
        begin
          //normals[curidx+0] := (radius * sin ( angleStep * i ) * sin ( angleStep * j ))/radius;
          normals[curidx + 0] := cos( ( anglestep * i ));//cos( degtorad( (360.0 / CIRCLE_RESOLUTION) * i ) );// * RADIUS) / radius;
          normals[curidx + 1] := ((j*WIDTH) / WIDTH_RESOLUTION) /radius;
          normals[curidx + 2] := sin( ( anglestep * i ));//sin( degtorad( (360.0 / CIRCLE_RESOLUTION) * i ) );// * RADIUS) / radius;
          curidx := curidx + 3;
        end;
      end;
    
      // TexCoords
      setlength(texcoords, high(texcoords) + (CIRCLE_RESOLUTION * WIDTH_RESOLUTION * 2 ));
      curidx := 0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        for j:=0 to WIDTH_RESOLUTION-1 do
        begin
          texcoords[curidx + 0] := 0;
          texcoords[curidx + 1] := 0;
          curidx := curidx + 2;
        end;
      end;
    
      result := totalElements;
    
    end;
    
    function createDisk(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    var
      i,j: GLuint;
      CIRCLE_RESOLUTION : integer;
      WIDTH_RESOLUTION : integer;
      WIDTH : glFloat;
      totalElements : integer;
      MAX_VERTICIES: integer;
      curidx: integer;
      anglestep: GLFloat;
      temp: integer;
    begin
    
    //stacking is wrong
    
    
    RADIUS := RADIUS /2; //why div 2 is that because i define with instead of radious
    
      CIRCLE_RESOLUTION := 35;
      WIDTH_RESOLUTION := 10;
      WIDTH := height/2;
    
      //WIDTH := 0.5;
    
    
      MAX_VERTICIES := (CIRCLE_RESOLUTION * WIDTH_RESOLUTION);
      numberVertices := MAX_VERTICIES;
    
       	angleStep := (2.0 * PI) / CIRCLE_RESOLUTION;
    
    
      // Vertices
      curidx := high(vertices);
      setlength(vertices, high(vertices) + (CIRCLE_RESOLUTION * 4) + (4) );
    
      //curidx := 0;
    
      //center point begin close
      vertices[curidx + 0] := 0.0;
      vertices[curidx + 1] := 1.0 * width;
      vertices[curidx + 2] := 0.0;
      vertices[curidx + 3] := 1.0;
      curidx := curidx + 4;
    
      j:=0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
        begin
            vertices[curidx + 0] := cos( ( anglestep * i )) * RADIUS;
            vertices[curidx + 1] := 1.0 * width;
            vertices[curidx + 2] := sin( ( anglestep * i )) * RADIUS;
            vertices[curidx + 3] := 1.0;
            curidx := curidx + 4;
      end;
    
      //Indices
      totalElements := (CIRCLE_RESOLUTION * 3);
    
      curidx := high(indices);
      temp := curidx;
      setlength(indices, high(indices) + totalElements);
    
      //curidx :=0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        Indices[(curidx)+2]:=temp;//0;
        Indices[(curidx)+1]:=temp+(i+1);
        if (i = CIRCLE_RESOLUTION-1) then
          Indices[(curidx)+0]:=temp+1 //1
        else
          Indices[(curidx)+0]:=temp+(i+2);
    
        curidx := curidx + 3;
      end;
    
      // Normals
      curidx :=high(normals);
      setlength(normals, high(normals) + (CIRCLE_RESOLUTION * 3) + (3) );
    
      //curidx := 0;
    
      normals[curidx + 0] := 0.0;
      normals[curidx + 1] := 1.0;
      normals[curidx + 2] := 0.0;
    
      curidx := curidx + 3;
    
      j:=0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        normals[curidx + 0] := 0;
        normals[curidx + 1] := 1;
        normals[curidx + 2] := 0;
        curidx := curidx + 3;
      end;
    
      // TexCoords
      curidx := high(texcoords);
      setlength(texcoords, high(texcoords) + ( CIRCLE_RESOLUTION * 2) );
      //curidx := 0;
      j:=0;
      for i:=0 to CIRCLE_RESOLUTION-1 do
      begin
        texcoords[curidx + 0] := 0;
        texcoords[curidx + 1] := 0;
        curidx := curidx + 2;
      end;
    
      result := totalElements;
    
    end;
    
    function createClosedCylinder(radius: GLFloat; height: GLFloat; var vertices: GLBufferf;var normals: GLbufferf; var texCoords: GLbufferf; var indices: GLBufferi;var numberVertices: GLuint): GLuint;
    var
      total, numofvert: GLUint;
    begin
    setlength(vertices,1);
    setlength(normals,1);
    setlength(texCoords,1);
    setlength(indices,1);
    
      total := createCylinder(radius, height, vertices, normals, texCoords, indices,numberVertices);
      numofvert := numberVertices;
      total := total + createDisk(radius, height, vertices, normals, texCoords, indices,numberVertices);
      numberVertices := numberVertices + numofvert;
    end;
    
    end.
    Drawing an open cylinder works, drawing an disk works, but combining them give lots of unexpected results. The calling of creatdisk is broken in this example it is not intendended to be called on its own, only as part createclosedcylinder.
    http://3das.noeska.com - create adventure games without programming

  8. #8
    The result of function createClosedCylinder() seems to be undefined... Didn't compiler warn about it?

  9. #9
    Quote Originally Posted by code_glitch View Post
    Hey there vgo - that is some mighty good code you've got there if I may say so myself. Would you mind awfully if I included this in Prometheus and added your name to the credits? This is non-commercial use, just so you know.
    Sure, I'm glad the code is useful for someone.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •