十四、混合

news2025/2/23 23:37:37

第一部分 概念:

1) 引入

OpenGL ES 混合本质上是将 2 个片元的颜色进行调和,产生一个新的颜色。OpenGL ES 混合发生在片元通过各项测试之后,准备进入帧缓冲区的片元和原有的片元按照特定比例加权计算出最终片元的颜色值,不再是新(源)片元直接覆盖缓冲区中的(目标)片元。

在这里插入图片描述

2)应用

启用 OpenGL ES 混合使用 需要在绘画前启动glEnable(GL_BLEND);

然后通过 void glBlendFunc(GLenum sfactor, GLenum dfactor); 设置混合的方式,其中 sfactor 表示源因子,dfactor 表示目标因子。

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// GL_SRC_ALPHA 表示源因子取值为源颜色的 alpha
// GL_ONE_MINUS_SRC_ALPHA 表示目标因子取值为 1- alpha(源颜色的 alpha)

// 操作符默认为 GL_FUNC_ADD ,即加权相加。
// 混合公式变成了 源颜色向量 × alpha + 目标颜色向量 × (1- alpha)

在这里插入图片描述

默认的操作符是加号,我们也可以通过void glBlendEquation(GLenum mode)接口来自定义设置。

GL_FUNC_ADD:默认的,彼此元素相加

GL_FUNC_SUBTRACT:彼此元素相减

GL_FUNC_REVERSE_SUBTRACT:彼此元素相减,但顺序相反

GL_MIN:混合结果的 4 个通道值分别取 2 元素中 4 个通道较小的值

GL_MAX:混合结果的 4 个通道值分别取 2 元素中 4 个通道较大的值

glBlendFuncSeperate为 RGB 和 alpha 通道各自设置不同的混合因子

//对 RGB 和 Alpha 分别设置 BLEND 函数

void glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha);

glBlendFuncSeperate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE, GL_ZERO);
上面就表示
混合结果颜色 RGB 向量 = 源颜色 RGB 向量 × alpha + 目标颜色 RGB 向量 × (1- alpha);
混合结果颜色 alpha = 源颜色 alpha × 1 + 目标颜色 alpha × 0;

这个也是默认为+号,但是可以通过glBlendEquationSeparate为 RGB 和 alpha 通道各自设置不同操作符。void glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha);

另外需要格外注意的是,开启混合和深度测试绘制透明物体时,需要遵循物体距观察者(Camera)的距离,由远到近开始绘制,这样可以避免由于深度测试开启后(在透明物体后面)丢弃片元造成的奇怪现象。

第二部分 实践:

1)java部分

java部分在绘制部分都是跟之前一致的,只是因为混合使用到了图片的RGBA中A的维度,需要将32位的png图片在java端转换为具体的RGBA数据传递到JNI去。

NativeImpl.java

public class NativeImpl {
	。。。。
	//多出这个native接口
	public static native void native_SetImageDataWithIndex(int index, int width,int height, byte[] byteArray);
}

MyGLSurfaceView.java

public class MyGLSurfaceView extends GLSurfaceView implements ScaleGestureDetector.OnScaleGestureListener{
	 public MyGLSurfaceView(Context context) {
	 	...
	 	
	 	//开始的时候就把内容主动传递到
	 	loadRGBAImage(R.drawable.board_texture,0);
        loadRGBAImage(R.drawable.floor,1);
        loadRGBAImage(R.drawable.window,2);
	 }
	private Bitmap loadRGBAImage(int resId, int index) {
        InputStream is = this.getResources().openRawResource(resId);
        Bitmap bitmap;
        try {
            bitmap = BitmapFactory.decodeStream(is);
            if (bitmap != null) {
                int bytes = bitmap.getByteCount();
                ByteBuffer buf = ByteBuffer.allocate(bytes);
                bitmap.copyPixelsToBuffer(buf);
                byte[] byteArray = buf.array();
                renderer.setImageDataWithIndex(index, bitmap.getWidth(), bitmap.getHeight(), byteArray);
            }
        }
        finally
        {
            try
            {
                is.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
        return bitmap;
    }
    
    
    ...
    
    private class MyRenderer implements Renderer {
    	...
    	public void setImageDataWithIndex(int index, int width, int height, byte[] bytes) {
            NativeImpl.native_SetImageDataWithIndex(index, width, height, bytes);
        }
    }
}

2)C++部分

NativeGL.cpp

多出
std::vector<struct ImageTyep> vcImage;
/*
 * Class:     com_example_nineblending_native_SetImageDataWithIndex
 * Method:    native_SetImageDataWithIndex
 * Signature: (III[B)V
 */
JNIEXPORT void JNICALL native_SetImageDataWithIndex(JNIEnv *env, jobject instance, jint index, jint width, jint height, jbyteArray byteArray)
{
	struct ImageTyep itype;
	int len = env->GetArrayLength (byteArray);
	uint8_t* buf = new uint8_t[len];
	env->GetByteArrayRegion(byteArray, 0, len, reinterpret_cast<jbyte*>(buf));
	itype.data = buf;
	itype.width =width;
	itype.height = height;
	vcImage.push_back(itype);
	LOGD("native_SetImageDataWithIndex  width=%d height =  height", width, height);
	//env->DeleteLocalRef(byteArray);
}

Blending.h

//
// Created by CreatWall_zhouwen on 2023/5/15.
//

#ifndef NINEBLENDING_BLENDING_H
#define NINEBLENDING_BLENDING_H
#include <GLES3/gl3.h>
#include <detail/type_mat.hpp>
#include <detail/type_mat4x4.hpp>
#include <vector>
#include <map>
#include "Const.h"
#define MATH_PI 3.1415926535897932384626433832802
#define RENDER_IMG_NUM 3
class Blending {
public:
    Blending();
    ~Blending();
    void CreateProgram(const char *ver, const char *frag);
    void Draw();
    void getTexturedata(std::vector<struct ImageTyep> vcImagetemp);
    static Blending* GetInstance();
    static void DestroyInstance();
    void UpdateTransformMatrix(float rotateX, float rotateY, float scaleX, float scaleY);
    void UpdateMatrix(glm::mat4 &mvpMatrix, int angleXRotate, int angleYRotate, float scale, glm::vec3 transVec3, float ratio);
    void OnSurfaceChanged(int width, int height);
private:
    GLuint program;
    GLuint vertexShaderHandle;
    GLuint fragShaderHandle;

    GLuint m_TextureIds[RENDER_IMG_NUM];
    GLint m_SamplerLoc;
    GLint m_MVPMatLoc;

    GLuint m_VaoIds[3];
    GLuint m_VboIds[3];
    std::vector<struct ImageTyep> m_vcImage;
    glm::mat4 m_MVPMatrix;

    std::vector<glm::vec3> windowsTrans;
    std::map<GLfloat, glm::vec3> sorted;

    int m_AngleX;
    int m_AngleY;
    int Srceenwidth;
    int Srceenheight;
};


#endif //NINEBLENDING_BLENDING_H

Blending.cpp

//
// Created by CreatWall_zhouwen on 2023/5/15.
//

#include "Blending.h"
#include "Util.h"
#include "GLUtil.h"
#include <gtc/matrix_transform.hpp>
Blending* m_pContext = nullptr;
#define TAG "DRAWTEXTURE"
GLfloat boxVertices[] = {
      //position            //texture coord
      -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 flatVertices[] = {
      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 windowVertices[] = {
      0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
      0.0f, -0.5f,  0.0f,  0.0f,  1.0f,
      1.0f, -0.5f,  0.0f,  1.0f,  1.0f,

      0.0f,  0.5f,  0.0f,  0.0f,  0.0f,
      1.0f, -0.5f,  0.0f,  1.0f,  1.0f,
      1.0f,  0.5f,  0.0f,  1.0f,  0.0f
};

Blending::Blending() {
    m_SamplerLoc = GL_NONE;
   m_MVPMatLoc = GL_NONE;

   m_AngleX = 0;
   m_AngleY = 0;
   Srceenwidth =  1080;
   Srceenheight = 2115;
}

Blending::~Blending() {

}

void Blending::CreateProgram(const char *ver, const char *frag) {
   LOGD("CreateProgram Enter");
   // 编译链接用于离屏渲染的着色器程序
   program = CreateGLProgram(ver, frag, vertexShaderHandle, fragShaderHandle);
   if (program == GL_NONE)
   {
      LOGD("FBOSample::Init m_ProgramObj == GL_NONE");
      return;
   }
   LOGD("CreateGLProgram Success");
   m_SamplerLoc = glGetUniformLocation(program, "s_TextureMap");
   m_MVPMatLoc = glGetUniformLocation(program, "u_MVPMatrix");
   //创建VBO
   glGenBuffers(3, m_VboIds);
   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]);
   glBufferData(GL_ARRAY_BUFFER, sizeof(boxVertices), boxVertices, GL_STATIC_DRAW);

   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]);
   glBufferData(GL_ARRAY_BUFFER, sizeof(flatVertices), flatVertices, GL_STATIC_DRAW);

   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[2]);
   glBufferData(GL_ARRAY_BUFFER, sizeof(windowVertices), windowVertices, GL_STATIC_DRAW);

   //创建VAO并绑定VBO
   glGenVertexArrays(3, m_VaoIds);

   glBindVertexArray(m_VaoIds[0]);
   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]);
   glEnableVertexAttribArray(0);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) 0);
   glEnableVertexAttribArray(1);
   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) (3* sizeof(GLfloat)));
   glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);
   glBindVertexArray(GL_NONE);

   glBindVertexArray(m_VaoIds[1]);
   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[1]);
   glEnableVertexAttribArray(0);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) 0);
   glEnableVertexAttribArray(1);
   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) (3* sizeof(GLfloat)));
   glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);
   glBindVertexArray(GL_NONE);

   glBindVertexArray(m_VaoIds[2]);
   glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[2]);
   glEnableVertexAttribArray(0);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) 0);
   glEnableVertexAttribArray(1);
   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (const void *) (3* sizeof(GLfloat)));
   glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);
   glBindVertexArray(GL_NONE);

   //创建纹理并绑定数据
   glGenTextures(RENDER_IMG_NUM, m_TextureIds);
   for (int i = 0; i < RENDER_IMG_NUM; ++i)
   {
      glActiveTexture(GL_TEXTURE0 + i);
      glBindTexture(GL_TEXTURE_2D, m_TextureIds[i]);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      glTexParameterf(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);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_vcImage[i].width, m_vcImage[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_vcImage[i].data);
      LOGD("width = %d, height = %d",m_vcImage[i].width, m_vcImage[i].height);
      glBindTexture(GL_TEXTURE_2D, GL_NONE);
   }

    //布局参数
    windowsTrans.push_back(glm::vec3(-1.5f,  0.0f, -0.48f));
    windowsTrans.push_back(glm::vec3( 1.5f,  0.0f,  0.51f));
    windowsTrans.push_back(glm::vec3( 0.0f,  0.0f,  0.7f));
    windowsTrans.push_back(glm::vec3(-0.3f,  0.0f, -2.3f));
    windowsTrans.push_back(glm::vec3( 0.5f,  0.0f, -0.6f));
    for (GLuint i = 0; i < windowsTrans.size(); i++)
    {
        GLfloat distance = std::sqrt(std::pow(windowsTrans[i].x - 0.5f, 2.0f) + std::pow(windowsTrans[i].y - 1.0f, 2.0f) + std::pow(windowsTrans[i].z - 3.0f, 2.0f));
        sorted[distance] = windowsTrans[i];
    }
}

void Blending::Draw() {
   float ratio = (float)Srceenwidth / Srceenheight;
   glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
   glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glEnable(GL_DEPTH_TEST);//开启深度测试
   glEnable(GL_BLEND);//开启混合
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//源颜色向量 × alpha + 目标颜色向量 × (1- alpha)

   glUseProgram(program);

   glBindVertexArray(m_VaoIds[0]);
   // Bind the RGBA map
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, m_TextureIds[0]);
   glUniform1i(m_SamplerLoc, 0);

   UpdateMatrix(m_MVPMatrix, 0, 0, 1.0,  glm::vec3(-1.0f, 0.0f, -1.0f), ratio);
   glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
   glDrawArrays(GL_TRIANGLES, 0, 36);

   UpdateMatrix(m_MVPMatrix, 0, 0, 1.0,  glm::vec3(2.0f, 0.0f, 0.0f), ratio);
   glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
   glDrawArrays(GL_TRIANGLES, 0, 36);

   glBindVertexArray(0);

   glBindVertexArray(m_VaoIds[1]);
   // Bind the RGBA map
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, m_TextureIds[1]);
   glUniform1i(m_SamplerLoc, 0);

   UpdateMatrix(m_MVPMatrix, 0, 0, 1.0, glm::vec3(0.0f,  0.0f,  0.0f), ratio);
   glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
   glDrawArrays(GL_TRIANGLES, 0, 6);
   glBindVertexArray(0);

   glBindVertexArray(m_VaoIds[2]);
   // Bind the RGBA map
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, m_TextureIds[2]);
   glUniform1i(m_SamplerLoc, 0);

   for (auto it = sorted.rbegin(); it != sorted.rend(); ++it)
   {
      UpdateMatrix(m_MVPMatrix, 0, 0 , 1.0, it->second, ratio);
      glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
      glDrawArrays(GL_TRIANGLES, 0, 6);
   }

   glBindVertexArray(0);

   glDisable(GL_DEPTH_TEST);
   glDisable(GL_BLEND);
}

void Blending::getTexturedata(std::vector<struct ImageTyep> vcImagetemp) {
   m_vcImage = vcImagetemp;
}

Blending *Blending::GetInstance() {
   if (m_pContext == nullptr)
   {
      m_pContext = new Blending();
   }
   return m_pContext;
}

void Blending::DestroyInstance() {
   if (m_pContext)
   {
      delete m_pContext;
      m_pContext = nullptr;
   }
}

void Blending::UpdateTransformMatrix(float rotateX, float rotateY, float scaleX, float scaleY) {
   m_AngleX = static_cast<int>(rotateX);
   m_AngleY = static_cast<int>(rotateY);
}

void Blending::UpdateMatrix(glm::mat4 &mvpMatrix, int angleXRotate, int angleYRotate, float scale,
                            glm::vec3 transVec3, float ratio) {
   LOGD("BlendingSample::UpdateMatrix angleX = %d, angleY = %d, ratio = %f", angleXRotate,
         angleYRotate, ratio);
   angleXRotate = angleXRotate % 360;
   angleYRotate = angleYRotate % 360;

   //转化为弧度角
   float radiansX = static_cast<float>(MATH_PI / 180.0f * angleXRotate);
   float radiansY = static_cast<float>(MATH_PI / 180.0f * angleYRotate);


   // Projection matrix
   //glm::mat4 Projection = glm::ortho(-ratio, ratio, -1.0f, 1.0f, 0.0f, 100.0f);
   //glm::mat4 Projection = glm::frustum(-ratio, ratio, -1.0f, 1.0f, 4.0f, 100.0f);
   glm::mat4 Projection = glm::perspective(45.0f, ratio, 0.1f, 100.f);

   // View matrix
   glm::mat4 View = glm::lookAt(
         glm::vec3(0.5, 1, 3), // Camera is at (0,0,1), in World Space
         glm::vec3(0, 0, 0), // and looks at the origin
         glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
   );

   // Model matrix
   glm::mat4 Model = glm::mat4(1.0f);
   Model = glm::scale(Model, glm::vec3(scale, scale, scale));
   Model = glm::rotate(Model, radiansX, glm::vec3(1.0f, 0.0f, 0.0f));
   Model = glm::rotate(Model, radiansY, glm::vec3(0.0f, 1.0f, 0.0f));
   Model = glm::translate(Model, transVec3);

   mvpMatrix = Projection * View * Model;
}

void Blending::OnSurfaceChanged(int width, int height) {
   Srceenwidth = width;
   Srceenheight = height;
   LOGD("OnSurfaceChanged Srceenwidth = %d, Srceenheight = %d, ratio = %f", Srceenwidth,Srceenheight);
}

#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

07SpringCloud Gateway服务网关

目标 目标 1、服务网关 Gateway 2、ServerWebExchange 3、Gateway使用Bucket4j限流 服务网关Gateway API 网关是一个服务&#xff0c;是系统的唯一入口。从面向对象设计的角度看&#xff0c;它与外观模式类似。API 网关封装了系统内部架构&#xff0c;为每个客户端提供一…

数据湖和数据仓库区别介绍

从数据仓库到数据湖 仓库和湖泊 仓库是人为提前建造好的&#xff0c;有货架&#xff0c;还有过道&#xff0c;并且还可以进一步为放置到货架的物品指定位置。 而湖泊是液态的&#xff0c;是不断变化的、没有固定形态的&#xff0c;基本上是没有结构的&#xff0c;湖泊可以是由…

项目上线出Bug!为什么你作为测试没测出来?

材料收集 你服务于一个数据库查询业务&#xff0c;某次客户现场反馈查询某个语句长时间未返回结果&#xff0c;耗时已经远远超过项目对外提供的性能报告承诺给用户最长查询时间。 问题和相关日志已经传递回来&#xff0c;开发人员进行原因分析和故障修复&#xff0c;测试人员进…

Ubuntu系统denyhosts的使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、denyhosts是什么&#xff1f;二、安装denyhosts1.下载安装包2.安装3.配置4.启动5.测试 总结 前言 今天服务器又被攻击了&#xff0c;防火墙也打开了&#…

劝退忠告:外包实在是太坑了,划水三年,感觉人都废了

先说一下自己的情况&#xff0c;专科生&#xff0c;19年通过校招进入杭州某个外包软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了3年的功…

Linux使用者必备-13款厉害到让人怒赞的工具大揭秘

本文介绍几款 Linux 运维比较实用的工具&#xff0c;希望对 Linux 管理员有所帮助。 1、查看进程占用带宽情况-Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽。 下载&#xff1a;http://sourceforge.net/projects/nethogs/files/nethogs…

【MVS+DepthFilter】video-based real-time multi view stereo

1.SVO 半直接视觉里程计 2. SVO2系列之深度滤波DepthFilter 3. SVO&#xff08;SVO: fast semi-direct monocular visual odometry&#xff09; 4. svo_note 5. MVSDepthFilter: video-based real-time multi view stereo 6. 作者George Vogiatzis主页 video-based real-time m…

Java版Spring cloud 企业电子招投标系统源码

一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点&#xff1a;对草稿进行编辑&#x…

Pytorch版本的Ernie Health源码详解

Pytorch版本的Ernie Health源码详解 一、目录架构 二、尝试使用Ernie Health import torch # 查看torch版本 torch.__version__ 1.12.0cpu# 查看设备是否有GPU资源 # device torch.device(cuda:0 if torch.cuda.is_available() else cpu) device cuda if torch.cuda.is_ava…

I.MX6ULL_Linux_驱动篇(37) linux系统定时器

定时器是我们最常用到的功能&#xff0c;一般用来完成定时功能&#xff0c;本章我们就来学习一下 Linux 内核提供的定时器 API 函数&#xff0c;通过这些定时器 API 函数我们可以完成很多要求定时的应用。 Linux内核也提供了短延时函数&#xff0c;比如微秒、纳秒、毫秒延时函数…

Python selenium爬取影评生成词云图

文章目录 问题描述效果截图如下问题分析前期准备完整代码及解释字体素材 问题描述 通过中文分词、过滤停用词、生成词云图等步骤对评论数据进行处理和可视化。 效果截图如下 非常nice 问题分析 该程序需要使用 Selenium 库来模拟浏览器操作&#xff0c;因此需要下载安装 Chr…

@Autowired VS @Resource

一、两者的区别 首先&#xff0c;两者都是通过注解来实现依赖注入 。不同的话有以下几点&#xff1a; Autowired 是 Spring 提供的注解&#xff0c;所以只有 Spring 的 IoC容器 支持该注解。Resource 是 JSR-250 提供的&#xff08;是 Java 的标准 &#xff09;&#xff0c;我…

CnOpenData·A股上市公司标准数据

一、数据简介 按照《中华人民共和国标准化法》的定义&#xff0c;标准是指农业、工业、服务业以及社会事业等领域需要统一的技术要求。标准作为一种通用性的规范语言&#xff0c;在合理利用国家资源、保障产品质量、提高市场信任度、促进商品流通、维护公平竞争、保障安全等方面…

Hash算法的特点、应用和实现方法详解

什么是Hash算法&#xff1f;Hash算法&#xff0c;简称散列算法&#xff0c;也成哈希算法&#xff08;英译&#xff09;&#xff0c;是将一个大文件映射成一个小串字符。与指纹一样&#xff0c;就是以较短的信息来保证文件的唯一性的标志&#xff0c;这种标志与文件的每一个字节…

企业数字化转型必看的6本书

导读 >> 2023年数据产业将为企业带来新的价值增量&#xff0c;成为企业数字化转型的重要突破口。数字化已经成为商业的一种基本常识&#xff0c;未来企业都将是数字化企业。然而在数字化转型话题热议的当下&#xff0c;真正成果显著的企业仍是少数&#xff0c;2023年企业…

如何阻止Windows Update更新Windows 10中的特定设备驱动程序

如果你想禁用Windows 10驱动程序的自动更新,那么方法有的是,但是如果你想禁用特定设备的驱动程序更新,该怎么办呢? 幸运的是,有一种替代方法可以禁用特定设备的驱动程序更新。你可以通过设置组策略“禁止安装与这些设备ID匹配的设备”来实现这一点。 根据微软的说法: …

在简历上写了“精通”后,我差点被面试官问到窒息....

前言 如果有真才实学&#xff0c;写个精通可以让面试官眼前一亮&#xff01; 如果是瞎写&#xff1f;基本就要被狠狠地虐一把里&#xff01; 最近在面试&#xff0c;我现在十分后悔在简历上写了“精通”二字… 先给大家看看我简历上的技能列表&#xff1a; 熟悉软件测试理…

阿里云服务器25565端口开通教程(ECS和轻量)

阿里云服务器25565端口怎么开通&#xff1f;ECS云服务器端口在安全组中开启&#xff0c;轻量应用服务器端口在防火墙中打开&#xff0c;我的世界mc服务器依赖25565端口&#xff0c;阿里云服务器网来详细说下云服务器ECS和轻量应用服务器开通25565端口的方法&#xff1a; 云服务…

学成在线项目note

目录 一、index.html 1、头部header 2、轮播图banner 3、精品推荐 4、精品推荐课程 5、footer 二、index.css 1、重要的代码 一、index.html <!-- 网站的首页, 所有网站的首页都叫index.html, 因为服务器找首页都是找index.html --> <!-- 布局: 从外到内, 从上到…

青岛科技大学|物联网工程|物联网定位技术(第三讲)|15:40

目录 物联网定位技术&#xff08;第三讲&#xff09; 1. 试简述C/A码的作用、构成 请画出C/A码生成电路简图并给予原理性的说明 2. 试简述 P码的作用、构成 请画出P码生成电路简图&#xff0c;并给予原理性的说明 3. GPS信号是如何进行伪码扩频与解扩 请画图给予说明 4…