opengl 球体顶点坐标

合集下载

opengles 顶点理解

opengles 顶点理解

opengles 顶点理解摘要:1.简介2.OpenGL ES 顶点概念3.顶点属性4.顶点数组5.顶点缓冲对象6.总结正文:OpenGL ES(OpenGL for Embedded Systems)是一种为嵌入式系统设计的图形编程接口。

在OpenGL ES中,顶点是图形渲染的基本单元,负责描述物体的形状和纹理。

本文将详细介绍OpenGL ES顶点的相关知识。

2.OpenGL ES 顶点概念在OpenGL ES中,顶点(Vertex)是一个抽象的概念,它代表了一个三维空间中的点。

顶点可以是实心的,也可以是空心的,甚至可以是一个平面。

为了更好地表示顶点,我们需要为其定义一些属性。

3.顶点属性顶点属性(Vertex Attribute)是用来描述顶点特征的数据。

在OpenGL ES中,每个顶点可以包含以下属性:- 位置(Position):顶点在三维空间中的坐标。

- 颜色(Color):顶点的颜色,通常用RGBA表示。

- 纹理坐标(Texture Coordinate):顶点在纹理上的坐标。

- 法向量(Normal):顶点所在平面的法向量。

- 其他属性:根据实际需求,还可以定义其他属性,如顶点ID、权重等。

4.顶点数组顶点数组(Vertex Array)是一种数据结构,用于存储顶点属性的数据。

OpenGL ES提供了两种顶点数组:- 顶点数组对象(Vertex Array Object,VAO):是一个高级的顶点数组,可以保存顶点数组的状态,如顶点数组渲染属性等。

- 顶点数组缓冲(Vertex Array Buffer,VAB):是一个低级的顶点数组,用于存储顶点属性数据。

5.顶点缓冲对象顶点缓冲对象(Vertex Buffer Object,VBO)是一种用于存储顶点数据的数据结构。

VBO可以用于存储顶点数组、顶点数组缓冲和其他类型的顶点数据。

通过使用VBO,可以提高渲染性能,并减轻CPU的负担。

OpenGL坐标系统

OpenGL坐标系统

OpenGL坐标系统⼀、坐标系统概述本⽂类容见。

直接copy过来留个存档。

OpenGL希望每次顶点着⾊后,我们的可见顶点都为标准化设备坐标(Normalized Device Coordinate,NDC)。

也就是说每个顶点的z,y,z 都应该在−1到1之间,超出这个范围的顶点将是不可见的。

通常情况下我们会⾃⼰设定⼀个坐标范围,之后再在顶点着⾊器中将这些坐标变换为表转化设备坐标。

然后这些标化设备坐标传⼊光栅器(Rasterizer),将它们变换为屏幕上的⼆维坐标和像素。

将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进⾏的,也就是类似于流⽔线那样⼦。

在流⽔线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系统(Coordinate System)。

将物体的坐标变换到⼏个过渡坐标系(Intermediate Coordinate System)的优点在于,在这些特定的坐标系统中,⼀些操作或运算更加⽅便和容易,这⼀点很快就会变得很明显。

对我们来说⽐较重要的总共有5个不同的坐标系统局部空间(Local Space,或者称为物体空间(Object Space))世界空间(World Space)观察空间(View Space,或者称为视觉空间(Eye Space))裁剪空间(Clip Space)屏幕空间(Screen Space)这就是⼀个顶点在最终被转化为⽚段之前需要经历的所有不同状态。

为了将坐标从⼀个坐标系变换到另⼀个坐标系,我们需要⽤到⼏个变换矩阵,最重要的⼏个分别是模型(Model)、观察(View)、投影(Projection)三个矩阵。

物体顶点的起始坐标再局部空间(Local Space),这⾥称它为局部坐标(Local Coordinate),它在之后会变成世界坐标(world Coordinate),观测坐标(View Coordinate),裁剪坐标(Clip Coordinate),并最后以屏幕坐标(Screen Corrdinate)的形式结束。

opengl学习脚印opengl坐标变换

opengl学习脚印opengl坐标变换

OpenGL学习脚印OpenGL 坐标变换OpenGL学习脚印: OpenGL 坐标变换写在前面本节内容翻译和整理自http://www.songho.ca songho的博客《OpenGL Transformation》内容,以供自己和初学者熟悉OpenGL中坐标变换的整个过程。

通过本节,你可以了解到:OpenGL坐标变换过程理解OpenGL矩阵计算概览几何数据例如顶点位置和法向量在光栅化操作之前,都要通过Vertex Operation 和Primitive Assembly OpenGL流水线操作(在OpenGL pipeline节描述)。

OpenGL 顶点变换Object Coordinates(对象坐标系或模型坐标系)这是对象的局部坐标系统,是对象在被应用任何变换之前的初始位置和方向所在的坐标系。

要对对象实行变换,可以使用glRotatef(), glTranslatef(), glScalef()等函数。

Eye Coordinates(眼坐标系或照相机坐标系)由GL_MODELVIEW矩阵和模型坐标系中坐标相乘的结果。

在OpenGL中使用GL_MODELVIEW矩阵来使对象从模型坐标系转换到眼坐标系。

GL_MODELVIEW矩阵是模型变换和视变换矩阵的组合(Mview*Mmodel)。

模型变换从对象坐标系转换到世界坐标系,而视变换从世界坐标系转换到眼坐标系。

注意:OpenGL中并没有单独的视变换矩阵。

因此,要想模拟变换照相机或者进行视变换,那么场景(3D对象和光照)必须以视变换矩阵的逆矩阵进行变换。

换言之,OpenGL将照相机定义在位于眼坐标系下朝向-Z轴,位于点(0,0,0)的位置,而不能进行变换。

法向量同样从对象坐标系变换到眼坐标系来用于光照计算。

注意:法向量的转换方式和顶点不同。

它用法向量乘以GL_MODELVIEW矩阵的逆矩阵的转置矩阵。

请参考Normal Vector Transformation获取更多细节。

OpenGL课程设计-三维球体的实现

OpenGL课程设计-三维球体的实现

游戏软件设计课程报告(三维球体的实现)院系:专业:学号:姓名:指导教师:2010年10月10日目录目录一、应用程序的最终界面----------------------------------------------------------------1二、三维球体的绘制---------------------------------------------------------------------21、球体绘制方法研究 ----------------------------------------------------------------22、面分解法的实现----------------------------------------------------------------32.1面分解函数 ----------------------------------------------------------------32.2初值的选取 ----------------------------------------------------------------32.3 球体的实现----------------------------------------------------------------43、三角形绘制函数----------------------------------------------------------------44、三角面法向量函数 ----------------------------------------------------------------55、点的模长扩展函数 ----------------------------------------------------------------56、南北极法的实现----------------------------------------------------------------57、动画的实现-------------------------------------------------------------------10三、二种绘制方法的比较---------------------------------------------------------------12一、应用程序的最终界面一、应用程序的最终界面本OpenGL应用程序的最终界面主要由二部分构成,其一是参数控制栏,其二是视图显示窗。

OpenGL顶点数组

OpenGL顶点数组

OpenGL顶点数组概述作为在⽴即模式(glBegin()与glEnd()之间)下指定单个顶点数据的替代,你可以保存顶点数据在⼀组列表中,包括顶点位置、法线、纹理坐标与颜⾊信息。

并且你可以通过索引数组解引⽤数组元素绘制选定的⼏何图元。

看看下⾯的⽤⽴即模式绘制⽴⽅体的代码。

glBegin(GL_TRIANGLES); // draw a cube with 12 triangles// 前⾯ =================glVertex3fv(v0); // v0-v1-v2glVertex3fv(v1);glVertex3fv(v2);glVertex3fv(v2); // v2-v3-v0glVertex3fv(v3);glVertex3fv(v0);// 右⾯ =================glVertex3fv(v0); // v0-v3-v4glVertex3fv(v3);glVertex3fv(v4);glVertex3fv(v4); // v4-v5-v0glVertex3fv(v5);glVertex3fv(v0);// 上⾯ ===================glVertex3fv(v0); // v0-v5-v6glVertex3fv(v5);glVertex3fv(v6);glVertex3fv(v6); // v6-v1-v0glVertex3fv(v1);glVertex3fv(v0);... // 绘制其余3⾯glEnd();为构造每个⾯的2个三⾓形,需要调⽤glVertex*()6次。

例如,正⾯分为v0-v1-v2与v2-v3-v0两个三⾓形。

⼀个⽴⽅体有6个⾯,因此glVertex* ()的调⽤次数为36。

如果你还需为相关顶点指定法线、纹理坐标与颜⾊,这增加对OpenGL函数的调⽤。

另⼀个需要注意的是:顶点“v0”被三个相邻的⾯共⽤:正⾯、右⾯与顶⾯。

opengles 顶点理解 -回复

opengles 顶点理解 -回复

opengles 顶点理解-回复OpenGL ES (Open Graphics Library for Embedded Systems) 是针对嵌入式系统的图形库,主要用于在移动设备和嵌入式平台上进行图形渲染和加速。

在OpenGL ES中,顶点是一种重要的图形元素,通过定义和操作顶点,可以创建出各种形状和效果。

本文将详细介绍OpenGL ES顶点的概念、属性和使用方法。

一、顶点概念在计算机图形学中,顶点是由一组属性(如位置、颜色、纹理坐标等)描述的几何图形的端点。

在OpenGL ES中,每个顶点通常都有一个位置属性,用于指定顶点在三维空间中的坐标。

除了位置属性外,顶点还可以具有其他属性,如颜色属性、纹理坐标属性等。

二、顶点属性顶点属性是指描述顶点特征的数据,它由多个分量组成。

在OpenGL ES 中,常见的顶点属性包括位置属性、颜色属性、法线属性、纹理坐标属性等。

这些属性可以分别存储在单独的顶点缓冲区对象(Vertex Buffer Object,VBO)中,或者打包在一个通用的顶点缓冲区对象中。

1. 位置属性位置属性是描述顶点在三维空间中位置的属性,它通常由三个浮点数分量(x、y、z)组成。

位置属性可以用来确定几何图形的形状和位置,并以此进行坐标变换、投影等操作。

在OpenGL ES中,位置属性通常被指定为顶点着色器的输入。

2. 颜色属性颜色属性是描述顶点颜色的属性,它通常由三个或四个浮点数分量(r、g、b、a)组成。

颜色属性可以用来指定顶点的着色方式,例如实现光照效果、渐变效果等。

在OpenGL ES中,颜色属性通常被指定为顶点着色器的输入。

3. 法线属性法线属性是描述三角形面的法线(即垂直于面的向量)的属性,它通常由三个浮点数分量(x、y、z)组成。

法线属性可以用来计算光照效果、阴影效果等。

在OpenGL ES中,法线属性通常被指定为顶点着色器的输入。

4. 纹理坐标属性纹理坐标属性是描述顶点在纹理图像中位置的属性,它通常由两个浮点数分量(s、t)组成。

Opengl绘制我们的小屋(一)球体,立方体绘制

Opengl绘制我们的小屋(一)球体,立方体绘制

Opengl绘制我们的⼩屋(⼀)球体,⽴⽅体绘制这个系列我想⽤来运⽤opengl红⽪书的前⼋章节的内容,来打造⼀个室内⼩屋.这⼀章主要是定义⼏个基本的结构.并给出球体与⽴⽅体的画法,先让我们来定义⼀些基本的结构.⼀个是包含点,法向量,纹理贴图向量,⼆是矩形与圆形的⽗类,包含⼀些基本公有的处理. 1type T2N3V3 =2struct3val mutable TexCoord : Vector24val mutable Normal : Vector35val mutable Position : Vector36new(v,n,p) = {TexCoord = v;Normal = n;Position = p}7end8 [<AbstractClass>]9type Shape() =10let mutable bCreate = false11let mutable vi = 012let mutable ei = 013let mutable count = 014member this.vboID with get() = vi and set value = vi <- value15member this.eboID with get() = ei and set value = ei <- value16member this.TriangelCount with get() = count and set value = count <- value17member this.IsCreate with get() = bCreate and set value = bCreate <- value18abstract Draw : unit -> unit19abstract Init : unit -> unit20member this.InitQ : unit -> unit =fun () -> ()View Code然后是球体的画法,相关具体过程如上篇,先贴上代码,我会对其中⼀些做些说明.1type Sphere(radius:float32,level:int) =2inherit Shape()3let mutable rad,lev = radius,level4let RightLevel =5if lev < 0then lev <- 06 elif lev > 6then lev <-67override this.Draw() =8if this.IsCreate<>true then this.Init()9 GL.BindBuffer(BufferTarget.ArrayBuffer,this.vboID)10 GL.BindBuffer(BufferTarget.ElementArrayBuffer,this.eboID)11 GL.InterleavedArrays(InterleavedArrayFormat.T2fN3fV3f,0,IntPtr.Zero)12 GL.DrawElements(BeginMode.Triangles,this.TriangelCount,DrawElementsType.UnsignedInt,IntPtr.Zero)13override this.Init() =14let alls = Array.create 6 (new T2N3V3())15 alls.[0] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), Vector3.UnitX, Vector3.UnitX * rad )16 alls.[1] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), Vector3.UnitY, Vector3.UnitY * rad )17 alls.[2] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), Vector3.UnitZ, Vector3.UnitZ * rad )18 alls.[3] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), -Vector3.UnitX, -Vector3.UnitX * rad )19 alls.[4] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), -Vector3.UnitY, -Vector3.UnitY * rad )20 alls.[5] <- new T2N3V3(new Vector2( 0.0f, 0.0f ), -Vector3.UnitZ, -Vector3.UnitZ * rad )21let is = [|221;2;0230;2;4240;4;5255;1;0261;3;2274;2;3284;3;5291;5;330 |]31let (vvv:T2N3V3 []),(iv: int[]) = this.Sub (alls,is)32let mutable vID,eID = 0,033//let mutable tv,vv,pv = vvv |> Array.map (fun v -> v.TexCoord,v.Normal,v.Position) |> Array.unzip334 GL.GenBuffers(1,&vID)35 GL.BindBuffer(BufferTarget.ArrayBuffer,vID)36 GL.BufferData(BufferTarget.ArrayBuffer,IntPtr (4 * 8 * vvv.Length),vvv,BufferUsageHint.StaticDraw)3738 GL.GenBuffers(1,&eID)39 GL.BindBuffer(BufferTarget.ElementArrayBuffer,eID)40 GL.BufferData(BufferTarget.ElementArrayBuffer,IntPtr (4 * iv.Length),iv,BufferUsageHint.StaticDraw)4142 this.vboID <- vID43 this.eboID <- eID44 this.TriangelCount <- iv.Length45 this.IsCreate <- true46 ()47member v.GetMidValue (first:T2N3V3,second:T2N3V3) =48let midN = Vector3.Lerp(first.Position,second.Position,0.5f) |> Vector3.Normalize49let midP = midN *(float32 rad)50let midT = Vector2.Lerp(first.TexCoord,second.TexCoord,0.5f) |> Vector2.Normalize51let result = new T2N3V3(midT,midN,midP)52 result53member v.Subdivide (v1:T2N3V3,v2:T2N3V3,v3:T2N3V3) =54let vs = Array.create 6 (new T2N3V3())55 vs.[0] <- v156 vs.[1] <- v.GetMidValue(v1,v2)57 vs.[2] <- v.GetMidValue(v3,v1)58 vs.[3] <- v259 vs.[4] <- v.GetMidValue(v2,v3)60 vs.[5] <- v361let is = Array.create 12062 is.[0] <- 063 is.[1] <- 164 is.[2] <- 265 is.[3] <- 266 is.[4] <- 167 is.[5] <- 468 is.[6] <- 469 is.[7] <- 170 is.[8] <- 371 is.[9] <- 272 is.[10] <-473 is.[11] <- 574 (vs,is)75member this.Sub(alls:T2N3V3 [],is:int []) =76//let mutable tv,vv,pv = alls |> Array.map (fun v -> v.TexCoord,v.Normal,v.Position) |> Array.unzip377let mutable allv = alls78let mutable iv = is79let show array = printfn "%A" array80for j in0 .. lev do81let mutable av = Array.create 0 (new T2N3V3())82let mutable ev = Array.create 0083 printfn "%i" allv.Length84 printfn "%i" iv.Length85for i in0 .. 3 .. iv.Length - 1do86let (vvv,iiv) = this.Subdivide(allv.[iv.[i]],allv.[iv.[i+1]],allv.[iv.[i+2]])87let length = av.Length88 av <- Array.append av vvv89let map = iiv |> Array.map (fun p -> p + length)90 ev <- Array.append ev map91 allv <- av92 iv <- ev93 allv |> Array.map (fun p -> p.Position) |> show94 show iv95 allv,ivView Code初始化需要的⼆个参数,分别代表球的⼤⼩(radius),与画的细分程度(level).其中相关如何绘制球体代码在上⽂有讲,相当于有是把⼀个分别位于x,y,z各(+radius,-radius)这六个点,组成的⼀个⼋个三⾓形,索引点的位置如Init⾥GL.InterleavedArrays(InterleavedArrayFormat.T2fN3fV3f,0,IntPtr.Zero)其中的T2fN3fV3f对应于我们的数据结构T2N3V3,这个函数分别相当于指定GL.TexCoordPointer,GL.NormalPointer,GL.VertexPointer(还会打开相应状态),会⾃动给我们处理好,我们也可以只指定顶点,如下GL.VertexPointer(3,VertexPointerType.Float,4*8,IntPtr (4*8-4*5)),这些数据之间的间隔对应与我们前⾯写⼊的GL.BufferData(BufferTarget.ArrayBuffer,IntPtr (4 * 8 * vvv.Length),vvv,BufferUsageHint.StaticDraw)其中vvv是T2N3V3的结构.基本的GL.BindBuffer的对应的三个处理就不细说了,在Draw⾥,BindBuffer是指定我们当前格式数据在存储位置,然后分别调⽤InterleavedArrays设定各顶点的状态,然后是调⽤DrawElements对应上⾯的GL.BindBuffer(BufferTarget.ElementArrayBuffer,this.eboID)处理.然后是⽴⽅体的绘制,其中⽴⽅体的绘制⽤的⽅法看起来会容易理解.如下1type Cube(width:float32,height:float32,length:float32,index:int) =2inherit Shape()3let mutable id = index4let xl,yl,zl =width/2.f,height/2.f,length/2.f5let mutable color = Color.White6let v8 = [|7new Vector3(xl,yl,zl)8new Vector3(-xl,yl,zl)9new Vector3(-xl,-yl,zl)10new Vector3(xl,-yl,zl)11new Vector3(xl,yl,-zl)12new Vector3(-xl,yl,-zl)13new Vector3(-xl,-yl,-zl)14new Vector3(xl,-yl,-zl)15 |]16new(x,y,z) =17let rnd = System.Random().Next()18 printfn "%i" rnd19 Cube(x,y,z,-1)20override this.Draw() =21if this.IsCreate<>true then this.Init()22 GL.EnableClientState(ArrayCap.VertexArray)23 GL.EnableClientState(ArrayCap.NormalArray)24 GL.BindBuffer(BufferTarget.ArrayBuffer,this.vboID)25 GL.VertexPointer(3,VertexPointerType.Float,0,IntPtr.Zero)26 GL.PushMatrix()27if id >= 0 && id < 8then28 GL.Translate(v8.[id])29 GL.Color3(this.Color:Color)30 GL.Normal3(Vector3.UnitZ)31 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|0;1;2;0;2;3|])32//GL.Color3(Color.Black)33 GL.Normal3(Vector3.UnitY)34 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|4;5;1;4;1;0|])35//GL.Color3(Color.Red)36 GL.Normal3(Vector3.UnitX)37 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|4;0;3;4;3;7|])38//GL.Color3(Color.Green)39 GL.Normal3(-Vector3.UnitY)40 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|3;2;6;3;6;7|])41//GL.Color3(Color.Blue)42 GL.Normal3(-Vector3.UnitX)43 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|1;5;6;1;6;2|])44//GL.Color3(Color.DodgerBlue)45 GL.Normal3(-Vector3.UnitZ)46 GL.DrawElements(BeginMode.Triangles,6,DrawElementsType.UnsignedInt,[|5;4;7;5;7;6|])47 GL.PopMatrix()48override this.Init() =49let mutable vID = 050 GL.GenBuffers(1,&vID)51 GL.BindBuffer(BufferTarget.ArrayBuffer,vID)52 GL.BufferData(BufferTarget.ArrayBuffer,IntPtr (4 * 3 * v8.Length),v8,BufferUsageHint.StaticDraw)53 this.vboID <- vID54 this.IsCreate <- true55let rnd = System.Random(this.GetHashCode())56 this.Color <- Color.FromArgb(rnd.Next(0,255),rnd.Next(0,255),rnd.Next(0,255))57 ()58member this.Index with get() = id and set value = id <-value59member this.Color with get() = color and set value = color <- valueView Code上图中的V8分别对应其中的0-7个顶点,GL.DrawElements后⾯的0;1;2;0;2;3分别是以三⾓形的画法来画⼀个正⽅形.⽴⽅体的画法主要是确定宽,⾼,长,我们这样定义,我们站在原点上,⾯向Z+轴,我们的⼿展开来表⽰X轴(对应宽度),⽽我们的⾝⾼表⽰Y轴(对应⾼度),和我们⾯向距离的长远来表⽰Z轴,(对应长度).绘制也是8个⾯,和上⾯⼀样,也是在缓存中记录顶点,但是不⼀样的是,顶点索引是在绘制时没有⽤到顶点索引缓存,主要考虑后⾯有法向量的处理,还有现在没有加上的纹理贴图的处理.在这⾥,我们要特别注意,顶点顺序问题,在opengl,默认正⾯是逆时针,⽽我们可以看0;1;2;0;2;3对应图上的顺序.然后⼤家可能会发现,画⽴⽅体的后⾯5;4;7;5;7;6,这个顺序好像不对,是顺时针的.⼤家可以想象下,我们在门外看门的逆时针画法与我们在门内看门外顺时针的画法是⼀样的.所以如果我们要画后⾯4,5,6,7我们以为的是逆时针是不对的,我们要想象我们在那边来看,然后再画,应该是5,4,7,6这个⽅向.其中纹理贴图后⾯会说,和这处理也有类似.在上⾯,我们看到我们都没对顶点的颜⾊来定义,这⾥没必要,因为后⾯我们肯定要⽤到灯光,⽤到灯光的话,设置的颜⾊都没⽤,我们会⽤到灯光颜⾊与材质的颜⾊.纹理贴图也有没对应处理,这⾥在后⾯我会根据讲到再来改写相关处理.下⼀节,主要是讲第⼀⼈称漫游的相关处理.。

OpenGL空间(坐标系)变换

OpenGL空间(坐标系)变换

OpenGL空间(坐标系)变换⽹友的《3D图形学的学习策略》⼀⽂使我深受启发,在图形学以及openGL学习⽅⾯给了我很有价值的指导性意见,在此对前辈们的不吝赐教表⽰感激,谢谢你们的⽆私分享。

如⽂章所说,API是⼯具,不是本质,OpenGL/Direct3D的本质是图形学,⽽不是OpenGL/Direct3D的本⾝,API的本⾝只是⼀些Interface⽽已。

最重要的,最根本的是,你要明⽩这些API背后的图形学的原理---因为那才是根本中的根本。

其实很多事情,包括学习也涉及到⽣活,只有抓住了本质,才能体会到其中的真谛。

带着这种希望探究本质的学习⽅法,结合图形学原理,通过阅读书⽬和⽹友们的⽂章,我对OpenGL⼏何空间变换进⾏了总结性的学习。

OpenGL处理管线的⽬的是将对象的三维描述转换为可以显⽰的⼆维图像。

为了完成这个从三维到⼆维的转换,OpenGL 使⽤了多个空间(坐标系),每个空间完成特定的任务,从⼀个空间到另⼀个空间需要进⾏空间转换。

理解OpenGL所使⽤的各种空间以及它们间的变换是⾮常重要的。

如上图所⽰,openGL中使⽤的空间依次是:对象空间、世界空间、视点空间、裁剪空间、归⼀化设备空间、窗⼝空间、屏幕空间。

结合⾃⼰的理解,就每个空间完成的基本任务和空间的变换关系,总结如下。

对象空间。

对象空间中完成的最⼤任务是对象建模,三维对象的属性,包括顶点位置和表⾯法线等是在这个空间内指定的。

这个空间的坐标原点⼀般在对象上,有时候也在其他地⽅,主要是为了建模⽅便。

每⼀个对象都有⼀个⾃⼰的对象空间。

就openGL⽽⾔,我⽬前还没有接触到建⽴很复杂模型的应⽤,建模⼀般在其他地⽅如3DMAX中完成,然后读⼊openGL进⾏处理。

世界空间。

对象空间之后是世界空间,我理解为世界坐标系是固定不变的。

世界空间主要是对三维场景进⾏描述,就是把已经建⽴的各种对象摆放在三维空间中,空间的转换是通过模型变换完成的。

可以通过平移、旋转、⽐例缩放等把对象摆放在需要的位置,就好像买好家具以后设计房间布局⼀样。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

opengl 球体顶点坐标
在OpenGL中,创建一个球体的最简单方法是使用纬度和经度来生成顶点坐标。

以下是一个例子:
```cpp
#include <cmath>
#include <vector>
std::vector<float> createSphereVertices(float radius, int stacks, int slices) {
std::vector<float> vertices;
for (int i = 0; i <= stacks; ++i) {
float latitude = M_PI / stacks * i;
float sinLat = sin(latitude);
float cosLat = cos(latitude);
for (int j = 0; j <= slices; ++j) {
float longitude = 2 * M_PI / slices * j;
float sinLon = sin(longitude);
float cosLon = cos(longitude);
float x = radius * sinLat * cosLon;
float y = radius * sinLat * sinLon;
float z = radius * cosLat;
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(z);
}
}
return vertices;
}
int main() {
float radius = 1.0f;
int stacks = 30;
int slices = 30;
std::vector<float> sphereVertices = createSphereVertices(radius, stacks, slices);
// 使用生成的顶点坐标绘制球体
// ...
return 0;
}
```
这段代码创建一个球体的顶点坐标,使用纬度(stacks)和经度(slices)作为输入参数,并将其返回为一个
`std::vector<float>`类型的容器。

你可以使用生成的顶点坐标来绘制球体。

请注意,这个例子中使用的是笛卡尔坐标系,即x 轴向右,y轴向上,z轴垂直于屏幕指向外部。

相关文档
最新文档