Directx11学习笔记【十五】 基本几何体的绘制

本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/

  前面实现简单地形的教程,我们只是绘制了一个网格,这一次我们来学习一下几种基本几何体的绘制,包括平面网格、立方体、圆柱和球体等。

原来在GeometryGenerator类中只给出了CreateGrid一个方法来绘制网格,现在让我们添加其他方法绘制一些几何体。

  为了方便绘制几何体方法的调用,GeometryGenerator类我们使用了单例模式。很简单,将构造函数设为private,添加一个GetInstance函数如下:

//单例模式
    static GeometryGenerator* GetInstance()
    {
        static GeometryGenerator instance;
        return &instance;
    }

  这只是实现单例模式的一种方法,还有几种实现单例模式的方法就不一一说明了。

1.基本几何体绘制方法 

  下面介绍几种常见几何体的绘制方法(代码均参考dx11龙书)。

1.1网格

  网格可以说是最常见同时也是最重要的,像实现地形水面等都离不开网格。生成一个网格首先要给出网格的宽和高,以及在宽和高上划分的格子数。

看龙书中给出的一张图片就明白了:

由此,顶点的坐标就很容易生成了。

顶点索引的计算关键是推导出一个用于求构成第i行,第j列的顶点处右下方两个三角形的顶点索引的通用公式。

对顶点缓存中的任意一点A,如果该点位于地形中的第i行、第j列的话,那么该点在顶点缓存中所对应的位置应该就是i*m+j(m为每行的顶点数)。如果A点在索引缓存中的位置为k的话,那么A点为起始点构成的三角形ABC中,B、C顶点在顶点缓存中的位置就为(i+1)x m+j和i x m+(j+1)。且B点索引值为k+1,C点索引值为k+2.这样。这样,公式就可以推导为如下:

三角形ABC=【i*每行顶点数+j,i*每行顶点数+(j+1),(i+1)*行顶点数+j】

三角形CBD=【(i+1)*每行顶点数+j,i*每行顶点数+(j+1),(i+1)*行顶点数+(j+1)】

 1 void GeometryGenerator::CreateGrid(float width, float height, UINT m, UINT n, MeshData &mesh)
 2 {
 3     mesh.vertices.clear();
 4     mesh.indices.clear();
 5     //每行顶点数、每列顶点数
 6     UINT nVertsRow = m + 1;
 7     UINT nVertsCol = n + 1;
 8     //起始x、z坐标
 9     float oX = -width * 0.5f;
10     float oZ = height * 0.5f;
11     //每一格坐标变化
12     float dx = width / m;
13     float dz = height / n;
14
15     //顶点总数量:nVertsRow * nVertsCol
16     mesh.vertices.resize(nVertsRow * nVertsCol);
17
18     //逐个添加顶点
19     for (UINT i = 0; i < nVertsCol; ++i)
20     {
21         float tmpZ = oZ - dz * i;
22         for (UINT j = 0; j < nVertsRow; ++j)
23         {
24             UINT index = nVertsRow * i + j;
25             mesh.vertices[index].pos.x = oX + dx * j;
26             mesh.vertices[index].pos.y = 0.f;
27             mesh.vertices[index].pos.z = tmpZ;
28
29             mesh.vertices[index].normal = XMFLOAT3(0.f, 1.f, 0.f);
30             mesh.vertices[index].tangent = XMFLOAT3(1.f, 0.f, 0.f);
31
32             mesh.vertices[index].tex = XMFLOAT2(dx*i, dx*j);
33         }
34     }
35
36     //总格子数量:m * n
37     //因此总索引数量: 6 * m * n
38     UINT nIndices = m * n * 6;
39     mesh.indices.resize(nIndices);
40     UINT tmp = 0;
41     for (UINT i = 0; i < n; ++i)
42     {
43         for (UINT j = 0; j < m; ++j)
44         {
45             mesh.indices[tmp] = i * nVertsRow + j;
46             mesh.indices[tmp + 1] = i * nVertsRow + j + 1;
47             mesh.indices[tmp + 2] = (i + 1) * nVertsRow + j;
48             mesh.indices[tmp + 3] = i * nVertsRow + j + 1;
49             mesh.indices[tmp + 4] = (i + 1) * nVertsRow + j + 1;
50             mesh.indices[tmp + 5] = (i + 1) * nVertsRow + j;
51
52             tmp += 6;
53         }
54     }
55 }

1.2立方体

  立方体的绘制就很简单了,一个立方体只需要提供三维方向上的长度。有一点与之前绘制彩色立方体时不一样的是,我们这里创建立方体用到24个顶点(每个面4个),而之前彩色立方体只用到了8个顶点(每个顶点被3个面共享)。这是因为在后面学习过程中我们需要顶点的法线坐标,而一个顶点相对于其连接的3个面来说,法线完全不同,因此无法共享顶点。

  1 void GeometryGenerator::CreateBox(float width, float height, float depth, MeshData &mesh)
  2 {
  3     mesh.vertices.clear();
  4     mesh.indices.clear();
  5
  6     //一共24个顶点(每面4个)
  7     mesh.vertices.resize(24);
  8     //一共36个索引(每面6个)
  9     mesh.indices.resize(36);
 10
 11     float halfW = width * 0.5f;
 12     float halfH = height * 0.5f;
 13     float halfD = depth * 0.5f;
 14
 15     //眼睛面向z轴正方向
 16     //构建顶点
 17     //前面
 18     mesh.vertices[0].pos = XMFLOAT3(-halfW, -halfH, -halfD);
 19     mesh.vertices[0].normal = XMFLOAT3(0.f, 0.f, -1.f);
 20     mesh.vertices[0].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 21     mesh.vertices[0].tex = XMFLOAT2(0.f, 1.f);
 22     mesh.vertices[1].pos = XMFLOAT3(-halfW, halfH, -halfD);
 23     mesh.vertices[1].normal = XMFLOAT3(0.f, 0.f, -1.f);
 24     mesh.vertices[1].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 25     mesh.vertices[1].tex = XMFLOAT2(0.f, 0.f);
 26     mesh.vertices[2].pos = XMFLOAT3(halfW, halfH, -halfD);
 27     mesh.vertices[2].normal = XMFLOAT3(0.f, 0.f, -1.f);
 28     mesh.vertices[2].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 29     mesh.vertices[2].tex = XMFLOAT2(1.f, 0.f);
 30     mesh.vertices[3].pos = XMFLOAT3(halfW, -halfH, -halfD);
 31     mesh.vertices[3].normal = XMFLOAT3(0.f, 0.f, -1.f);
 32     mesh.vertices[3].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 33     mesh.vertices[3].tex = XMFLOAT2(1.f, 1.f);
 34     //左侧面
 35     mesh.vertices[4].pos = XMFLOAT3(-halfW, -halfH, halfD);
 36     mesh.vertices[4].normal = XMFLOAT3(-1.f, 0.f, 0.f);
 37     mesh.vertices[4].tangent = XMFLOAT3(0.f, 0.f, -1.f);
 38     mesh.vertices[4].tex = XMFLOAT2(0.f, 1.f);
 39     mesh.vertices[5].pos = XMFLOAT3(-halfW, halfH, halfD);
 40     mesh.vertices[5].normal = XMFLOAT3(-1.f, 0.f, 0.f);
 41     mesh.vertices[5].tangent = XMFLOAT3(0.f, 0.f, -1.f);
 42     mesh.vertices[5].tex = XMFLOAT2(0.f, 0.f);
 43     mesh.vertices[6].pos = XMFLOAT3(-halfW, halfH, -halfD);
 44     mesh.vertices[6].normal = XMFLOAT3(-1.f, 0.f, 0.f);
 45     mesh.vertices[6].tangent = XMFLOAT3(0.f, 0.f, -1.f);
 46     mesh.vertices[6].tex = XMFLOAT2(1.f, 0.f);
 47     mesh.vertices[7].pos = XMFLOAT3(-halfW, -halfH, -halfD);
 48     mesh.vertices[7].normal = XMFLOAT3(-1.f, 0.f, 0.f);
 49     mesh.vertices[7].tangent = XMFLOAT3(0.f, 0.f, -1.f);
 50     mesh.vertices[7].tex = XMFLOAT2(1.f, 1.f);
 51     //背面
 52     mesh.vertices[8].pos = XMFLOAT3(halfW, -halfH, halfD);
 53     mesh.vertices[8].normal = XMFLOAT3(0.f, 0.f, 1.f);
 54     mesh.vertices[8].tangent = XMFLOAT3(-1.f, 0.f, 0.f);
 55     mesh.vertices[8].tex = XMFLOAT2(0.f, 1.f);
 56     mesh.vertices[9].pos = XMFLOAT3(halfW, halfH, halfD);
 57     mesh.vertices[9].normal = XMFLOAT3(0.f, 0.f, 1.f);
 58     mesh.vertices[9].tangent = XMFLOAT3(-1.f, 0.f, 0.f);
 59     mesh.vertices[9].tex = XMFLOAT2(0.f, 0.f);
 60     mesh.vertices[10].pos = XMFLOAT3(-halfW, halfH, halfD);
 61     mesh.vertices[10].normal = XMFLOAT3(0.f, 0.f, 1.f);
 62     mesh.vertices[10].tangent = XMFLOAT3(-1.f, 0.f, 0.f);
 63     mesh.vertices[10].tex = XMFLOAT2(1.f, 0.f);
 64     mesh.vertices[11].pos = XMFLOAT3(-halfW, -halfH, halfD);
 65     mesh.vertices[11].normal = XMFLOAT3(0.f, 0.f, 1.f);
 66     mesh.vertices[11].tangent = XMFLOAT3(-1.f, 0.f, 0.f);
 67     mesh.vertices[11].tex = XMFLOAT2(1.f, 1.f);
 68     //右侧面
 69     mesh.vertices[12].pos = XMFLOAT3(halfW, -halfH, -halfD);
 70     mesh.vertices[12].normal = XMFLOAT3(1.f, 0.f, 0.f);
 71     mesh.vertices[12].tangent = XMFLOAT3(0.f, 0.f, 1.f);
 72     mesh.vertices[12].tex = XMFLOAT2(0.f, 1.f);
 73     mesh.vertices[13].pos = XMFLOAT3(halfW, halfH, -halfD);
 74     mesh.vertices[13].normal = XMFLOAT3(1.f, 0.f, 0.f);
 75     mesh.vertices[13].tangent = XMFLOAT3(0.f, 0.f, 1.f);
 76     mesh.vertices[13].tex = XMFLOAT2(0.f, 0.f);
 77     mesh.vertices[14].pos = XMFLOAT3(halfW, halfH, halfD);
 78     mesh.vertices[14].normal = XMFLOAT3(1.f, 0.f, 0.f);
 79     mesh.vertices[14].tangent = XMFLOAT3(0.f, 0.f, 1.f);
 80     mesh.vertices[14].tex = XMFLOAT2(1.f, 0.f);
 81     mesh.vertices[15].pos = XMFLOAT3(halfW, -halfH, halfD);
 82     mesh.vertices[15].normal = XMFLOAT3(1.f, 0.f, 0.f);
 83     mesh.vertices[15].tangent = XMFLOAT3(0.f, 0.f, 1.f);
 84     mesh.vertices[15].tex = XMFLOAT2(1.f, 1.f);
 85     //上面
 86     mesh.vertices[16].pos = XMFLOAT3(-halfW, halfH, -halfD);
 87     mesh.vertices[16].normal = XMFLOAT3(0.f, 1.f, 0.f);
 88     mesh.vertices[16].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 89     mesh.vertices[16].tex = XMFLOAT2(0.f, 1.f);
 90     mesh.vertices[17].pos = XMFLOAT3(-halfW, halfH, halfD);
 91     mesh.vertices[17].normal = XMFLOAT3(0.f, 1.f, 0.f);
 92     mesh.vertices[17].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 93     mesh.vertices[17].tex = XMFLOAT2(0.f, 0.f);
 94     mesh.vertices[18].pos = XMFLOAT3(halfW, halfH, halfD);
 95     mesh.vertices[18].normal = XMFLOAT3(0.f, 1.f, 0.f);
 96     mesh.vertices[18].tangent = XMFLOAT3(1.f, 0.f, 0.f);
 97     mesh.vertices[18].tex = XMFLOAT2(1.f, 0.f);
 98     mesh.vertices[19].pos = XMFLOAT3(halfW, halfH, -halfD);
 99     mesh.vertices[19].normal = XMFLOAT3(0.f, 1.f, 0.f);
100     mesh.vertices[19].tangent = XMFLOAT3(1.f, 0.f, 0.f);
101     mesh.vertices[19].tex = XMFLOAT2(1.f, 1.f);
102     //底面
103     mesh.vertices[20].pos = XMFLOAT3(-halfW, -halfH, halfD);
104     mesh.vertices[20].normal = XMFLOAT3(0.f, -1.f, 0.f);
105     mesh.vertices[20].tangent = XMFLOAT3(1.f, 0.f, 0.f);
106     mesh.vertices[20].tex = XMFLOAT2(0.f, 1.f);
107     mesh.vertices[21].pos = XMFLOAT3(-halfW, -halfH, -halfD);
108     mesh.vertices[21].normal = XMFLOAT3(0.f, -1.f, 0.f);
109     mesh.vertices[21].tangent = XMFLOAT3(1.f, 0.f, 0.f);
110     mesh.vertices[21].tex = XMFLOAT2(0.f, 0.f);
111     mesh.vertices[22].pos = XMFLOAT3(halfW, -halfH, -halfD);
112     mesh.vertices[22].normal = XMFLOAT3(0.f, -1.f, 0.f);
113     mesh.vertices[22].tangent = XMFLOAT3(1.f, 0.f, 0.f);
114     mesh.vertices[22].tex = XMFLOAT2(1.f, 0.f);
115     mesh.vertices[23].pos = XMFLOAT3(halfW, -halfH, halfD);
116     mesh.vertices[23].normal = XMFLOAT3(0.f, -1.f, 0.f);
117     mesh.vertices[23].tangent = XMFLOAT3(1.f, 0.f, 0.f);
118     mesh.vertices[23].tex = XMFLOAT2(1.f, 1.f);
119
120     //构建索引
121     mesh.indices[0] = 0;
122     mesh.indices[1] = 1;
123     mesh.indices[2] = 2;
124     mesh.indices[3] = 0;
125     mesh.indices[4] = 2;
126     mesh.indices[5] = 3;
127
128     mesh.indices[6] = 4;
129     mesh.indices[7] = 5;
130     mesh.indices[8] = 6;
131     mesh.indices[9] = 4;
132     mesh.indices[10] = 6;
133     mesh.indices[11] = 7;
134
135     mesh.indices[12] = 8;
136     mesh.indices[13] = 9;
137     mesh.indices[14] = 10;
138     mesh.indices[15] = 8;
139     mesh.indices[16] = 10;
140     mesh.indices[17] = 11;
141
142     mesh.indices[18] = 12;
143     mesh.indices[19] = 13;
144     mesh.indices[20] = 14;
145     mesh.indices[21] = 12;
146     mesh.indices[22] = 14;
147     mesh.indices[23] = 15;
148
149     mesh.indices[24] = 16;
150     mesh.indices[25] = 17;
151     mesh.indices[26] = 18;
152     mesh.indices[27] = 16;
153     mesh.indices[28] = 18;
154     mesh.indices[29] = 19;
155
156     mesh.indices[30] = 20;
157     mesh.indices[31] = 21;
158     mesh.indices[32] = 22;
159     mesh.indices[33] = 20;
160     mesh.indices[34] = 22;
161     mesh.indices[35] = 23;
162 }

1.3圆柱

  为了构建一个圆柱,需要提供如下信息:圆柱的上口半径(topRadius),下口半径(bottomRadius),高度(height)。此外,为了指定圆柱的精细度,还需要指定两个参数,一个为没高度方向上平均划分的个数(stack),另一个为沿圆周方向等分的个数(slice)。

  可以根据龙书中给出的图理解一下:

 1 void GeometryGenerator::CreateCylinder(float topRadius, float bottomRadius, float height, int slice, int stack, MeshData &mesh)
 2 {
 3     mesh.vertices.clear();
 4     mesh.indices.clear();
 5
 6     //从上到下每个stack半径变化量:dRadius
 7     float dRadius = (bottomRadius - topRadius) / stack;
 8     //每个stack高度:dHeight
 9     float dHeight = height / stack;
10
11     //每个圆周上顶点数量:slice+1
12     int vertsPerRow = slice + 1;
13     //顶点行数:stack+1
14     int nRows = stack + 1;
15
16     //总顶点数
17     int nVerts = vertsPerRow * nRows;
18     //总索引数
19     int nIndices = slice * stack * 6;
20
21     mesh.vertices.resize(nVerts);
22     mesh.indices.resize(nIndices);
23
24     //顶部Y坐标
25     float topY = height * 0.5f;
26
27     for (int i = 0; i < nRows; ++i)
28     {
29         float tmpY = topY - dHeight * i;
30         float tmpRadius = topRadius + i * dRadius;
31
32         for (int j = 0; j < vertsPerRow; ++j)
33         {
34             float theta = XM_2PI * j / slice;
35             int index = i * vertsPerRow + j;
36             mesh.vertices[index].pos = XMFLOAT3(tmpRadius*cos(theta), tmpY, tmpRadius*sin(theta));
37         }
38     }
39
40     UINT tmp(0);
41     for (int i = 0; i < stack; ++i)
42     {
43         for (int j = 0; j < slice; ++j)
44         {
45             mesh.indices[tmp] = i * vertsPerRow + j;
46             mesh.indices[tmp + 1] = (i + 1) * vertsPerRow + j + 1;
47             mesh.indices[tmp + 2] = (i + 1) * vertsPerRow + j;
48             mesh.indices[tmp + 3] = i * vertsPerRow + j;
49             mesh.indices[tmp + 4] = i * vertsPerRow + j + 1;
50             mesh.indices[tmp + 5] = (i + 1) * vertsPerRow + j + 1;
51
52             tmp += 6;
53         }
54     }
55 }

1.4球

  绘制球基本参数只有一个半径,但是同圆柱一样为了指定精细程度也要给出stack和slice两个参数,这里slice是从上极点沿球面到下极点的180度角等分。具体绘制可以看代码理解:

 1 void GeometryGenerator::CreateSphere(float radius, int slice, int stack, MeshData &mesh)
 2 {
 3
 4     mesh.vertices.clear();
 5     mesh.indices.clear();
 6
 7     int vertsPerRow = slice + 1;
 8     int nRows = stack - 1;
 9
10     int nVerts = vertsPerRow * nRows + 2;
11     int nIndices = (nRows - 1)*slice * 6 + slice * 6;
12
13     mesh.vertices.resize(nVerts);
14     mesh.indices.resize(nIndices);
15
16     for (int i = 1; i <= nRows; ++i)
17     {
18         float phy = XM_PI * i / stack;
19         float tmpRadius = radius * sin(phy);
20         for (int j = 0; j < vertsPerRow; ++j)
21         {
22             float theta = XM_2PI * j / slice;
23             UINT index = (i - 1)*vertsPerRow + j;
24
25             float x = tmpRadius*cos(theta);
26             float y = radius*cos(phy);
27             float z = tmpRadius*sin(theta);
28
29             //位置坐标
30             mesh.vertices[index].pos = XMFLOAT3(x, y, z);
31             //法线
32             XMVECTOR N = XMVectorSet(x, y, z, 0.f);
33             XMStoreFloat3(&mesh.vertices[index].normal, XMVector3Normalize(N));
34             //切线
35             XMVECTOR T = XMVectorSet(-sin(theta), 0.f, cos(theta), 0.f);
36             XMStoreFloat3(&mesh.vertices[index].tangent, XMVector3Normalize(T));
37             //纹理坐标
38             mesh.vertices[index].tex = XMFLOAT2(j*1.f / slice, i*1.f / stack);
39         }
40     }
41
42     int size = vertsPerRow * nRows;
43     //添加顶部和底部两个顶点信息
44     mesh.vertices[size].pos = XMFLOAT3(0.f, radius, 0.f);
45     mesh.vertices[size].normal = XMFLOAT3(0.f, 1.f, 0.f);
46     mesh.vertices[size].tangent = XMFLOAT3(1.f, 0.f, 0.f);
47     mesh.vertices[size].tex = XMFLOAT2(0.f, 0.f);
48
49     mesh.vertices[size + 1].pos = XMFLOAT3(0.f, -radius, 0.f);
50     mesh.vertices[size + 1].normal = XMFLOAT3(0.f, -1.f, 0.f);
51     mesh.vertices[size + 1].tangent = XMFLOAT3(1.f, 0.f, 0.f);
52     mesh.vertices[size + 1].tex = XMFLOAT2(0.f, 1.f);
53
54     UINT tmp(0);
55     int start1 = 0;
56     int start2 = mesh.vertices.size() - vertsPerRow - 2;
57     int top = size;
58     int bottom = size + 1;
59     for (int i = 0; i < slice; ++i)
60     {
61         mesh.indices[tmp] = top;
62         mesh.indices[tmp + 1] = start1 + i + 1;
63         mesh.indices[tmp + 2] = start1 + i;
64
65         tmp += 3;
66     }
67
68     for (int i = 0; i < slice; ++i)
69     {
70         mesh.indices[tmp] = bottom;
71         mesh.indices[tmp + 1] = start2 + i;
72         mesh.indices[tmp + 2] = start2 + i + 1;
73
74         tmp += 3;
75     }
76
77     for (int i = 0; i < nRows - 1; ++i)
78     {
79         for (int j = 0; j < slice; ++j)
80         {
81             mesh.indices[tmp] = i * vertsPerRow + j;
82             mesh.indices[tmp + 1] = (i + 1) * vertsPerRow + j + 1;
83             mesh.indices[tmp + 2] = (i + 1) * vertsPerRow + j;
84             mesh.indices[tmp + 3] = i * vertsPerRow + j;
85             mesh.indices[tmp + 4] = i * vertsPerRow + j + 1;
86             mesh.indices[tmp + 5] = (i + 1) * vertsPerRow + j + 1;
87
88             tmp += 6;
89         }
90     }
91 }

2.场景绘制

2.1最终效果

2.2多个几何体共享顶点索引缓冲区

  我们一共绘制了四种几何体:网格、立方体、球和圆柱,它们公用了一个顶点和索引缓冲区。这样我们就需要在其中找出每个几何体对应的位置。

为了在顶点、索引缓冲区中找到一个物体对应的位置,我们使用三个参数:该物体在顶点缓冲区中的起始位置(VStart),索引缓冲区中的起始位置(IStart),以及索引总数(totalIndices)。看龙书中的一幅图就很容易理解了:

2.3设为线框模式绘制

  在Render函数中创建一个栅格化状态ID3D11RasterizerState ,状态描述中FillMode设为D3D11_FILL_WIREFRAME即可

 1 //设置为线框绘制模式
 2     D3D11_RASTERIZER_DESC rsDesc;
 3     ZeroMemory(&rsDesc, sizeof(rsDesc));
 4     rsDesc.CullMode = D3D11_CULL_BACK;
 5     rsDesc.DepthClipEnable = true;
 6     //D3D11_FILL_WIREFRAME以线框模式绘制,D3D11_FILL_SOLID是以实体模式绘制
 7     rsDesc.FillMode = D3D11_FILL_WIREFRAME;
 8     rsDesc.FrontCounterClockwise = false;
 9     ID3D11RasterizerState *rsState(nullptr);
10     m_pd3dDevice->CreateRasterizerState(&rsDesc, &rsState);
11     m_pImmediateContext->RSSetState(rsState);

  由于具体代码太多就不一一给出了,代码和之前实现地形的代码类似,稍作改变就行啦。

时间: 2024-11-03 22:12:56

Directx11学习笔记【十五】 基本几何体的绘制的相关文章

Swift 学习笔记十五:扩展

扩展就是向一个已有的类.结构体或枚举类型添加新功能(functionality).扩展和 Objective-C 中的分类(categories)类似.(不过与Objective-C不同的是,Swift 的扩展没有名字.) Swift 中的扩展可以: 1.添加计算型属性和计算静态属性 2.定义实例方法和类型方法 3.提供新的构造器 4.定义下标 5.定义和使用新的嵌套类型 6.使一个已有类型符合某个协议 一.扩展属性,构造器,方法 class Human{ var name:String? va

laravel3学习笔记(十五)

原作者博客:ieqi.net ==================================================================================================== 异常与日志 在应用中,我们总会遇到各种问题.各种异常,这时,记录异常发生时的状态就很重要,所以异常与日志是有着天然的关系的. 关于异常与日志的配置在文件 application/config/error.php 中. 文件中有四个配置项: 'ignore' => ar

西门子PLC学习笔记十五-(数据块及数据访问方式)

一.数据块 数据块是在S7 CPU的存储器中定义的,用户可以定义多了数据块,但是CPU对数据块数量及数据总量是有限制的. 数据块与临时数据不同,当逻辑块执行结束或数据块关闭,数据块中的数据是会保留住的. 数据块分共享数据块.背景数据块.用户自定义数据块,下面分别介绍. 1.共享数据块(全局数据块) 其用于存储全局数据,所有逻辑块(OB.FC.FB)都可以访问共享数据块中的数据. 2.背景数据块(私有存储区) 其用做功能块(FB)的"存储器".FB的参数和静态变量安排在它的背景数据块中.

Java基础学习笔记十五 集合、迭代器、泛型

Collection 集合,集合是java中提供的一种容器,可以用来存储多个数据. 在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据.那么,集合和数组既然都是容器,它们有啥区别呢? 数组的长度是固定的.集合的长度是可变的. 集合中存储的元素必须是引用类型数据 集合继承关系图 ArrayList的继承关系: 查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口.Collec

Android学习笔记十五.深入理解fragment(三) 之《兼容多分辨率的应用》实战

深入理解fragment(三) 之<兼容多分辨率的应用>实战 在上一篇博文中介绍了如何使用Android Fragment开发适用于大屏幕应用,现在我们在上一个应用的基础上继续学习如何使用Fragment开发兼容多分辨率的应用. 1.建立/res/values-large/refs.xml引用资源文件 为了开发兼顾屏幕分辨率的应用,我们需要建立一个引用资源文件,专门用于定义各种引用项.refs.xml引用资源文件中定义了一项引用,其作用就是标明activity_book_list实际引用(@)

yii2源码学习笔记(十五)

这几天有点忙今天好些了,继续上次的module来吧 1 /** 2 * Returns the directory that contains the controller classes according to [[controllerNamespace]]. 3 *根据控制器的命名空间返回控制器的目录路径 4 * Note that in order for this method to return a value, you must define 5 * an alias for th

python学习笔记十五 web框架

python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. Python的WEB框架分为两类: 自己写socket,自己处理请求 基于wsgi(Web Server Gateway Interface WEB服务网关接口,实现socket功能),自己处理请求 如图示: 自己写的web框架 #!/usr/bin/env python #coding:utf-8 import socket def handle_req

PHP学习笔记十五【面向对象二】

<?php class Cat{ //public 访问修饰符 public $name; public $age; } //创建 $cat1=new Cat; $cat1->name="小白"; //访问某个对象的某个属性 $对象名->属性名 echo $cat1->name; echo "<br/>"; class Person { public $name; public $age; } $a=new Person(); $

学习笔记 十五: mariadb

一 mariadb简介 二 安装配置 三 案例

页面可视化编辑ckeditor(web基础学习笔记十五)

一.CKedit下载ckedit 下载地址:http://ckeditor.com/ 二.ckedit的引入 2.1.解压并将ckedit复制到项目中 2.2.在页面中引入 在页面头部加入 <script type="text/javascript" src="<%=request.getContextPath()%>/ckeditor/ckeditor.js"></script> 2.3.在需要使用ckedit的标签中添加cla