OpenGL ES中MRT应用
Demo涵盖了OpenGL ES 3.0 的一系列新特性:
1、VAO和VBO
2、帧缓冲对象
3、MRT
效果:
代码:
//yf's version
#define STB_IMAGE_IMPLEMENTATION
#include <stdlib.h>
#include "esUtil.h"
#include "stb_image.h" typedef struct
{
// Handle to a program object
GLuint programObject;
GLuint programObjectQuad; GLuint cubeVAO, cubeVBO;
GLuint floorVAO, floorVBO;
GLuint quadVAO, quadVBO;
GLuint framebuffer; ESMatrix mvMatrix;
ESMatrix mvpMatrix; GLuint mvLoc;
GLuint mvpLoc; GLuint cubeTexture;
GLuint floorTexture; // Rotation angle
GLfloat angle; GLuint texIDfloor;
GLuint texIDcube; GLuint texColorbuffer;
GLuint texColorArray[]; GLuint textureWidth;
GLuint textureHeight;
} UserData; GLfloat cubeVertices[] = {
// Positions // Texture Coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
GLfloat floorVertices[] = {
// Positions // Texture Coords (note we set these higher than 1 that together with GL_REPEAT as texture wrapping mode will cause the floor texture to repeat)
5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, 5.0f, 0.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, 5.0f, 2.0f, 0.0f,
-5.0f, -0.5f, -5.0f, 0.0f, 2.0f,
5.0f, -0.5f, -5.0f, 2.0f, 2.0f
};
//渲染到这个四边形
GLfloat quadVertices[] = { // Vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// Positions // TexCoords
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
}; GLuint screenWidth = ;
GLuint screenHeight = ; GLuint LoadTextureFile(const char* filename)
{
GLuint texID;
glGenTextures(, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int width, height, nrChannels;
unsigned char *data = stbi_load(filename, &width, &height, &nrChannels, );
if (data)
{
glTexImage2D(GL_TEXTURE_2D, , GL_RGB, width, height, , GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
printf("Failed to load texture\n");
stbi_image_free(data);
return texID;
} char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 a_position; \n"
"layout(location = 1) in vec2 a_texCoord; \n"
"uniform mat4 u_mvpMatrix; \n"
"out vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = u_mvpMatrix * a_position; \n"
" v_texCoord=a_texCoord; \n"
"} \n"; char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec2 v_texCoord; \n"
"uniform sampler2D screenTexture; \n"
"out vec4 outColor; \n"
"void main() \n"
"{ \n"
" outColor = texture(screenTexture,v_texCoord); \n"
"} \n"; //填充quad面片的VS
char vScreenShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec2 a_position; \n"
"layout(location = 1) in vec2 texCoord; \n"
"out vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(a_position.x,a_position.y,0.0,1.0); \n"
" v_texCoord=texCoord; \n"
"} \n"; ////正常:outColor=texture(Texture,v_texCoord);
char fScreenShaderStr[] = //正常Shader
"#version 300 es \n"
"precision mediump float; \n"
"out vec4 outColor; \n"
"in vec2 v_texCoord; \n"
"uniform sampler2D Texture; \n"
"void main() \n"
"{ \n"
//" outColor=texture(Texture,v_texCoord); \n"//正常色
" outColor=vec4(vec3(1.0-texture(Texture,v_texCoord)),1.0); \n"//反色
"} \n"; char fScreenShaderStrKernel[] =//核效果着色器
"#version 300 es \n"
"precision mediump float; \n"
"const float offset=1.0/300.0; \n"
"layout(location = 0) out vec4 outColor0; \n"
"layout(location = 1) out vec4 outColor1; \n"
"layout(location = 2) out vec4 outColor2; \n"
"layout(location = 3) out vec4 outColor3; \n"
"in vec2 v_texCoord; \n"
"uniform sampler2D Texture; \n"
"void main() \n"
"{ \n"
" vec2 offsets[9] = vec2[]( \n"
" vec2(-offset, offset), \n"
" vec2(0.0f, offset), \n"
" vec2(offset, offset), \n"
" vec2(-offset, 0.0f), \n"
" vec2(0.0f, 0.0f), \n"
" vec2(offset, 0.0f), \n"
" vec2(-offset, -offset), \n"
" vec2(0.0f, -offset), \n"
" vec2(offset, -offset) \n"
" ); \n" " float kernel[9] = float[]( \n"//模糊核0
" 1.0/16.0, 2.0/16.0, 1.0/16.0, \n"
" 2.0/16.0, 4.0/16.0, 2.0/16.0, \n"
" 1.0/16.0, 2.0/16.0, 1.0/16.0 \n"
" ); \n"
" vec3 sampleTex[9]; \n"
" for (int i = 0; i < 9; i++) \n"
" { \n"
" sampleTex[i] = vec3(texture(Texture, v_texCoord.st + offsets[i])); \n"
" } \n"
" vec3 col = vec3(0.0); \n"
" for (int i = 0; i < 9; i++) \n"
" col += sampleTex[i] * kernel[i]; \n"
" outColor0 = vec4(col, 1.0); \n" " kernel = float[]( \n"//锐化核1
" -1, -1, -1, \n"
" -1, 9, -1, \n"
" -1, -1, -1 \n"
" ); \n"
" for (int i = 0; i < 9; i++) \n"
" { \n"
" sampleTex[i] = vec3(texture(Texture, v_texCoord.st + offsets[i])); \n"
" } \n"
" col = vec3(0.0); \n"
" for (int i = 0; i < 9; i++) \n"
" col += sampleTex[i] * kernel[i]; \n"
" outColor1 = vec4(col, 1.0); \n"
" outColor2 = texture(Texture,v_texCoord); \n"//正常色2
" outColor3 = vec4(vec3(1.0-texture(Texture,v_texCoord)),1.0); \n"//反色3
"} \n"; int Init(ESContext *esContext)
{
UserData *userData = esContext->userData;
userData->textureWidth = ;
userData->textureHeight = ;
// Load the shaders and get a linked program object
userData->programObject = esLoadProgram(vShaderStr, fShaderStr);//载入文件、附件、编译、判错、删除Shader
userData->programObjectQuad = esLoadProgram(vScreenShaderStr, fScreenShaderStrKernel); userData->angle = 0.0f;
userData->mvLoc = glGetUniformLocation(userData->programObject, "u_mvMatrix");
userData->mvpLoc = glGetUniformLocation(userData->programObject, "u_mvpMatrix");
//cube
glGenVertexArrays(, &userData->cubeVAO);//初始化cube的vao
glGenBuffers(, &userData->cubeVBO);//初始化装载cube属性的vbo
glBindVertexArray(userData->cubeVAO);//以下操作对cubeVAO负责
glBindBuffer(GL_ARRAY_BUFFER, userData->cubeVBO);//以下操作对cubeVBO负责
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);//复制数据到当前vbo
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*));//设置顶点位置
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*)(sizeof(GLfloat) * ));
glEnableVertexAttribArray();
userData->texIDcube = LoadTextureFile("container.jpg");
glBindVertexArray();//完成cubeVAO的设置
//floor
glGenVertexArrays(, &userData->floorVAO);//初始化地板vao
glGenBuffers(, &userData->floorVBO);
glBindVertexArray(userData->floorVAO);
glBindBuffer(GL_ARRAY_BUFFER, userData->floorVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(floorVertices), floorVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*));
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*)(sizeof(GLfloat) * ));
userData->texIDfloor = LoadTextureFile("brick_DIFF.bmp");
glBindVertexArray();//完成floorVAO的设置
//quad
glGenVertexArrays(, &userData->quadVAO);
glGenBuffers(, &userData->quadVBO);
glBindVertexArray(userData->quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, userData->quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*));
glEnableVertexAttribArray();
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, sizeof(GLfloat) * , (GLvoid*)(sizeof(GLfloat) * ));
glBindVertexArray(); //GLuint defaultFramebuffer = 0;
const GLenum attachments[] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
//glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFramebuffer); //设置FBO
glGenFramebuffers(, &userData->framebuffer);//初始化帧缓冲framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, userData->framebuffer);//以下代码对framebuffer负责,包括纹理附件设置和rbo附件设置
glGenTextures(, &userData->texColorArray);
for (int i = ; i < ; i++){
//userData->texColorArray[i] = generateAttachmentTexture(GL_FALSE, GL_FALSE);//纹理附件
glBindTexture(GL_TEXTURE_2D, userData->texColorArray[i]);
glTexImage2D(GL_TEXTURE_2D, , GL_RGBA,
userData->textureWidth, userData->textureHeight,
, GL_RGBA, GL_UNSIGNED_BYTE, NULL);//设置宽高但不赋予纹理文件的数据
// Set the filtering mode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, userData->texColorArray[i], );//完成FBO的纹理附件挂载
}
glDrawBuffers(, attachments);
if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
return FALSE; //设置渲染缓冲对象附件
GLuint rbo;
glGenRenderbuffers(, &rbo);//初始化rbo附件
glBindRenderbuffer(GL_RENDERBUFFER, rbo);//以下操作对rbo负责
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screenWidth, screenHeight);
glBindRenderbuffer(GL_RENDERBUFFER, );//完成对rbo的设置
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);//完成FBO的rbo附件挂载 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!"); glBindFramebuffer(GL_FRAMEBUFFER, );//完成纹理附件和rbo附件的设置,解绑fbo glClearColor(1.0f, 1.0f, 1.0f, 0.0f);//初始刷新一下
glEnable(GL_DEPTH_TEST);
return TRUE;
} void Update(ESContext *esContext, float deltaTime)
{
UserData *userData = esContext->userData; userData->angle += (deltaTime * 50.0f);//转动
if (userData->angle >= 360.0f)
userData->angle -= 360.0f; esMatrixLoadIdentity(&userData->mvMatrix);
esTranslate(&userData->mvMatrix, 0.0f, 0.0f, -3.0f);
esRotate(&userData->mvMatrix, userData->angle, 0.0f, 1.0f, 0.0f); ESMatrix perspective;
esMatrixLoadIdentity(&perspective);//单位化一个矩阵作为透视投影矩阵
float aspect = (GLfloat)esContext->width / ((GLfloat)esContext->height);
esPerspective(&perspective, .f, aspect, 0.2f, .f); esMatrixMultiply(&userData->mvpMatrix, &userData->mvMatrix, &perspective);
} void DrawQuad(ESContext *esContext)
{
UserData *userData = esContext->userData;
glBindFramebuffer(GL_FRAMEBUFFER, userData->framebuffer);
glViewport(, , esContext->width, esContext->height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glUseProgram(userData->programObject);//启用programObject
glUniformMatrix4fv(userData->mvpLoc, , GL_FALSE, (GLfloat *)&userData->mvpMatrix);//mvpMatrix在Update里更新 glBindVertexArray(userData->cubeVAO);
glBindTexture(GL_TEXTURE_2D, userData->texIDcube);
glDrawArrays(GL_TRIANGLES, , );
glBindVertexArray(); glBindVertexArray(userData->floorVAO);
glBindTexture(GL_TEXTURE_2D, userData->texIDfloor);
glDrawArrays(GL_TRIANGLES, , );
glBindVertexArray();
glBindFramebuffer(GL_FRAMEBUFFER, ); // Bind to default framebuffer again and draw the quad plane with attched screen texture.
glBindFramebuffer(GL_FRAMEBUFFER, userData->framebuffer);//闪烁是因为重复渲染了三维图像和QUAD
glUseProgram(userData->programObjectQuad);//启用programObjectQuad
glBindVertexArray(userData->quadVAO);
glBindTexture(GL_TEXTURE_2D, userData->texColorArray[]);//texColorArray在Init里绑定到了fbo的纹理Attachment
glDrawArrays(GL_TRIANGLES, , );
glBindVertexArray();
glBindFramebuffer(GL_FRAMEBUFFER, );
//ID号为0表示缺省帧缓存,即默认的window提供的帧缓存。因此,在glBindFramebuffer()中将ID号设置为0可以解绑定当前FBO。
} void BlitTextures(ESContext *esContext)//区位块传送
{
UserData *userData = esContext->userData; // set the fbo for reading
glBindFramebuffer(GL_READ_FRAMEBUFFER, userData->framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, );
// Copy the output red buffer to lower left quadrant
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(, , userData->textureWidth, userData->textureHeight,
, , esContext->width / , esContext->height / ,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
//(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
// GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) // Copy the output green buffer to lower right quadrant
glReadBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(, , userData->textureWidth, userData->textureHeight,
esContext->width / , , esContext->width, esContext->height / ,
GL_COLOR_BUFFER_BIT, GL_LINEAR); // Copy the output blue buffer to upper left quadrant
glReadBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(, , userData->textureWidth, userData->textureHeight,
, esContext->height / , esContext->width / , esContext->height,
GL_COLOR_BUFFER_BIT, GL_LINEAR); // Copy the output gray buffer to upper right quadrant
glReadBuffer(GL_COLOR_ATTACHMENT3);
glBlitFramebuffer(, , userData->textureWidth, userData->textureHeight,
esContext->width / , esContext->height / , esContext->width, esContext->height,
GL_COLOR_BUFFER_BIT, GL_LINEAR);
} void Draw(ESContext *esContext)
{
DrawQuad(esContext);
BlitTextures(esContext);
} void ShutDown(ESContext *esContext)
{
UserData *userData = esContext->userData; glDeleteVertexArrays(, &userData->cubeVAO);
glDeleteBuffers(, &userData->cubeVBO);
glDeleteVertexArrays(, &userData->floorVAO);
glDeleteBuffers(, &userData->floorVBO);
glDeleteVertexArrays(, &userData->quadVAO);
glDeleteBuffers(, &userData->quadVBO); glDeleteBuffers(, userData->texColorArray);
glDeleteFramebuffers(, &userData->framebuffer); glDeleteProgram(userData->programObject);
glDeleteProgram(userData->programObjectQuad);
} int esMain(ESContext *esContext)
{
esContext->userData = malloc(sizeof(UserData)); esCreateWindow(esContext, "正常,反色,模糊,锐化", screenWidth, screenHeight, ES_WINDOW_RGB | ES_WINDOW_ALPHA | ES_WINDOW_DEPTH); if (!Init(esContext))
{
return GL_FALSE;
}
esRegisterShutdownFunc(esContext, ShutDown);
esRegisterUpdateFunc(esContext, Update);
esRegisterDrawFunc(esContext, Draw); return GL_TRUE;
}
OpenGL ES中MRT应用的更多相关文章
- opengl es中不同的绘制方式
opengl es中不同的绘制方式 转载请保留出处:http://xiaxveliang.blog.163.com/blog/static/297080342013467344263/ 1. GL_P ...
- OpenGL ES 中Uniform块
1.采用uniform Block的原因如果你的程序中包含了多个着色器,而且这些着色器使用了相同的Uniform变量,你就不得不为每个着色器分别管理这些变量.Uniform变量的location是在程 ...
- 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL ES中的Shader编程
在OpenGL ES中,Shader是着色器,包括两种:顶点着色器(Vertex Shader)和片元着色器(Fragment Shader).每个program对象有且仅有一个Vertex Shad ...
- 深度剖析OpenGL ES中的多线程和多窗口渲染技术
由 创新网小编 于 星期五, 2014-04-11 14:56 发表 移动设备中的CPU和GPU已经变得很强大,到处都是配备一个或多个高分辨率屏幕的设备,需要使用带有图形驱动器的复杂交互也日益增加.在 ...
- OpenGL ES 中的模板测试
模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...
- OpenGL ES 如何能看到一个物体内部和象3dmax中能只显示网格线
上一篇 OpenGL ES 正反面设置指令 中分析了正反面的判区方法,那么正反面有什么用呢?接下来我们就要引入一个叫做背面消除的概念.在3dmax中有个选项,当你用挤压修改器挤出一个中空的长方体时,在 ...
- iOS 中OpenGL ES 优化 笔记 1
1,避免同步和Flushing操作 OpenGL ES的命令执行通常是在command buffer中积累一定量的命令后,再做批处理执行,这样效率会更高:但是一些OpenGL ES命令必须flush ...
- [iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ格式分析
[iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ文件格式分析作者:yuezang - iTyran 在iOS的3D开发中常常需要导入通过3DS MAX之类 ...
- OpenGL ES 3D空间中自定义显示空间
在Android中,我们所熟知的是在ES管线中,其在图元装配时,会进行图元组装与图元分配,这样就回剪裁出来视景体中的物体.但是如果我想在3D场景中规定一个区域,凡是在这个区域中的物体就能显示出来,非这 ...
随机推荐
- 微信小程序 project.config.json 配置
可以在项目根目录使用 project.config.json 文件对项目进行配置. miniprogramRoot Path String 指定小程序源码的目录(需为相对路径) qcloudRoot ...
- 如何用MATLAB读stl并显示点云文件
function [VertexData,FVCD,isBinary]=stl2matlab(stlfile) % STL2MATLAB reads STL-file, ASCII or binary ...
- Django启动报错笔记
NO.1: You have 15 unapplied migration(s). Your project may not work properly until you apply the mig ...
- selenium使用技巧
标签(空格分隔): selenium 我们进行selenium的时候,就是通过webdriver,对浏览器做一些操作的: webdriver,除了find操作,之外还有哪些方法和属性呢? 1.获取当前 ...
- JUnit源码分析 - 扩展 - 自定义Rule
JUnit Rule简述 Rule是JUnit 4.7之后新加入的特性,有点类似于拦截器,可以在测试类或测试方法执行前后添加额外的处理,本质上是对@BeforeClass, @AfterClass, ...
- 网站改版应对google
客户要求修改网站,这会给我们带来问题!为了保留他的网站权重和关键字排名,我们必须在做网站修改工作之前分析他原来网站的连接结构和标题,这样我才能更好地保证他原来网站的整体权重不会有大的变化!以下是我们根 ...
- win7旗舰版64位GHOST版的,安装telnet客户端时,提示:出现错误。并非所有的功能被成功更改。
win7旗舰版64位GHOST版的,安装telnet客户端时,提示:出现错误.并非所有的功能被成功更改. 从安装成功的电脑上拷贝ghost版本缺少的文件,然后再安装telnet客户端,我已打包 链接: ...
- 虚拟网络学习笔记之一:VXLAN
1. 什么是虚拟网络? 答:从架构角度考虑,我们可以采用与服务器虚拟化引入Hypervisor的方式一样,引入Nypervisor或者叫“虚拟网络管理平台”实现虚拟网络.虚拟网络必须像虚拟机一样,脱离 ...
- Python学习笔记4基本数据类型
start:16:00 1.Python基本数据类型 (1)数字类型及其操作 整数类型 浮点数类型 浮点数间运算存在不确定尾数,不是bug 复数类型 数值运算操作符 (2)数值运算函数 . 2. ...
- 【转载】路径双反斜杠!!!Python IDLE或Python shell中切换路径 切换目录os.chdir("C:\\python37\\2019pythonshel37\\diedai")
Python IDLE或shell中切换路径在Python自带的编辑器IDLE中或者python shell中不能使用cd命令,那么跳到目标路径呢.方法是使用os包下的相关函数实现路径切换功能. im ...