正投影

正投影



什么是正投影?

Orthographic Projection 看物体有两种方式.一种 是正投影方式观察物体,另一种是透视图的方式。如果你曾经俯视一条长路,你会发现这条路会在远处变得越来越窄。这是一个透视图。

在一个正投影视图,这条路会在你视线所及内保持相同的宽度。

 

正投影如何使用?

正投影视图运行比透视图快. 这并不意味着我们应该一直使用它。但有时你不需要深度。例如2D应用程序或者游戏。在这里, 正投影是极为有用的

其他的事项

在本教程中,你将最终了解如何在屏幕上显示一个形状。我们通过指定的顶点建立原型。这些顶点是这个形状在三维空间上的指定点。下面给出了各个原型与对应应该放置的顶点的列表

Primitive Flag Description
GL_POINTS 顶点的坐标
GL_LINES 线将绘制在给出的两个顶点之间.
GL_LINE_STRIP 画连续的线. 以第一个顶点为头,以后的每个后续的顶点与前个顶点之间划线
GL_LINE_LOOP 与 GL_LINE_STRIP 类似,但会连接最后一点和第一点.
GL_TRIANGLES 以每个给出的三个点为顶点画三角形.
GL_TRIANGLE_STRIP 经过前2个顶点,每个后续的顶点使用之前的第2个顶点画一个三角形。
GL_TRIANGLE_FAN 经过前2个顶点,每个后续顶点使用之前的顶点和第一个顶点画一个三角形。这是用来画锥状物。

当画点时,  glPointSize 函数可以改变画的点的大小。这个函数需要一个参数指定点的大小。默认值是1.

当画线时,你可以用glLineWidth 函数改变线宽. 这个函数也有一个参数指定线的宽度,默认值也是1.

 


例子:

第一步是指定我们要画在屏幕上的正方形的坐标。下面每组给定3个浮点数指定顶点的X,Y和Z值。X是水平位置,Y是垂直位置,Z是表示这个点进入或者移出屏幕的距离。Z正值越大,表示这个点移出屏幕越远(向我们方向)

头三个顶点是用来画第一个三角形的。最后一个点是用来画最后的三角形的。你可以从我们用GL_TRIANGLE_STRIP 原型看出。

GLfloat square[] = {
	0.25, 0.25, 0.0,
	0.75, 0.25, 0.0,
	0.25, 0.75, 0.0,
	0.75, 0.75, 0.0
    };

我们还是像上个教程中做的一样通过初始化程序开始。

void init()
{
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

When working with OpenGL, there are various matrices that are available to work with. These define your view and how primitives should be placed. When transforming primitives (discussed later), we use the GL_MODELVIEW matrix. If we want to change the projection (how objects are viewed), we use the GL_PROJECTION matrix. We can change the current matrix by using the glMatrixMode function. We pass what matrix we want to use onto the function.

	glMatrixMode(GL_PROJECTION);

We want to initialize the matrix to the identity matrix. This is a matrix with 1's on the diagonals and 0's everywhere else. The identity matrix has the same properties as the value 1 in normal multiplication. Any matrix you multiply by the identity matrix will stay the same. To load the identity matrix, you use the glLoadIdentity function. This function takes no parameters.

	glLoadIdentity();

At the beginning of this tutorial, we said that we would be using Orthographic projection. The glOrthof function is used to specify orthographic projection. This function takes 6 parameters, each explained below.

GLfloat left & GLfloat right - These specify the values for the left and right clipping planes.

GLfloat bottom & GLfloat top - These specify the values for the bottom and top clipping planes.

GLfloat near & GLfloat far - These specify the drawing distance. Any objects out of this range will not be displayed.

All parameters above specify an area that will be displayed in the window. Looking back at the vertices specified for the square, you can see that the square will be displayed in the center of the window.

	glOrthof(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);

We have now setup the Orthographic Projection. It is now time to render our square.

Primitives in OpenGL ES are drawn using Vertex Arrays. You need to set the current vertices to use. This is accomplished by using the glVertexPointer function. This function takes 4 parameters :

GLint size - This specifies the number of coordinates per vertex. If we had left off the 0.0f's in the square vertices above, we would have placed a 2 here. Because each vertex has been specified using 3 values, we pass a 3 for this parameter.

GLenum type - specifies what data type is being used for the values in the array eg. GL_BYTE, GL_SHORT, GL_FLOAT, etc.

GLsizei stride - specifies the offset between consecutive vertices ie. how many extra values exist between the end of the current vertex and the beginning of the next vertex. We do not have any extra data between vertices and so we therefore pass 0 for this parameter.

const GLvoid *pointer - The last parameter is used to specify the memory location of the first value in the array of values ie. the pointer to the array.

	glVertexPointer(3, GL_FLOAT, 0, square);

Like the Vertex Array, there are a number of other arrays that will be covered. If not all of these arrays are being used, resources can be saved by disabling the others. All are disabled by default and so we therefore need to enable the Vertex Array. This is done by using the glEnableClientState function. This function takes one parameter, specifying the array that must be enabled. We therefore pass the GL_VERTEX_ARRAY flag to enable the Vertex Array.

	glEnableClientState(GL_VERTEX_ARRAY);
}

Now that we have setup our view and shape, we can display it. We first clear the screen as per normal. Remember that if you are using the Vincent library, the display function needs to accept a UGWindow parameter.

void display()
{
   glClear(GL_COLOR_BUFFER_BIT);

To draw the primitives using the current set of arrays, you use the glDrawArrays function. The parameters are as follows :

GLenum mode - This is used to specify what primitive to draw. Remember when we discussed the primitives above that we are going to be using the GL_TRIANGLE_STRIP primitive.

GLint first - This is used to specify the starting index in the array ie. how many vertices in the array to skip before starting to read them. We want to start from the beginning, thus requiring a value of 0 to be passed.

GLsizei count - This specifies how many vertices to process. We have 4 vertices that we want to use. This is the value that we need to pass to the function.

   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

We end off as we did in the previous tutorial.

   glFlush();
   glutSwapBuffers();
}

Before completing this tutorial, we will discuss the use of GLUT|ES context menus. If you are using GLUT|ES, you cannot open the standard keyboard. We therefore have to have another way of interacting with the program. If you are using the UG library, you can simply skip to the conclusion.

To add a context menu, you need a minimum of 3 lines of code. These are placed just before your call to glutMainLoop.

	glutCreateMenu(menu);
	glutAddMenuEntry("Quit", 1);

	glutAttachMenu(GLUT_LEFT_BUTTON);

The glutCreateMenu function simply creates a menu and accepts a parameter specifying which custom function will be used to handle a menu option being selected. Here, we pass the menu function which will be shown shortly.

The glutAddMenuEntry function accepts 2 parameters and adds a menu item to the menu. The first parameter is a character string which is used to specify the text for the menu item. The second parameter is the ID of the menu item and should be unique for each menu item. This is used to determine which menu item was selected.

The last function, glutAttachMenu, is used to attach the menu to the window. It accepts 1 parameter indicating what action must be taken to make the menu appear. Here we pass the GLUT_LEFT_BUTTON flag as we want the context menu to appear after touching the screen.

The callback function specified by glutCreateMenu is given below. It simply accepts one integer parameter which indicates the menu option that was pressed. We only have one menu item which is used to quit the application when pressed.

void menu(int entry)
{
	switch(entry)
	{
	case 1 : exit(0); break;
	}
}

You have finally drawn something to the screen. When you run the program, you should be presented with a white box in the middle of the screen.

Please let me know of any comments you may have : Contact Me

GLUT|ES Source Files : Embedded Visual C++ 4.0
UG Source Files : Embedded Visual C++ 4.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Three.js 是一个基于 WebGL 的 JavaScript 库,用于创建和展示复杂的 3D 和 2D 图形无需插件。Three.js 提供了多种内置对象、材质、光源等资源,简化了三维图形渲染的过程。 正投影相机是 Three.js 中的一种相机模型,它用于模拟二维空间中的平行投影效果,在三维场景中生成的图像保持线条平行性和相对大小不变。这种类型的相机适用于绘制建筑平面图、技术图纸或其他需要保持物体间精确比例的视图。以下是关于正投影相机的一些关键特性: ### 特点 1. **线性透视**:在正投影中,所有平行线在投影面上仍然保持平行,这使得物体的比例在整个视野内保持一致,非常适合绘制结构图和机械设计图。 2. **尺寸稳定性**:与透视投影相比,正投影下的物体不会因为距离的变化而改变其实际大小,这对于需要精确测量和标注的场景非常有用。 3. **无变形效果**:在正投影下,无论物体离相机有多远,它们的形状都不会发生扭曲变形,有助于保持物体的真实形态。 4. **易于理解和解释**:由于没有视觉上的深度错觉,用户能够更直接地理解所呈现的空间布局和结构,这对于工程、建筑设计等领域尤为重要。 ### 使用示例 假设我们想创建一个正投影相机并将其应用到一个 Three.js 场景中: ```javascript // 引入Three.js库 import * as THREE from 'three'; // 创建一个新的场景 const scene = new THREE.Scene(); // 设置背景颜色 scene.background = new THREE.Color(0xffffff); // 白色背景 // 创建摄像机实例 - 使用透视相机(通常情况正投影相机在Three.js中表示为透视相机而非一种特定的“正投影”相机) const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 100); // 设置初始位置 // 创建渲染器实例 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加一个立方体作为场景的一部分 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 调整相机视口以适应场景的大小 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); // 渲染场景并持续更新 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 在这个简单的例子中,我们首先导入了必要的 Three.js 文件,并创建了一个新的场景、摄像机以及一个立方体作为场景的内容。这里使用的是透视相机 `THREE.PerspectiveCamera` 类型的相机,它是 Three.js 默认提供的相机类型之一,尽管它默认配置的实际上是一种透视投影效果而不是纯正投影。对于真正的正投影效果,实际中并不常见于 Three.js 环境下,因为大多数图形处理需求涉及到视角变换和透视效果,以获得更真实的三维体验。然而,上述代码提供了一个基础框架,用于在 Three.js 中操作和渲染场景。 --- ### 相关问题: 1. 为什么在某些情况下选择正投影相机而非透视相机? 2. 怎样调整正投影相机的位置和视角以优化3D场景的表现? 3. 正投影相机如何影响物体的显示和交互,在设计过程中有哪些应用场景?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值