OpenGL ES中MRT应用

时间:2022-11-04 08:11:05

Demo涵盖了OpenGL ES 3.0 的一系列新特性:

1、VAO和VBO

2、帧缓冲对象

3、MRT

效果:

OpenGL ES中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应用的更多相关文章

  1. opengl es中不同的绘制方式

    opengl es中不同的绘制方式 转载请保留出处:http://xiaxveliang.blog.163.com/blog/static/297080342013467344263/ 1. GL_P ...

  2. OpenGL ES 中Uniform块

    1.采用uniform Block的原因如果你的程序中包含了多个着色器,而且这些着色器使用了相同的Uniform变量,你就不得不为每个着色器分别管理这些变量.Uniform变量的location是在程 ...

  3. 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL ES中的Shader编程

    在OpenGL ES中,Shader是着色器,包括两种:顶点着色器(Vertex Shader)和片元着色器(Fragment Shader).每个program对象有且仅有一个Vertex Shad ...

  4. 深度剖析OpenGL ES中的多线程和多窗口渲染技术

    由 创新网小编 于 星期五, 2014-04-11 14:56 发表 移动设备中的CPU和GPU已经变得很强大,到处都是配备一个或多个高分辨率屏幕的设备,需要使用带有图形驱动器的复杂交互也日益增加.在 ...

  5. OpenGL ES 中的模板测试

    模板测试的主要功能是丢弃一部分片元,相对于深度检测来说,模板测试提出的片元数量相对较少.模板测试发生在剪裁测试之后,深度测试之前. 使用模板测试时很重要的代码提示: 1.glClear( GL_STE ...

  6. OpenGL ES 如何能看到一个物体内部和象3dmax中能只显示网格线

    上一篇 OpenGL ES 正反面设置指令 中分析了正反面的判区方法,那么正反面有什么用呢?接下来我们就要引入一个叫做背面消除的概念.在3dmax中有个选项,当你用挤压修改器挤出一个中空的长方体时,在 ...

  7. iOS 中OpenGL ES 优化 笔记 1

    1,避免同步和Flushing操作 OpenGL ES的命令执行通常是在command buffer中积累一定量的命令后,再做批处理执行,这样效率会更高:但是一些OpenGL ES命令必须flush ...

  8. &lbrack;iTyran原创&rsqb;iPhone中OpenGL ES显示3DS MAX模型之一:OBJ格式分析

    [iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ文件格式分析作者:yuezang - iTyran     在iOS的3D开发中常常需要导入通过3DS MAX之类 ...

  9. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1&period;0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

随机推荐

  1. unity3d中获得物体的size

    以size的x方向为例 1:gameObject.renderer.bounds.size.x;//这个值的结果真实反应出有MeshRenderer这个组件的模型的尺寸.不需要再乘以localScal ...

  2. Python学习day3作业

    days3作业 作业需求 HAproxy配置文件操作 根据用户输入,输出对应的backend下的server信息 可添加backend 和sever信息 可修改backend 和sever信息 可删除 ...

  3. Docker入门教程(一)介绍

    http://dockone.io/article/101 Docker入门教程(一)介绍 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第一篇,介绍了 ...

  4. top free综合监控工具

    top选项: -d:指定刷新时间间隔 -n:指定刷新次数 -u:指定只显示user用户的进程信息 -p:指定只显示pid的进程信息 [root@linuxzgf ~]# top Mem: 817449 ...

  5. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  6. lua cURL使用笔记

    cURL cURL是 URL命令行工具, 即 command URL, 可以通过命令行模拟各种应用协议的发包, 包括FTP HTTP HTTPS, 官方网站 http://curl.haxx.se/ ...

  7. 华为OJ平台——统计字符串中的大写字母

    题目描述: 统计字符串中的大写字母的个数 输入: 一行字符串 输出: 字符串中大写字母的个数(当空串时输出0) 思路: 这一题很简单,直接判断字符串中的每一个字符即可,唯一要注意的一点是输入的字符串可 ...

  8. nyoj---t448&lpar;寻找最大数&rpar;

    描述 请在整数 n 中删除m个数字, 使得余下的数字按原次序组成的新数最大, 比如当n=92081346718538,m=10时,则新的最大数是9888   输入 第一行输入一个正整数T,表示有T组测 ...

  9. shell如何将文件上传至ftp

    #!/bin/bash ip=$ port=$ user=$ /usr/bin/lftp -p $port $ip <<EOF user $user $pwd set ftp:ssl-au ...

  10. npm 使用指南参考

    [阮一峰npm scripts基本教程] [rimraf 跨平台删除文件] [ts-loader 安装问题] [nvm 安装使用] [npm镜像的问题] [webpack 如何引入jquery]web ...