1 前言

纹理贴图 中介绍了将矩形图片贴到矩形模型上,本文将介绍:在不裁剪图片的情况下,将正方形的图片贴到圆形模型上。

​ 思考:实数区间 [0, 1] 与 [0, 2] 的元素可以建立一一映射关系么?答案是肯定的,如:y=2x、y=2x2、y=2*ex/e^2、y=2ln(x+1)/ln2、y=2sin(π/2*x) 等等,其中 x∈[0, 1],y∈[0, 2]。

​ 同理,在二维平面上,也可以构造一个函数,使得正方形上的点与圆形上的点一一对应。映射的构建如下图:

​ 原图如下:

​ 映射如下:

​ 读者如果对 OpenGL ES 不太熟悉,请回顾以下内容:

​ 本文完整代码资源见→【OpenGL ES】正方形图片贴到圆形上

​ 项目目录如下:

2 案例

​ MainActivity.java

  1. package com.zhyan8.squaretocircle.activity;
  2. import android.opengl.GLSurfaceView;
  3. import android.os.Bundle;
  4. import androidx.appcompat.app.AppCompatActivity;
  5. import com.zhyan8.squaretocircle.opengl.MyGLSurfaceView;
  6. import com.zhyan8.squaretocircle.opengl.MyRender;
  7. public class MainActivity extends AppCompatActivity {
  8. private GLSurfaceView mGlSurfaceView;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. mGlSurfaceView = new MyGLSurfaceView(this);
  13. setContentView(mGlSurfaceView);
  14. mGlSurfaceView.setRenderer(new MyRender(this));
  15. }
  16. @Override
  17. protected void onResume() {
  18. super.onResume();
  19. mGlSurfaceView.onResume();
  20. }
  21. @Override
  22. protected void onPause() {
  23. super.onPause();
  24. mGlSurfaceView.onPause();
  25. }
  26. }

​ MyGLSurfaceView.java

  1. package com.zhyan8.squaretocircle.opengl;
  2. import android.content.Context;
  3. import android.opengl.GLSurfaceView;
  4. import android.util.AttributeSet;
  5. public class MyGLSurfaceView extends GLSurfaceView {
  6. public MyGLSurfaceView(Context context) {
  7. super(context);
  8. setEGLContextClientVersion(3);
  9. }
  10. public MyGLSurfaceView(Context context, AttributeSet attrs) {
  11. super(context, attrs);
  12. setEGLContextClientVersion(3);
  13. }
  14. }

​ MyRender.java

  1. package com.zhyan8.squaretocircle.opengl;
  2. import android.content.Context;
  3. import android.opengl.GLES30;
  4. import android.opengl.GLSurfaceView;
  5. import com.zhyan8.squaretocircle.model.Model;
  6. import javax.microedition.khronos.egl.EGLConfig;
  7. import javax.microedition.khronos.opengles.GL10;
  8. public class MyRender implements GLSurfaceView.Renderer {
  9. private Context mContext;
  10. private Model mModel;
  11. private int mProgramId;
  12. public MyRender(Context context) {
  13. mContext = context;
  14. mModel = new Model();
  15. }
  16. @Override
  17. public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
  18. //设置背景颜色
  19. GLES30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  20. //创建程序id
  21. mProgramId = mModel.onModelCreate(mContext.getResources());
  22. GLES30.glUseProgram(mProgramId);
  23. }
  24. @Override
  25. public void onSurfaceChanged(GL10 gl, int width, int height) {
  26. //设置视图窗口
  27. GLES30.glViewport(0, 0, width, height);
  28. mModel.onModelChange(width, height);
  29. }
  30. @Override
  31. public void onDrawFrame(GL10 gl) {
  32. //将颜色缓冲区设置为预设的颜色
  33. GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
  34. //启用顶点的数组句柄
  35. GLES30.glEnableVertexAttribArray(0);
  36. GLES30.glEnableVertexAttribArray(1);
  37. //绘制模型
  38. mModel.onModelDraw();
  39. //禁止顶点数组句柄
  40. GLES30.glDisableVertexAttribArray(0);
  41. GLES30.glDisableVertexAttribArray(1);
  42. }
  43. }

​ Model.java

  1. package com.zhyan8.squaretocircle.model;
  2. import android.content.res.Resources;
  3. import android.graphics.Point;
  4. import android.opengl.GLES30;
  5. import com.zhyan8.squaretocircle.R;
  6. import com.zhyan8.squaretocircle.utils.ArraysUtils;
  7. import com.zhyan8.squaretocircle.utils.ShaderUtils;
  8. import com.zhyan8.squaretocircle.utils.TextureUtils;
  9. import java.nio.FloatBuffer;
  10. public class Model {
  11. private static final int ROW_NUM = 60; // 纹理行数
  12. private static final int COL_NUM = 60; // 纹理列数
  13. private static final float ROW_WIDTH = 1.0f / ROW_NUM; // 每行宽度
  14. private static final float COL_WIDTH = 1.0f / COL_NUM; // 每列宽度
  15. private static final float SCALE = 1.0f; // 模型缩放系数
  16. private static final int TEXTURE_DIMENSION = 2; // 纹理坐标维度
  17. private static final int VERTEX_DIMENSION = 3; // 顶点坐标维度
  18. private static final double EPSILON = 0.00000000001; // epsilon,比较小的浮点常量
  19. private MyTransform mTransform = new MyTransform();
  20. private float[][] mTextures;
  21. private float[][] mVertices;
  22. private FloatBuffer[] mTexturesBuffers;
  23. private FloatBuffer[] mVerticesBuffers;
  24. private int mTextureId;
  25. private int mProgramId;
  26. private int mPointNumPerRow;
  27. public Model() {
  28. mPointNumPerRow = (COL_NUM + 1) * 2;
  29. mTextures = new float[ROW_NUM][mPointNumPerRow * TEXTURE_DIMENSION];
  30. mVertices = new float[ROW_NUM][mPointNumPerRow * VERTEX_DIMENSION];
  31. mTexturesBuffers = new FloatBuffer[ROW_NUM];
  32. mVerticesBuffers = new FloatBuffer[ROW_NUM];
  33. }
  34. // 模型创建
  35. public int onModelCreate(Resources resources) {
  36. getTexture();
  37. getVertex();
  38. for (int i = 0; i < ROW_NUM; i++) {
  39. mTexturesBuffers[i] = ArraysUtils.getFloatBuffer(mTextures[i]);
  40. mVerticesBuffers[i] = ArraysUtils.getFloatBuffer(mVertices[i]);
  41. }
  42. mProgramId = ShaderUtils.createProgram(resources, R.raw.vertex_shader, R.raw.fragment_shader);
  43. Point bitmapSize = new Point();
  44. mTextureId = TextureUtils.loadTexture(resources, R.raw.zzz, bitmapSize);
  45. mTransform.onTransformCreate(mProgramId, bitmapSize);
  46. return mProgramId;
  47. }
  48. // 模型参数变化
  49. public void onModelChange(int width, int height) {
  50. mTransform.onTransformChange(width, height);
  51. }
  52. // 模型绘制
  53. public void onModelDraw() {
  54. mTransform.onTransformExecute();
  55. for (int i = 0; i < ROW_NUM; i++) { // 一行一行绘制纹理
  56. //准备顶点坐标和纹理坐标
  57. GLES30.glVertexAttribPointer(0, VERTEX_DIMENSION, GLES30.GL_FLOAT, false, 0, mVerticesBuffers[i]);
  58. GLES30.glVertexAttribPointer(1, TEXTURE_DIMENSION, GLES30.GL_FLOAT, false, 0, mTexturesBuffers[i]);
  59. //激活纹理
  60. GLES30.glActiveTexture(GLES30.GL_TEXTURE);
  61. //绑定纹理
  62. GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mTextureId);
  63. //绘制贴图
  64. GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mPointNumPerRow);
  65. // GLES30.glDrawArrays(GLES30.GL_LINE_STRIP, 0, mPointNumPerRow);
  66. }
  67. }
  68. // 计算纹理坐标
  69. private void getTexture() {
  70. for (int i = 0; i < ROW_NUM; i++) {
  71. int index = 0;
  72. float y1 = i * ROW_WIDTH;
  73. float y2 = y1 + ROW_WIDTH;
  74. float x = 0;
  75. for (int j = 0; j <= COL_NUM; j++) {
  76. mTextures[i][index++] = x;
  77. mTextures[i][index++] = y1;
  78. mTextures[i][index++] = x;
  79. mTextures[i][index++] = y2;
  80. x += COL_WIDTH;
  81. }
  82. }
  83. }
  84. // 计算顶点坐标
  85. private void getVertex() {
  86. for (int i = 0; i < ROW_NUM; i++) {
  87. int index = 0;
  88. for (int j = 0; j < mTextures[i].length; j += TEXTURE_DIMENSION) {
  89. float[] pos = getPosInWorldAxis(mTextures[i][j], mTextures[i][j + 1]);
  90. textureVertexMapping(pos);
  91. mVertices[i][index++] = pos[0] * SCALE;
  92. mVertices[i][index++] = pos[1] * SCALE;
  93. mVertices[i][index++] = pos[2] * SCALE;
  94. }
  95. }
  96. }
  97. // 纹理坐标映射到顶点坐标
  98. private void textureVertexMapping(float[] pos) {
  99. float x = Math.abs(pos[0]);
  100. float y = Math.abs(pos[1]);
  101. double norm = Math.sqrt(x * x + y * y);
  102. if (norm < EPSILON) {
  103. return;
  104. }
  105. double normX = pos[0] / norm; // 归一化坐标
  106. double normY = pos[1] / norm; // 归一化坐标
  107. double rate = x > y ? y / x : x / y; // 短边与长边的比率
  108. double dist = Math.sqrt(1 + rate * rate); // 圆心到正方形边上的距离
  109. double factor = norm / dist; // 相对位置缩放因子
  110. // double adjustNorm = adjustDist(norm);
  111. // double adjustDist = adjustDist(dist);
  112. // double factor = adjustNorm / adjustDist; // 相对位置缩放因子
  113. pos[0] = (float) (normX * fun(factor));
  114. pos[1] = (float) (normY * fun(factor));
  115. }
  116. // 调整距离
  117. private double adjustDist(double dist) {
  118. if (dist < 1) return dist;
  119. double rest = dist - 1;
  120. double more = rest / 2;
  121. return 1 + more;
  122. }
  123. // 因子变换函数
  124. private double fun(double x) {
  125. return x;
  126. // return Math.sqrt(x);
  127. // return Math.pow(x, 0.3);
  128. // return Math.log(x + 1) / Math.log(2);
  129. // return Math.log10(x + 1) / Math.log10(2);
  130. // return Math.sin(Math.PI / 2 * x);
  131. }
  132. //纹理坐标转换为世界坐标
  133. private float[] getPosInWorldAxis(float x, float y) {
  134. float [] pos = new float[VERTEX_DIMENSION];
  135. pos[0] = x * 2 - 1;
  136. pos[1] = 1 - y * 2;
  137. pos[2] = 0f;
  138. return pos;
  139. }
  140. }

​ MyTransform.java

  1. package com.zhyan8.squaretocircle.model;
  2. import android.graphics.Point;
  3. import android.opengl.GLES30;
  4. import android.opengl.Matrix;
  5. public class MyTransform {
  6. private int mProgramId;
  7. private Point mBitmapSize;
  8. private Point mViewSize;
  9. private int mMvpMatrixHandle;
  10. private float[] mMvpMatrix = new float[16];
  11. public void onTransformCreate(int programId, Point bitmapSize) {
  12. mProgramId = programId;
  13. mBitmapSize = bitmapSize;
  14. mMvpMatrixHandle = GLES30.glGetUniformLocation(mProgramId, "mvpMatrix");
  15. }
  16. public void onTransformChange(int width, int height) {
  17. mViewSize = new Point(width, height);
  18. }
  19. //调整图片宽高适配屏幕尺寸
  20. public void onTransformExecute() {
  21. int mapWidth = mBitmapSize.x;
  22. int mapHeight = mBitmapSize.y;
  23. float mapRatio = mapWidth / (float) mapHeight;
  24. float ratio = mViewSize.x / (float) mViewSize.y;
  25. float w = 1.0f;
  26. float h = 1.0f;
  27. if (mapRatio > ratio) { //宽度最大,高度适配
  28. h = mapRatio / ratio;
  29. } else { //高度最大,宽度适配
  30. w = ratio / mapRatio;
  31. }
  32. Matrix.orthoM(mMvpMatrix, 0, -w, w, -h, h,-1, 1);
  33. GLES30.glUniformMatrix4fv(mMvpMatrixHandle, 1, false, mMvpMatrix, 0);
  34. }
  35. }

​ ShaderUtils.java

  1. package com.zhyan8.squaretocircle.utils;
  2. import android.content.res.Resources;
  3. import android.opengl.GLES30;
  4. import java.io.BufferedReader;
  5. import java.io.InputStream;
  6. import java.io.InputStreamReader;
  7. public class ShaderUtils {
  8. //创建程序id
  9. public static int createProgram(Resources resources, int vertexShaderResId, int fragmentShaderResId) {
  10. final int vertexShaderId = compileShader(resources, GLES30.GL_VERTEX_SHADER, vertexShaderResId);
  11. final int fragmentShaderId = compileShader(resources, GLES30.GL_FRAGMENT_SHADER, fragmentShaderResId);
  12. return linkProgram(vertexShaderId, fragmentShaderId);
  13. }
  14. //通过外部资源编译着色器
  15. private static int compileShader(Resources resources, int type, int shaderId){
  16. String shaderCode = readShaderFromResource(resources, shaderId);
  17. return compileShader(type, shaderCode);
  18. }
  19. //通过代码片段编译着色器
  20. private static int compileShader(int type, String shaderCode){
  21. int shader = GLES30.glCreateShader(type);
  22. GLES30.glShaderSource(shader, shaderCode);
  23. GLES30.glCompileShader(shader);
  24. return shader;
  25. }
  26. //链接到着色器
  27. private static int linkProgram(int vertexShaderId, int fragmentShaderId) {
  28. final int programId = GLES30.glCreateProgram();
  29. //将顶点着色器加入到程序
  30. GLES30.glAttachShader(programId, vertexShaderId);
  31. //将片元着色器加入到程序
  32. GLES30.glAttachShader(programId, fragmentShaderId);
  33. //链接着色器程序
  34. GLES30.glLinkProgram(programId);
  35. return programId;
  36. }
  37. //从shader文件读出字符串
  38. private static String readShaderFromResource(Resources resources, int shaderId) {
  39. InputStream is = resources.openRawResource(shaderId);
  40. BufferedReader br = new BufferedReader(new InputStreamReader(is));
  41. String line;
  42. StringBuilder sb = new StringBuilder();
  43. try {
  44. while ((line = br.readLine()) != null) {
  45. sb.append(line);
  46. sb.append("\n");
  47. }
  48. br.close();
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. return sb.toString();
  53. }
  54. }

​ TextureUtils.java

  1. package com.zhyan8.squaretocircle.utils;
  2. import android.content.res.Resources;
  3. import android.graphics.Bitmap;
  4. import android.graphics.BitmapFactory;
  5. import android.graphics.Point;
  6. import android.opengl.GLES30;
  7. import android.opengl.GLUtils;
  8. public class TextureUtils {
  9. //加载纹理贴图
  10. public static int loadTexture(Resources resources, int resourceId, Point bitmapSize) {
  11. BitmapFactory.Options options = new BitmapFactory.Options();
  12. options.inScaled = false;
  13. Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId, options);
  14. bitmapSize.set(bitmap.getWidth(), bitmap.getHeight());
  15. final int[] textureIds = new int[1];
  16. // 生成纹理id
  17. GLES30.glGenTextures(1, textureIds, 0);
  18. // 绑定纹理到OpenGL
  19. GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureIds[0]);
  20. GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR);
  21. GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
  22. // 加载bitmap到纹理中
  23. GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0);
  24. // 生成MIP贴图
  25. GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);
  26. // 取消绑定纹理
  27. GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
  28. return textureIds[0];
  29. }
  30. }

​ ArraysUtils.java

  1. package com.zhyan8.squaretocircle.utils;
  2. import java.nio.ByteBuffer;
  3. import java.nio.ByteOrder;
  4. import java.nio.FloatBuffer;
  5. public class ArraysUtils {
  6. public static FloatBuffer getFloatBuffer(float[] floatArr) {
  7. FloatBuffer fb = ByteBuffer.allocateDirect(floatArr.length * Float.BYTES)
  8. .order(ByteOrder.nativeOrder())
  9. .asFloatBuffer();
  10. fb.put(floatArr);
  11. fb.position(0);
  12. return fb;
  13. }
  14. }

​ vertex_shader.glsl

  1. #version 300 es
  2. layout (location = 0) in vec4 vPosition;
  3. layout (location = 1) in vec2 aTextureCoord;
  4. uniform mat4 mvpMatrix;
  5. out vec2 vTexCoord;
  6. void main() {
  7. gl_Position = mvpMatrix * vPosition;
  8. vTexCoord = aTextureCoord;
  9. }

​ 顶点着色器的作用:进行矩阵变换位置、根据光照公式计算顶点颜⾊、⽣成 / 变换纹理坐标,并且把位置和纹理坐标发送到片元着色器。

​ 顶点着色器中,如果没有指定默认精度,则 int 和 float 的默认精度都为 highp。

​ fragment_shader.glsl

  1. #version 300 es
  2. precision mediump float;
  3. uniform sampler2D uTextureUnit;
  4. in vec2 vTexCoord;
  5. out vec4 fragColor;
  6. void main() {
  7. fragColor = texture(uTextureUnit,vTexCoord);
  8. }

​ 片元着色器的作用:处理经光栅化阶段生成的每个片元,计算每个像素的颜色和透明度。

​ 在片元着色器中,浮点值没有默认的精度值,每个着色器必须声明一个默认的 float 精度。

3 运行效果

1)因子变换函数:y=x

2)因子变换函数:y=sqrt(x)

3)因子变换函数:y=log10(1+x)/log10(2)

4)因子变换函数:y=sin(πx/2)

5)因子变换函数:y=x,对距离进行调整

​ 鉴于以上图片头发都鼓起一个大包,对距离进行调整,如下:

  1. double adjustNorm = adjustDist(norm);
  2. double adjustDist = adjustDist(dist);
  3. double factor = adjustNorm / adjustDist; // 相对位置缩放因子
  4. // 调整距离
  5. private double adjustDist(double dist) {
  6. if (dist < 1) return dist;
  7. double rest = dist - 1;
  8. double more = rest / 2;
  9. return 1 + more;
  10. }

​ 效果如下:

​ 虽然头发也有个小包,但比前面4种方案小了很多。

​ 声明:本文转自【OpenGL ES】正方形图片贴到圆形上

【OpenGL ES】正方形图片贴到圆形上的更多相关文章

  1. OpenGL ES: (2) OpenGL ES 与 EGL、GLSL的关系

    OpenGL ES 是负责 GPU 工作的,目的是通过 GPU 计算,得到一张图片,这张图片在内存中其实就是一块 buffer,存储有每个点的颜色信息等.而这张图片最终是要显示到屏幕上,所以还需要具体 ...

  2. OpenGL ES: (5) OpenGL的基本概念、OpenGL ES 在屏幕产生图片的过程、OpenGL管线(pipeline)

    一. OpenGL的基本概念 OpenGL 的结构可以从逻辑上划分为下面 3 个部分: 图元(Primitives) 缓冲区(Buffers) 光栅化(Rasterize) 图元(Primitives ...

  3. Android OpenGL ES 开发(九): OpenGL ES 纹理贴图

    一.概念 一般说来,纹理是表示物体表面的一幅或几幅二维图形,也称纹理贴图(texture).当把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实.当前流行的图形系统中,纹理绘制已经成为 ...

  4. 一篇通俗易懂的讲解OpenGL ES的文章

    电脑或者手机上做图像处理有很多方式,但是目前为止最高效的方法是有效地使用图形处理单元,或者叫 GPU.你的手机包含两个不同的处理单元,CPU 和 GPU.CPU 是个多面手,并且不得不处理所有的事情, ...

  5. OpenGL ES学习笔记(三)——纹理

    首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...

  6. OpenGL ES 3.0 图元装配

    1. 前言 之前已经把纹理的渲染给弄出来了,但是又遇到一个新的问题,那就是图元装配,比如说我已经把图片给显示出来了,但是呢,并没有做到让它显示到具体的位置,而跟这个位置相关的则需要靠图元装配. 图元装 ...

  7. Opengl ES 1.x NDK实例开发之六:纹理贴图

    开发框架介绍请參见:Opengl ES NDK实例开发之中的一个:搭建开发框架 本章在第三章(Opengl ES 1.x NDK实例开发之三:多边形的旋转)的基础上演示怎样使用纹理贴图,分别实现了三角 ...

  8. Android OpenGL ES 画球体

    近期由于兴趣所向.開始学习OpenGL绘图. 本文以"画球体"为点,小结一下近期所学. > 初识OpenGL ES 接触OpenGL是从Android開始的.众所周知,And ...

  9. Android OpenGL ES(七)----理解纹理与纹理过滤

    1.理解纹理 OpenGL中的纹理能够用来表示图像.照片,甚至由一个数学算法生成的分形数据.每一个二维的纹理都由很多小的纹理元素组成.它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最 ...

  10. Opengl ES之纹理贴图

    纹理可以理解为一个二维数组,它可以存储大量的数据,这些数据可以发送到着色器上.一般情况下我们所说的纹理是表示一副2D图,此时纹理存储的数据就是这个图的像素数据. 所谓的纹理贴图,就是使用Opengl将 ...

随机推荐

  1. 调整PR界面字体大小

    1.问题 界面字体太大或者太小,看得不舒服 2.解决问题 按住ctrl+F12,调出如下工作台 选择Debug Datatbase View 其中找到AdobeCleanFontSize,并修改 重启 ...

  2. html监听标签的resize

    <html> <body> <div id="div1" style="width:100%;height:100%;"> ...

  3. Pickle反序列化学习

    什么是Pickle? 很简单,就是一个python的序列化模块,方便对象的传输与存储.但是pickle的灵活度很高,可以通过对opcode的编写来实现代码执行的效果,由此引发一系列的安全问题 Pick ...

  4. SkyWalking的学习之三

    SkyWalking的学习之三 持续优化 SkyWalking 默认可以使用h2,但是感觉容量和性能都可能不太好 所以我想使用一下elasticSearch进行替换. 自己其实一直想心想去学习, 但是 ...

  5. SQLServer解决deadlock问题的一个场景

    SQLServer解决deadlock问题的一个场景 背景 公司产品出现过很多次dead lock 跟研发讨论了很久, 都没有具体的解决思路 但是这边知道了一个SQLServer数据库上面计划100% ...

  6. [转帖]perf学习-linux自带性能分析工具

    目前在做性能分析的事情,之前没怎么接触perf,找了几篇文章梳理了一下,按照问题的形式记录在这里. 方便自己查看.   什么是perf? linux性能调优工具,32内核以上自带的工具,软件性能分析. ...

  7. [转帖]Tiup 常用运维操作命令干货

    https://zhuanlan.zhihu.com/p/356031031 **导读**> 作者:杨漆> 16年关系型数据库管理,从oracle 9i .10g.11g.12c到Mysq ...

  8. 【转帖】SmartNIC — TSO、GSO、LRO、GRO 技术

    目录 文章目录 目录 TSO(TCP Segmentation Offload) GSO(Generic Segmentation Offload) LRO(Large Receive Offload ...

  9. 是否开启raid卡缓存的影响

    开启raid卡缓存 Write back 对IO性能的影响 背景 公司买了一台服务器. 想进行一下升级 但是因为管理员担心数据丢失, 使用了write through + (raid6 + hotsp ...

  10. SpringBoot 连接Oracle 12c 以上版本PDB的解决思路

    1. 最近公司产品改用springboot开发, 要支持企业级大型数据库Oracle ,并且版本要求比较高,需要使用Oracle12c以上. 又因为Oracle 12c 以上有了一个PDB的可插拔数据 ...