Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 23:51

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Do Jun 14, 2007 13:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Hello,

I'm thinking about drawing a sphere, but having each face of the sphere being a square (or stretched quad). Milkshape 3D appears to do this when you create a Sphere, but then turns the faces into triangles when you let go of the mouse). Then I would like to be able to apply textures to each square face of that sphere. I can draw a sphere pretty easily with gluSphere, but I'm sure that there are other ways, although I guess normally the faces would then be composed of triangles as opposed to quads... I know all quads are composed of triangles, but I want to be able to say - this square face has this texture applied to it.

Is it possible to have a sphere made up of, say, 200 square faces (stretched to not be exactly square if necessary, what I really mean is quads I guess) that each can then be individually textured? I'm not too hot on all the maths behind this kind of stuff so will accept if what I'm asking sounds strange... I'd also probably need leading through this or pointing to an example.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 14:53 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Made some progress without using gluSphere, I cribbed the following in C++ off the Internet and converted it to Delphi. With this, I get a good sphere - especially using Precision of around 60... it is also being texture mapped but not how I am wanting. I have left two lines below commented out, where I thought I was binding to the appropriate texture for a face on the sphere. If I uncomment the first glBindTexture I get different images across each row (stack?) of the sphere, i.e. it looks like horizontal rings. If I uncomment the second glBindTexture then I just end up with the whole sphere being texture mapped with one image.

Is it going to be relatively simple to get the images in my Images array plastered all over each individual face of this sphere made up of QUAD_STRIPs or am I going down the wrong path?

Code:
  1. procedure TfrmMain.Sphere ( X, Y, Z : GLFloat; Radius, Precision : Integer
  2.                           );
  3. const
  4.   Pi = 3.141592654;
  5.   TwoPi = 6.283185308;
  6.   PiD2 = Pi / 2;
  7. var
  8.   Loop1, Loop2 : Integer;
  9.   Theta1, Theta2, Theta3 : Double;
  10.   X1, Y1, Z1, X2, Y2, Z2 : GLFloat;
  11. begin
  12.   for Loop1 := 0 to Precision div 2 do
  13.   begin
  14.     Theta1 := Loop1 * TwoPi / Precision - PiD2;
  15.     Theta2 := (Loop1 + 1) * TwoPi / Precision - PiD2;
  16.  
  17.     //glBindTexture (GL_TEXTURE_2D,Images[Loop1]);
  18.     glBegin (GL_QUAD_STRIP);
  19.       for Loop2 := 0 to Precision do
  20.       begin
  21.         //glBindTexture (GL_TEXTURE_2D,Images[Loop1]);
  22.         Theta3 := Loop2 * TwoPi / Precision;
  23.  
  24.         X1 := Cos (Theta2) * Cos (Theta3);
  25.         Y1 := Sin (Theta2);
  26.         Z1 := Cos (Theta2) * Sin (Theta3);
  27.  
  28.         X2 := X + Radius * X1;
  29.         Y2 := Y + Radius * Y1;
  30.         Z2 := Z + Radius * Z1;
  31.  
  32.         glNormal3f (X1,Y1,Z1);
  33.         glTexCoord2f (Loop2 / Precision,2 * (Loop1 + 1) / Precision);
  34.         glVertex3f (X2,Y2,Z2);
  35.  
  36.         X1 := Cos (Theta1) * Cos (Theta3);
  37.         Y1 := Sin (Theta1);
  38.         Z1 := Cos (Theta1) * Sin (Theta3);
  39.  
  40.         X2 := X + Radius * X1;
  41.         Y2 := Y + Radius * Y1;
  42.         Z2 := Z + Radius * Z1;
  43.  
  44.         glNormal3f (X1,Y1,Z1);
  45.         glTexCoord2f (Loop2 / Precision,2 * Loop1 / Precision);
  46.         glVertex3f (X2,Y2,Z2);
  47.       end;
  48.     glEnd;
  49.   end;
  50. end;
I would love to understand this a bit better, but for now I just know it produces me the sphere I want. Now I just need to texture each face. Any assistance greatly appreciated.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 15:42 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
The second glBindTextures is wrong. You can't bind an texture in an glBegin glEnd block. That dosn't work. But the position of the glBindTextures is right. Later more.

An quad strip looks like this. And the algorithm use this special way to draw to sphere. If you can see on the image the strip saves the vertex 3 and 4 for the next quads. If you want to split an strip into quads you must hold the vertex 3 ad 4 by yourself. Here some pseudocode.

Code:
  1. var
  2.   vertex: array[1..4] of record   // or create an own type for it
  3.     x, y, z: GLFloat;
  4.   end;
  5. for Loop1 := 0 to Precision div 2 do begin
  6.  
  7.   // calculate vertex 1 and 2 into fields vertex[1] and [2]
  8.   // for Loop2 you must use zero
  9.  
  10.   // important. Loop2 must start at 1 because first degree has allready been calculated
  11.   for Loop2 := 1 to Precision do begin
  12.     // calculate vertex 3 and 4 into fields vertex[3] and [4]
  13.  
  14.     glBindTexture
  15.     glBegin(GL_QUADS);
  16.       // Draw your points with you calculated value. vertex[1], [2], [3] and [4]
  17.       // but texture coordinates must be in range from 0 to 1.
  18.       // the coords from the code won't work because they use
  19.       // only an small rect from the texture.
  20.     glEnd;
  21.  
  22.     // store vertex[3] in [1]  // vertex[1] := vertex[3] should work
  23.     // store vertex[4] in [2]
  24.   end
  25. end;


That should be all what you have to do.

PS: you should store your normals too. Same way like vertex. But if you don't need light/normals you could ignore them.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 15:44 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
EDIT: I'd typed this response before seeing the entry above; I will have a read of this and see where I get.

OK, trying a simple example with GL_QUAD_STRIPs has led me to the conclusion that I can't change textures in the middle of doing glBegin (GL_QUAD_STRIP) - basic error I should've known about I guess. I'm coming round to the view that this sphere I have, that is created with GL_QUAD_STRIP can't have different textures applied to each face - it can only have them for every call to glBegin (GL_QUAD_STRIP) which appears to be called for each row of the sphere.

My simple example, each texture in the Images array is different but they don't take in the QUAD_STRIP because a GL_INVALID_OPERATION is probably being raised by the call to glBindTexture.

Code:
  1.   glBegin (GL_QUAD_STRIP);
  2.     glBindTexture (GL_TEXTURE_2D,Images[0]);
  3.     { 0: Bottom-left... }
  4.     glTexCoord2f (0,0);
  5.     glVertex3f (0,0,0);
  6.     { 1: Top-left... }
  7.     glTexCoord2f (0,1);
  8.     glVertex3f (0,1,0);
  9.     { 2: Bottom-right... }
  10.     glTexCoord2f (1,0);
  11.     glVertex3f (1,0,0);
  12.     { 3: Top-right... }
  13.     glTexCoord2f (1,1);
  14.     glVertex3f (1,1,0);
  15.  
  16.     glBindTexture (GL_TEXTURE_2D,Images[1]);
  17.     { 5... }
  18.     glTexCoord2f (2,0);
  19.     glVertex3f (2,0,0);
  20.  
  21.     { 6... }
  22.     glTexCoord2f (2,1);
  23.     glVertex3f (2,1,0);
  24.  
  25.     glBindTexture (GL_TEXTURE_2D,Images[2]);
  26.     { 7... }
  27.     glTexCoord2f (3,0);
  28.     glVertex3f (3,0,0);
  29.  
  30.     { 8... }
  31.     glTexCoord2f (3,1);
  32.     glVertex3f (3,1,0);
  33.   glEnd;
So... the question is - can I easily set up my sphere so it is made up of GL_QUADs instead and then can I apply a different texture to each face?

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 15:58 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
An information for later. Between glBegin and glEnd you only can set vertex, color, normal, textcoords, fog coords or some like this. But all other isn't allowed in this block.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 16:41 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
What you say makes good sense to me... 1) have a loop for the stacks, 2) have another loop for the slices, 3) define quads inside this loop and 4) apply textures to each quad then 5) save 2 of the vertexes for the next quad. However, I will admit that I am a bit lost as to how to actually go about calculating my quad vertices - is it very different from how it was done with the quad_strips in the Sphere procedure? I'm not well versed in basic 3D maths I'm afraid.

If I had written my Sphere procedure and understood the maths I'd be OK but I did just lift it from some C++ place off the Internet... I had originally hoped that I could use the GLU library for my sphere and apply textures to it by passing in an array of textures or something. The maths behind creating a sphere are not all that interesting to me to be honest, but kinda necessary for me to progress with what I want to do I guess.

Any additional pointers / assistance on how to create a sphere with GL_QUADS really appreciated.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 14, 2007 21:09 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
I try an explanation of your above sphere code by showing a picture. I am not quite sure if that is correct because I need only two angles (maybe somebody is willing to give a comment?).

I have a point P on a sphere surface and want to know its 3D-coordinates, so I need an input of two angles, Theta1 and Theta2 (the sphere has the radius 1, the three axes X,Y,Z are the same as in OpenGL).

If you take Px=cos Theta1, Py=0 and Pz= sin Theta1 you get P1.

But if we want to have ANY point on the surface, Px and Pz should be multiplied by cos Theta2 (to shorten them) to get P2. The Y-coordinate is simply sin Theta2:






EDIT: Sigh, there was a mistake in the picture concerning Theta1. The actual one should be correct.


Dateianhänge:
Point-On-Shpere.jpg
Point-On-Shpere.jpg [ 60.27 KiB | 8560-mal betrachtet ]
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 15, 2007 10:14 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Well, that was quite interesting... so I thank you for that, but I won't pretend that I understand it all, yet. I'm really looking for utility code to create me a sphere using GL_QUADS instead of GL_QUAD_STRIP - then I can do what I want with that sphere's quads, i.e. attach a texture to each quad, which I cannot do with GL_QUAD_STRIP for obvious reasons. The mechanics and mathematics of sphere building are a little beyond me at this moment in time and my main focus is on adding value to my project; rather than learning all this 3D maths; that I probably should've learned years ago!

Will the Sphere procedure using GL_QUAD_STRIP be easy to convert to one using GL_QUADS like Lossy Ex suggested? I did try making changes along the lines that he suggested, but I got into a bit of a mess to be honest - it certainly didn't work; of course, I'm 100% sure that this is my fault - not Lossy Ex's guidance (that all makes sense to me) - but I just need that bit of extra help getting past this hurdle of making it work... help in the form of code guidance as opposed to 3D maths understanding.

If anyone can help, as I say, I'd be very appreciative - you guys on this forum have helped me tons so far but I understand if there are some things people think I really should persevere with. Regardless, HMusicCentre is coming along very strong in OpenGL - it's looking much, much better than the old GDI-based version anyway.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 15, 2007 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
I have it. Well, I have something that works and something that I'm pleased with... considering I thought I was stuck earlier.

The code I've produced is a bit different, but is following the same principle. Firstly, I calculate all the Vertices I will need for the Sphere and store them in an array, along with the Normals. For this, I use:

Code:
  1. procedure TfrmMain.CalculateVertices ( X, Y, Z : GLFloat;
  2.                                        Radius, Precision : Integer
  3.                                      );
  4. const
  5.   Pi = 3.141592654;
  6.   TwoPi = 6.283185308;
  7.   PiD2 = Pi / 2;
  8. var
  9.   Loop1, Loop2, Index : Integer;
  10.   Theta1, Theta2, Theta3 : Double;
  11.   X1, Y1, Z1, X2, Y2, Z2 : GLFloat;
  12. begin
  13.   Index := 0;
  14.   for Loop1 := 0 to Precision div 2 do
  15.   begin
  16.     Theta1 := Loop1 * TwoPi / Precision - PiD2;
  17.     Theta2 := (Loop1 + 1) * TwoPi / Precision - PiD2;
  18.  
  19.     for Loop2 := 0 to Precision do
  20.     begin
  21.       Theta3 := Loop2 * TwoPi / Precision;
  22.  
  23.       X1 := Cos (Theta2) * Cos (Theta3);
  24.       Y1 := Sin (Theta2);
  25.       Z1 := Cos (Theta2) * Sin (Theta3);
  26.  
  27.       X2 := X + Radius * X1;
  28.       Y2 := Y + Radius * Y1;
  29.       Z2 := Z + Radius * Z1;
  30.  
  31.       Vertices[Index].X := X2;
  32.       Vertices[Index].Y := Y2;
  33.       Vertices[Index].Z := Z2;
  34.       Vertices[Index].NX := X1;
  35.       Vertices[Index].NY := Y1;
  36.       Vertices[Index].NZ := Z1;
  37.       Inc (Index);
  38.  
  39.       X1 := Cos (Theta1) * Cos (Theta3);
  40.       Y1 := Sin (Theta1);
  41.       Z1 := Cos (Theta1) * Sin (Theta3);
  42.  
  43.       X2 := X + Radius * X1;
  44.       Y2 := Y + Radius * Y1;
  45.       Z2 := Z + Radius * Z1;
  46.  
  47.       Vertices[Index].X := X2;
  48.       Vertices[Index].Y := Y2;
  49.       Vertices[Index].Z := Z2;
  50.       Vertices[Index].NX := X1;
  51.       Vertices[Index].NY := Y1;
  52.       Vertices[Index].NZ := Z1;
  53.       Inc (Index);
  54.     end;
  55.   end;
  56.   FacesForSphere := Index div 2;
  57. end;
Then, in my Draw routine, I call:

Code:
  1. procedure TfrmMain.DrawSphereFromArray;
  2. var
  3.   Loop, Face : Integer;
  4. begin
  5.   Loop := 0;
  6.   for Face := 0 to FacesForSphere - 1 do
  7.   begin
  8.     glBindTexture (GL_TEXTURE_2D,CoverImages[Face]);
  9.     glBegin (GL_QUADS);
  10.       glNormal3f (Vertices[Loop].NX,Vertices[Loop].NY,Vertices[Loop].NZ);
  11.       glTexCoord2f (1,1);
  12.       glVertex3f (Vertices[Loop].X,Vertices[Loop].Y,Vertices[Loop].Z);
  13.  
  14.       glNormal3f (Vertices[Loop + 1].NX,Vertices[Loop + 1].NY,Vertices[Loop + 1].NZ);
  15.       glTexCoord2f (1,0);
  16.       glVertex3f (Vertices[Loop + 1].X,Vertices[Loop + 1].Y,Vertices[Loop + 1].Z);
  17.  
  18.       glNormal3f (Vertices[Loop + 3].NX,Vertices[Loop + 3].NY,Vertices[Loop + 3].NZ);
  19.       glTexCoord2f (0,0);
  20.       glVertex3f (Vertices[Loop + 3].X,Vertices[Loop + 3].Y,Vertices[Loop + 3].Z);
  21.  
  22.       glNormal3f (Vertices[Loop + 2].NX,Vertices[Loop + 2].NY,Vertices[Loop + 2].NZ);
  23.       glTexCoord2f (0,1);
  24.       glVertex3f (Vertices[Loop + 2].X,Vertices[Loop + 2].Y,Vertices[Loop + 2].Z);
  25.     glEnd;
  26.     Loop := Loop + 2;
  27.   end;
  28. end;
...and I end up with this... yum-yum...

Bild

I'm not sure if the code I have produced is very efficient - I'm just happy that it works - so I thought I'd post it up here so people could comment on it, or maybe even learn from it themselves... there certainly doesn't seem to be much on the Internet about creating spheres with GL_QUADS, I guess 'cos it's the most inefficient when compared to GL_QUAD_STRIP and maybe even GL_TRIANGLES.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 15, 2007 19:46 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Congratulations! I am just busy preparing sphere quad code in the meantime because I thought if you were very desparate I could provide something. Yet finding an own solution is the really optimal way. :wink:
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jun 16, 2007 12:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
What I did notice, which alarmed me at first, but is normal and expected I guess, is that when my program loads in all the textures for the Sphere on startup it uses over 120mb of RAM according to Task Manager. Quite an expensive effect.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Foren-Übersicht » English » English Programming Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 17 Queries | GZIP : On ]