Creating a cube from triangles
BlitzMax Forums/OpenGL Module/Creating a cube from triangles
| ||
I'm trying to create a cube using triangles. 1: I created a front and back face but they seem to connect to eachoter creating another triangle? 2: For a cube with one texture, is 8 vertexes enough? 3: For a cube with a different texture for each face, i need 4 vertexes for each face? 4: How many vertexes do i need for a cube with correct lightning? |
| ||
I'm surprised no one has answered already :P maybe the GL pros are away for the weekend :D I'm more of a DirectX guy instead of GL but here are some things I'd look for :- 1: How are you drawing the triangles? each triangle separate with individual vertex data? index and vertex data? How are rendering - GL_TRIANGLES or GL_TRIANGLE_STRIP or other? 2: Kind of, but you may find some faces may be upside down, or reversed left to right 3: Yes, if using indices, otherwise 6 to define 2 Tris. Also you'll need UV data for each vertex. 4: The same as for 3, depending if you're using just vertex data or vertex and index data. Either way you'll need more information for each vertex - Normal Vector. |
| ||
There are many different ways to draw a cube in openGL. - if using the immediate state glBegin()/glEnd(), you can use quads, triangles, triangle strips (beginners start here, i'm assuming you are starting here) - if using the buffer method (vbo), then sending an array of vertices to the glDrawElements() My advice would be to first create a Function() that creates a square or "quad", then rotate that quad in your app. Then you can see how a basic "quad" is built and how it works, how it lights, and how it is textured. Then you can use that function to accept x,y,z for positioning, size, and order (order is important for determining face direction) and you'll see how to create your own cube from that. Once you do that it should answer all your questions, since a cube is just six squares pointing in different directions. Last edited 2011 |
| ||
I was drawing all triangles at once, drawing each one seperate seems to work. But now i need 36 vertexes for a cube, wich seems allot. I'm using GL_TRIANGLES. I dont know what you mean with indices, index and vertex data. What i do is create a mesh type with a list of surfaces, each surface has a vertex and a triangle list. A vertex type stores position,color,uv and normals. A triangle type points to 3 vertexes. I draw the 3 vertexes for each triangle. |
| ||
As it seems that you're a beginner, I'd advise you to go all through the Nehe Tutorials over at gamedev.net :P They are on the right hand side of this page ( under Legacy Tutorials ) :- http://nehe.gamedev.net/ |
| ||
That obvious :p I'm reading the red book and started playing to soon. Is the red book a good start for a beginner or should i look at the Nehe Tutorials first? |
| ||
Both are good but I found Nehe to be more complete. The red book is good but I found it better for reference. 36 vertices is correct-- remember, if you are drawing PER TRIANGLE and not by an indices list, then you will be repeating vertices. 6 quads * 2 triangles per quad * 3 vertices per triangle = 36. If you're creating classes and trying to create an engine, I'd advise learning about glDrawElements: http://www.songho.ca/opengl/gl_vertexarray.html |
| ||
I read about gl arays last night, if i understand correctly vertices can be shared. Had a quick look at the link, verry interesting, especialy using buffers to speed things up. Going to play with those arays first and learn about buffers and display lists. Thx for the advise! |
| ||
I got glArrayElement() working but can't get glDrawElements() to work. Here is a test app to show what i'm doing. Last edited 2011 |
| ||
I think I had problems with glDrawElements using GL_INT, too. Try using GL_UNSIGNED_SHORT, and remember you will have to cast your array differently (Global indices:Short[]). OH! NOTE: I see you've place glbegin() glend()-- you DO NOT use these when using glDrawElements. glDrawElements is your drawing command. |
| ||
It works now :), thx. Also added added normal and texture coords arrays. |
| ||
A bit late for the party, but I wrote this a good few years ago:- [bbcode] Type vector Field x:Float Field y:Float Field z:Float Field xp:Float Field yp:Float End Type Type Triangle Field p1:Long Field p2:Long Field p3:Long Field dotProduct:Float End Type Global P:vector[9] 'We need eight vectors and 12 triangles, but adding Global T:Triangle[13] 'But I'm adding one more so we can index them them 'from 1, instead of 0... Just to ease readibility. For loop = 0 To 12 If loop< 9 P[loop] = New vector End If T[loop] = New Triangle Next Const CULL_BACK_FACES = True Const PERSPECTIVE_MODE = True Global Offset:Float = 300 Global turnRate:Float = 1 Global pointOfView:Float Init(200) Graphics 800,600 Repeat Cls If KeyDown(KEY_LEFT) RotateCubeZ(-turnRate) End If If KeyDown(KEY_RIGHT) RotateCubeZ(turnRate) End If If KeyDown(KEY_UP) RotateCubeX(-turnRate) End If If KeyDown(KEY_DOWN) RotateCubeX(turnRate) End If If KeyDown(KEY_S) RotateCubeY(-turnRate) End If If KeyDown(KEY_A) RotateCubeY(turnRate) End If If CULL_BACK_FACES = True CullBackFaces() End If If PERSPECTIVE_MODE = True CalculatevectorProjections() End If DrawCube() Flip(1) Until KeyDown(KEY_ESCAPE) Function CullBackFaces() Local loop:Int For loop = 1 To 12 CalculateCrossProduct(loop) T[loop].dotProduct = CalculateDotProduct() Next End Function Function CalculatevectorProjections() Local loop:Int For loop = 1 To 8 P[loop].xp = P[loop].X * pointOfView / (pointOfView + P[loop].Z) + Offset P[loop].yp = P[loop].Y * pointOfView / (pointOfView + P[loop].Z) + Offset Next End Function Function CalculateCrossProduct(triangleIndex:Long) Local x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float x1 = P[T[triangleIndex].p2].X - P[T[triangleIndex].p1].X y1 = P[T[triangleIndex].p2].Y - P[T[triangleIndex].p1].Y z1 = P[T[triangleIndex].p2].Z - P[T[triangleIndex].p1].Z x2 = P[T[triangleIndex].p3].X - P[T[triangleIndex].p1].X y2 = P[T[triangleIndex].p3].Y - P[T[triangleIndex].p1].Y z2 = P[T[triangleIndex].p3].Z - P[T[triangleIndex].p1].Z P[0].X = y1 * z2 - y2 * z1 P[0].Y = x2 * z1 - x1 * z2 P[0].Z = x1 * y2 - x2 * y1 End Function Function CalculateDotProduct:Float() Return(0 * P(0).X + 0 * P(0).Y + (pointOfView * P(0).Z)) End Function Function RotateCubeX(angle:Float) Local NewY:Float, NewZ:Float,loop:Int For loop = 1 To 8 NewY = P[loop].Y * Cos(angle) - P[loop].Z * Sin(angle) NewZ = P[loop].Y * Sin(angle) + P[loop].Z * Cos(angle) P[loop].Y = NewY P[loop].Z = NewZ Next End Function Function RotateCubeZ(angle:Float) Local newX:Float,newY:Float,loop:Int For loop = 1 To 8 NewX = P[loop].X * Cos(angle) - P[loop].Y * Sin(angle) NewY = P[loop].X * Sin(angle) + P[loop].Y * Cos(angle) P[loop].X = NewX P[loop].Y = NewY Next End Function Function RotateCubeY(angle:Float) Local loop:Int,NewX:Float, NewZ:Float For loop = 1 To 8 NewX = P[loop].Z * Sin(angle) + P[loop].X * Cos(angle) NewZ = P[loop].Z * Cos(angle) - P[loop].X * Sin(angle) P[loop].X = NewX P[loop].Z = NewZ Next End Function Function DrawCube() Local loop:Int, draw:Byte If CULL_BACK_FACES = True Then draw = True For loop = 1 To 12 If (draw = True And T[loop].dotProduct > 0.5) Or draw = False DrawColouredLine(T(loop).p1,T(loop).p2) DrawColouredLine(T(loop).p2,T(loop).p3) DrawColouredLine(T(loop).p3,T(loop).p1) End If Next End Function Function Init(size:Float) If CULL_BACK_FACES = False pointOfView = 1000 Else pointOfView = 5000 End If P[1].x = -size; P[1].y = -size; P[1].z = -size P[2].x = -size; P[2].y = size; P[2].z = -size P[3].x = size; P[3].y = size; P[3].z = -size P[4].x = size; P[4].y = -size; P[4].z = -size P[5].x = -size; P[5].y = -size; P[5].z = size P[6].x = -size; P[6].y = size; P[6].z = size P[7].x = size; P[7].y = size; P[7].z = size P[8].x = size; P[8].y = -size; P[8].z = size T[1].p1 = 1; T[1].p2 = 4; T[1].p3 = 3 T[2].p1 = 1; T[2].p2 = 3; T[2].p3 = 2 T[3].p1 = 5; T[3].p2 = 1; T[3].p3 = 2 T[4].p1 = 5; T[4].p2 = 2; T[4].p3 = 6 T[5].p1 = 8; T[5].p2 = 5; T[5].p3 = 6 T[6].p1 = 8; T[6].p2 = 6; T[6].p3 = 7 T[7].p1 = 4; T[7].p2 = 8; T[7].p3 = 7 T[8].p1 = 4; T[8].p2 = 7; T[8].p3 = 3 T[9].p1 = 3; T[9].p2 = 7; T[9].p3 = 6 T[10].p1 = 3; T[10].p2 = 6; T[10].p3 = 2 T[11].p1 = 4; T[11].p2 = 1; T[11].p3 = 5 T[12].p1 = 4; T[12].p2 = 5; T[12].p3 = 8 End Function Function DrawColouredLine(p1:Long,p2:Long,r:Byte =255,g:Byte = 255,b:Byte = 255) Local x1:Float, y1:Float,x2:Float,y2:Float If PERSPECTIVE_MODE = True x1 = P[p1].X * pointOfView / (pointOfView + P[p1].Z) + Offset y1 = P[p1].Y * pointOfView / (pointOfView + P[p1].Z) + Offset x2 = P[p2].X * pointOfView / (pointOfView + P[p2].Z) + Offset y2 = P[p2].Y * pointOfView / (pointOfView + P[p2].Z) + Offset Else x1 = P(p1).x + offset y1 = P(p1).y + offset x2 = P(p2).x + offset y2 = P(p2).y + offset End If SetColor r,g,b DrawLine x1,y1,x2,y2 SetColor 255,255,255 End Function [/bbcode] Just for anyone who's passing and might be interested, back fall culling is a bit 'meh', but overall, it looks nice! :D Check code for controls. Dabz |