本节是OpenGL学习的第六个课时,下面介绍OpenGL图形的相关知识:

    (1)多边形的概念:

多边形是由多条线段首尾相连而形成的闭合区域。OpenGL规定,一个多边形必须是一个“凸多边形”。通过点、直线和多边形,就可以组合成各种几何图形。一段弧可以看成是是很多短的直线段相连,这些直线段足够短,以至于其长度小于一个像素的宽度。通过位于不同平面的相连的小多边形,还可以组成一个“曲面”。

什么是凸边形:

凸边形:多边形内任意两点所确定的线段都在多边形内,由此也可以推导出,凸多边形不能是空心的。

凸边形与凹边形:

凸多边形又可称为平面多边形,是多边形中的一种,与凹多边形相对。凸多边形的内角均小于180°,而凹边形内角有的可以大于180°。

验证方法:

将图形的任意一边无限延长,如果延长线与图形有交点就是凹边形,反之就是凸边形。

    多边形是OpenGL中绘制曲面的基础。

    (2)如何绘制多边形:

1)三维坐标系下多边形的两面及其绘制方式:

从三维的角度来看,一个多边形具有两个面,每一个面都可以设置不同的绘制方式:

绘制方式:
.填充
.只绘制边缘轮廓线
.只绘制顶点
(“填充”是默认的方式)

void glPolygonMode(GLenum face,GLenum mode)函数用于控制多边形的显示方式:

face参数确定显示模式将适用于物体的哪些部分,控制多边形的正面和背面的绘图模式:
.GL_FRONT 表示显示模式将适用于物体的前向面(也就是物体能看到的面)
.GL_BACK 表示显示模式将适用于物体的后向面(也就是物体上不能看到的面)
.GL_FRONT_AND_BACK 表示显示模式将适用于物体的所有面
mode参数确定选中的物体的面以何种方式显示(显示模式):
.GL_POINT 表示只显示顶点,多边形用点显示
.GL_LINE 表示显示线段,多边形用轮廓显示
.GL_FILL 表示显示面,多边形采用填充形式
可以为两个面分别设置不同的显示方式:
glPolygonMode(GL_FRONT, GL_FILL);            //设置正面为填充方式
glPolygonMode(GL_BACK, GL_LINE);             //设置反面为边缘绘制方式
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);  //设置两面均为顶点绘制方式

2)反转(切换正反面):

一般约定:顶点以逆时针顺序出现在屏幕上的面为正面,另一个面即成为反面。可以使用glFrontFace函数来调换正面与反面的概念。

void glFrontFace(GLenum mode)作用是控制多边形的正面是如何决定的:

mode参数的值:
.GL_CCW 表示窗口坐标上投影多边形的顶点顺序为逆时针方向的表面为正面。(CounterClockWise)
.GL_CW 表示顶点顺序为顺时针方向的表面为正面。(ClockWise)
顶点的方向又称为环绕。
(在默认情况下,mode是GL_CCW) 

如果一个虚构的对象的顶点是按照多边形内部顺时针的方向进行绘制的,那么可以称这个多边形基于窗口坐标的投影是顺时针的。反之,则为逆时针。glFrontFace就是用来指定多边形在窗口坐标中的方向是逆时针还是顺时针的。

3)剔除多边形表面:

在一个全部由不透明封闭表面组成的场景中,背面多边形是永远看不见的。剔除这些不可见的多边形对于加速图形的渲染有很大的益处。

OpenGL中使用glCullFace()来进行剔除操作:

剔除操作的步骤:
.glEnable(GL_CULL_FACE):启动剔除功能;(glDisable(GL_CULL_FACE)关闭剔除功能)
.使用glCullFace()来进行剔除;

void glCullFace(GLenum mode)指明前面或后面的多边形是否要剔除:

mode参数的值:
.GL_FRONT 表示剔除正面
.GL_BACK 剔除反面
.GL_FRONT_AND_BACK 剔除正反两面的多边形

4)镂空多边形:

直线可以被画成虚线,而多边形则可以进行镂空。

OpenGL中使用glPolygonStipple()函数设置镂空的样式:

镂空操作的步骤:
.使用glEnable(GL_POLYGON_STIPPLE)来启动镂空模式。(使用glDisable(GL_POLYGON_STIPPLE)可以关闭之)。
.使用glPolygonStipple()来设置镂空的样式。

void glPolygonStipple(const GLubyte *mask)

glPolygonStipple() -- set the polygon stippling pattern

PARAMETERS

    mask Specifies a pointer to a 32*32 stipple pattern that will be unpacked from memory in the same way that glDrawPixels unpacks pixels.

DESCRIPTION

     Polygon stippling, like line stippling (see glLineStipple), masks out certain fragments produced by rasterization, creating a pattern. Stippling is independent of polygon antialiasing. mask is a pointer to a 32*32 stipple pattern that is stored in memory just like the pixel data supplied to a glDrawPixels with height and width both equal to 32, a pixel format of GL_COLOR_INDEX, and data type of GL_BITMAP. That is, the stipple pattern is represented as a 32*32 array of 1-bit color indices packed in unsigned bytes. glPixelStore parameters like GL_UNPACK_SWAP_BYTES and GL_UNPACK_LSB_FIRST affect the assembling of the bits into a stipple pattern. Pixel transfer operations (shift, offset, pixel map) are not applied to the stipple image, however. Polygon stippling is enabled and disabled with glEnable and glDisable, using argument GL_POLYGON_STIPPLE. If enabled, a rasterized polygon fragment with window coordinates xw and yw is sent to the next stage of the GL if and only if the (xw mod 32)th bit in the (yw mod 32)th row of the stipple pattern is one. When polygon stippling is disabled, it is as if the stipple pattern were all ones.

此函数定义填充多边形的当前点画模式。其中的参数mask指向一个长度为128字节的空间,它表示了一个32*32的矩形应该如何镂空。其中:第一个字节表示了最左下方的从左到右(也可以是从右到左,这个可以修改)8个像素是否镂空(1表示不镂空,显示该像素;0表示镂空,显示其后面的颜色),最后一个字节表示了最右上方的8个像素是否镂空。

    (3)绘制实例:

1)不同绘图模式下的对比和反转的对比:

#include <GL/glut.h>
#include <math.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#define Pi 3.1416
void Init(void)
{
glClearColor(0.5,0.5,0.5,0.5);
glClear(GL_COLOR_BUFFER_BIT);
} void paint()
{
glViewport(,,,); //先画分割线
glColor3f(1.0f,0.0f,0.0f);
glPointSize(5.0f);
glBegin(GL_LINES);
glVertex2f(-0.6f, -1.0f); glVertex2f(-0.6f, 1.0f);
glVertex2f( 0.2f, -1.0f); glVertex2f( 0.2f, 1.0f);
glEnd(); GLfloat a = / ( - * cos( * Pi / ));
GLfloat bx = a * cos( * Pi / );
GLfloat by = a * sin( * Pi / );
GLfloat cy = -a * cos( * Pi / );
GLfloat
PointA[] = { , a},
PointB[] = { bx , by},
PointC[] = { 0.25, cy},
PointD[] = { -0.25, cy},
PointE[] = { -bx, by }; //图1,为只无论正反面绘制顶点
glViewport(, , , );
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);//前面和后面均为以顶点的方式绘制
glColor3f(1.0f, 1.0f, 0.0f); glPointSize(5.0f);//黄色的顶点
glBegin(GL_POLYGON);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd(); //其余的图,均为正面填充,反面线形
glPolygonMode(GL_FRONT, GL_FILL);// 设置正面为填充模式
glPolygonMode(GL_BACK, GL_LINE);// 设置反面为线形模式
glPointSize(2.0f);
//图2和图三形成对比,一个看得是正面,一个看得是反面
//图2
glViewport(,,,);
glFrontFace(GL_CCW);//切换正反面
glColor3f(0.0, 1.0, 1.0f);
glBegin(GL_POLYGON);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd();
//图3
glViewport(,,,);
glColor3f(0.0, 1.0, 1.0f);
glFrontFace(GL_CW);//切换正反面
glBegin(GL_POLYGON);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd();
//图4和图5形成对比,一个看得是正面,一个看得是反面
//图4
glViewport(, , , );
glFrontFace(GL_CCW);//切换正反面
glColor3f(0.0, 0.0, 1.0f);
glBegin(GL_POLYGON);
glVertex2fv(PointA);
glVertex2fv(PointB);
glVertex2fv(PointC);
glVertex2fv(PointD);
glVertex2fv(PointE);
glEnd();
//图5
glViewport(,,,);
glFrontFace(GL_CW);//切换正反面
glColor3f(0.0, 0.0, 1.0f);
glBegin(GL_POLYGON);
glVertex2fv(PointA);
glVertex2fv(PointB);
glVertex2fv(PointC);
glVertex2fv(PointD);
glVertex2fv(PointE);
glEnd();
//图6
glViewport(, , , );
glFrontFace(GL_CW);//切换正反面
glColor3f(0.0, 0.0, 1.0f);
glBegin(GL_POLYGON);
glVertex2fv(PointE);
glVertex2fv(PointD);
glVertex2fv(PointC);
glVertex2fv(PointB);
glVertex2fv(PointA);
glEnd();
//图5和图6形成对比,按不同顶点顺序绘制,正反面的定义不同。
glFlush();
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
Init();
glutInitWindowSize(,);
glutInitWindowPosition(,);
glutCreateWindow("不同绘图模式下的对比和反转的对比");
glutDisplayFunc(paint);
glutMainLoop();
}

2)在3D空间中绘制旋转立方体:

#include<GL/freeglut.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //绘制立方体的八个立体空间中的坐标值,原点即其中点
GLfloat vertexNum[][] = {
{ 1.0, -1.0, -1.0 },
{ 1.0, -1.0, 1.0 },
{ 1.0, 1.0, 1.0 },
{ 1.0, 1.0, -1.0 },
{ -1.0, -1.0, -1.0 },
{ -1.0, -1.0, 1.0 },
{ -1.0, 1.0, 1.0 },
{ -1.0, 1.0, -1.0 }
};
GLfloat colors[][] = {
{ 1.0, 0.0, 0.0 },//红色
{ 1.0, 1.0, 0.0 },//黄色
{ 0.0, 1.0, 0.0 },//绿色
{ 0.0, 1.0, 1.0 },//青色
{ 1.0, 0.0, 1.0 },//品红色
{ 0.0, 0.0, 1.0 },//淡蓝色
{ 0.0, 0.5, 0.0 },//淡绿色
{ 0.0, 0.5, 0.5 },//淡青色 }; float angle = ; void polygon(int a, int b, int c, int d)
{ //4个点组成一个面
glBegin(GL_QUADS);//绘制多组独立的填充四边形
glColor3fv(colors[a]);
glVertex3fv(vertexNum[a]);
glColor3fv(colors[a]);
glVertex3fv(vertexNum[b]);
glColor3fv(colors[a]);
glVertex3fv(vertexNum[c]);
glColor3fv(colors[a]);
glVertex3fv(vertexNum[d]);
glEnd();
} void cube(void)
{
polygon(, , , );
polygon(, , , );
polygon(, , , );
polygon(, , , );
polygon(, , , );
polygon(, , , );
} void paint(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix();
{
glRotatef(angle, , , );
glColor3f(, , );
glutWireCube(2.0);//绘制边长为2的线框
cube();
}
glPopMatrix();
glutSwapBuffers();
} void IdleFunction()
{
angle += 0.02;
if (angle > )
angle = ;
glutPostRedisplay();
} void reshapeFunction(int w, int h)
{
glViewport(, , w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -8.0, 8.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(3.0, 3.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void Init()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.3, 0.3, 0.3, 1.0f);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(,);
glutInitWindowSize(, );
glutCreateWindow("RotateCube");
Init(); glutReshapeFunc(reshapeFunction);
glutIdleFunc(IdleFunction);
glutDisplayFunc(paint);
glutMainLoop();
return ; }

3)面的镂空操作的讲解实例:

#include <GL/glut.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") GLubyte data[] = {//数组就是一个苍蝇的图像。 数组有128个字节, 表示了一个32x32的矩阵型镂空的数据。数组里面的第一个字节表示了左下方从左到右的8个像素是否镂空, 以此类推。
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x03, 0x80, 0x01, 0xC0,
0x06, 0xC0, 0x03, 0x60,
0x04, 0x60, 0x06, 0x20,
0x04, 0x30, 0x0C, 0x20,
0x04, 0x18, 0x18, 0x20,
0x04, 0x0C, 0x30, 0x20,
0x04, 0x06, 0x60, 0x20,
0x44, 0x03, 0xC0, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66,
0x33, 0x01, 0x80, 0xCC,
0x19, 0x81, 0x81, 0x98,
0x0C, 0xC1, 0x83, 0x30,
0x07, 0xe1, 0x87, 0xe0,
0x03, 0x3f, 0xfc, 0xc0,
0x03, 0x31, 0x8c, 0xc0,
0x03, 0x33, 0xcc, 0xc0,
0x06, 0x64, 0x26, 0x60,
0x0c, 0xcc, 0x33, 0x30,
0x18, 0xcc, 0x33, 0x18,
0x10, 0xc4, 0x23, 0x08,
0x10, 0x63, 0xC6, 0x08,
0x10, 0x30, 0x0c, 0x08,
0x10, 0x18, 0x18, 0x08,
0x10, 0x00, 0x00, 0x08,
}; void display(void)
{
glClearColor(0.5,0.5,0.5,0.5);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(data);
glRectf(-0.75f, -0.75f, 0.75f, 0.75f);
glFinish();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(, );
glutInitWindowPosition(, );
glutCreateWindow("利用多边形镂空绘制苍蝇");
glutDisplayFunc(display);
glutMainLoop();
}

我们可以自定义进行图形镂空的图形:

保存为.bmp形式。

#include <GL/glut.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") void display(void)
{
GLubyte data[];
FILE* fp;
fp = fopen("C:/Users/JMSun/Desktop/图片/logo.bmp", "rb");
if (!fp)
{
exit();
}
if (fseek(fp, -(int)sizeof(data), SEEK_END))
{
exit();
}
if (!fread(data, sizeof(data), , fp))
{
exit();
}
fclose(fp); glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(data);
glRectf(-0.75f, -0.75f, 0.75f, 0.75f);
glFinish();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(, );
glutInitWindowPosition(, );
glutCreateWindow("利自定义logo进行多边形镂空");
glutDisplayFunc(display);
glutMainLoop();
}

4)相关知识:

1.设置颜色:

void glColor3f (GLfloat red, GLfloat green, GLfloat blue);//设置颜色
void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);//设置颜色, 带透明通道

如果需要使用透明通道, 必须要打开ALPHA混合器,并指定源与目标的混合方式:

使用透明通道时,打开ALPHA混合器的方式:
.glEnable(GL_BLEND); // 打开混合
.glDisable(GL_DEPTH_TEST); // 关闭深度测试
.glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基于源象素alpha通道值的半透明混合函数

使用ALPHA通道的实例:

#include <GL/glut.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") void display()
{
glClearColor(0.5f,0.5f,0.5f,0.5f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND); // 打开混合
glDisable(GL_DEPTH_TEST); // 关闭深度测试
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // 基于源象素alpha通道值的半透明混合函数
glColor3f(0.0f, 1.0f, 0.0f);
//glBegin(GL_POLYGON);//运用系统自带的函数绘制图形不需要glBegin和glEnd;
glRectf(-0.6,-0.6,0.6,0.6);
//glEnd(); glColor4f(1.0f, 0.0f, 0.0f, 0.5f);
glLineWidth(20.0f);
glBegin(GL_LINES);
glVertex2f(-0.25f, );
glVertex2f(0.25f, );
glEnd();
glFinish();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(, );
glutInitWindowPosition(, );
glutCreateWindow("带透明值Alpha的图形");
glutDisplayFunc(display);
glutMainLoop();
}

    (4)实时动态绘制正弦曲线上的点:(在之前的版本基础上的改动)

#include <GL/glut.h>
#include <math.h>
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") #define GL_PI 3.1416f
const GLfloat factor = 0.1f; GLfloat transferNum = 0.0f; void SetupRC(void)
{
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
}
void paint(void)
{
glClear(GL_COLOR_BUFFER_BIT);
GLfloat x;
glColor3f(1.0f, 1.0f, 1.0f);
glPointSize(4.0f);//应在glBegin之前
glBegin(GL_POINTS);
for (x = -; x<; x += 0.1)
{
glVertex2f(x*factor, sin(x -transferNum)*factor * );
}
glEnd();
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
glVertex2f(-1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(0.0f, -1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glutSwapBuffers();
}
void IdleFunction()
{
transferNum += 0.003 / ( * GL_PI);
if (transferNum>*GL_PI){
transferNum = ;
}
glutPostRedisplay();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);//当没有键盘监听时不需要用双缓冲模式
glutInitWindowSize(, );
glutCreateWindow("动态正弦图像");
glutDisplayFunc(paint);
SetupRC();
glutIdleFunc(IdleFunction);
glutMainLoop(); return ;
}

OpenGL学习进程(8)第六课:点、边和图形(三)绘制图形的更多相关文章

  1. OpenGL学习进程(12)第九课:矩阵乘法实现3D变换

    本节是OpenGL学习的第九个课时,下面将详细介绍OpenGL的多种3D变换和如何操作矩阵堆栈.     (1)3D变换: OpenGL中绘制3D世界的空间变换包括:模型变换.视图变换.投影变换和视口 ...

  2. OpenGL学习进程(11)第八课:颜色绘制的详解

        本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿.     (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. R ...

  3. OpenGL学习进程(10)第七课:四边形绘制与动画基础

        本节是OpenGL学习的第七个课时,下面以四边形为例介绍绘制OpenGL动画的相关知识:     (1)绘制几种不同的四边形: 1)四边形(GL_QUADS) OpenGL的GL_QUADS图 ...

  4. OpenGL学习进程(7)第五课:点、边和图形(二)边

    本节是OpenGL学习的第五个课时,下面介绍OpenGL边的相关知识: (1)边的概念: 数学上的直线没有宽度,但OpenGL的直线则是有宽度的.同时,OpenGL的直线必须是有限长度,而不是像数学概 ...

  5. OpenGL学习进程(4)第二课:绘制图形

    本节是OpenGL学习的第二个课时,下面介绍如何用点和线来绘制图形:     (1)用点的坐标来绘制矩形: #include <GL/glut.h> void display(void) ...

  6. 红帽学习笔记[RHCSA] 第六课[进程、服务相关]

    第六课 进程 进程:已经启动的可执行程序的运行中的实例.每个进程都有自己的地址空间,并占用了一定的系统资源. 如何产生一个进程 执行程序或命令 计划任务 在终端中对进程管理 运行一个前台进程 [roo ...

  7. OpenGL学习进程(6)第四课:点、边和图形(一)点

    本节是OpenGL学习的第四个课时,下面介绍OpenGL点的相关知识:     (1)点的概念:     数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点 ...

  8. OpenGL学习进程(5)第三课:视口与裁剪区域

    本节是OpenGL学习的第三个课时,下面介绍如何运用显示窗体的视口和裁剪区域:     (1)知识点引入:     1)问题现象: 当在窗体中绘制图形后,拉伸窗体图形形状会发生变化: #include ...

  9. OpenGL学习进程(3)第一课:初始化窗体

        本节是OpenGL学习的第一个课时,下面介绍如何初始化一个窗体:     (1)显示一个有蓝色背景的窗体: #include <GL/glut.h> #include <st ...

随机推荐

  1. char *strrchr使用

    /* 这个函数用到的少 这次用到记录一下 */ /* 函数原型: char *strrchr(const char *str, char c) * 功能: 找到字符c在字符串str中最后出现的位置,返 ...

  2. 【转】【Mac系统】之ADB命令总结

    参考文章: 张明云:<Android ADB命令大全(通过ADB命令查看wifi密码.MAC地址.设备信息.操作文件.查看文件.日志信息.卸载.启动和安装APK等)> Yjnull:< ...

  3. Java基础02 方法与数据成员(转载)

    对象中的数据成员表示对象的状态.对象可以执行方法,表示特定的动作. 此外,我们还了解了类(class).同一类的对象属于相同的类型(type).我们可以定义类,并使用该定义来产生对象.   调用同一对 ...

  4. TP中单字母快捷函数总结

    ThinkPHP中有许多使用简便的单字母函数,可以很方便开发者快速的调用,但是字母函数却不方便记忆,本文将所有的字母函数总结一下,以方便以后查找.1.U() URL组装 支持不同URL模式 U($ur ...

  5. ThinkPHP自动填充实现无限级分类的方法

    这篇文章主要介绍了ThinkPHP自动填充实现无限级分类的方法,是ThinkPHP项目开发中非常实用的一个技巧,需要的朋友可以参考下   本文实例展示了ThinkPHP自动填充实现无限级分类的方法,是 ...

  6. String转int的几种常用方法

    String类型转int类型通常需要int的包装类Integer,该类有三个方法可以实现这种转换,分别为decode(String s).parseInt(String s).valueOf(Stri ...

  7. ASP.NET动态网站制作(28)-- 三层框架(2)

    前言:三层框架的第二节课,继续上次课的内容. 内容: 1.三层框架的使用目的:可以将视图层和业务逻辑层及实体层分开,可以提高代码的扩展性,安全性,可以实现程序的低耦合性. 2.GetModel方法及G ...

  8. Android-ViewPagerIndicator框架使用——UnderlinePageIndicator

    前言:UnderlinePageIndicator这个指示,是一个很小巧的东西,简单,没有那么多复杂的效果. 一:布局定义simple_underlines: <LinearLayout xml ...

  9. MathType可以编辑省略号吗

    说到省略号大家可能会想到写文章的时候会用到,其实在数学中也会常常的使用到.当数学过程是重复有规律性的过程时,就会用到它.MathType是一款数学公式编辑器,那么,在数学公式中,MathType编辑时 ...

  10. Ubuntu下MongoDB的安装和使用

    本博文介绍了MongoDB,并详细指引读者在Ubuntu下MongoDB的安装和使用.本教程在Ubuntu14.04下测试通过.(2017.09.07) 安装MongoDB MongoDB安装很简单, ...