openGL系列文章目录

文章目录

  • openGL系列文章目录
  • 前言
  • 一、高度贴图是什么
  • 二、代码
    • 1.c++主程序
    • 2.着色器程序
  • 运行效果
  • 源码下载

前言

不少模型都会附带以“bump”为名结尾的贴图,这种帖图统称为凹凸贴图,目的是为了体现出物体的凹凸不平,最经典的例子就是法线贴图,有兴趣的朋友可以看看。除此之外还有高度贴图、浮雕贴图等,不过这里暂时先只了解高度帖图吧
高度贴图又称视差贴图,用于直接给予纹理显示上的错觉,视差贴图往往都是黑白图,因为理论上只需要知道每个纹理的深度值,因此RGB三个值都是相等的,就如下:
如果对应的像素是黑色的,意味着此纹理的高度为0,也就是默认值,如果一张高度图为全黑那就相当于没有高度图一样,像素点越接近白色,就代表着当前像素点越“凹”,之前渲染的地板看上去有点花,就如下:

一、高度贴图是什么

现在我们扩展法线贴图的概念——从纹理图像用于扰动法向量到扰乱顶点位置本身。实
际上,以这种方式修改对象的几何体具有一定的优势,例如使表面特征沿着对象的边缘可
见,并使特征能够响应阴影贴图。我们将会看到,它还可以帮助构建地形。
一种实用的方法是使用纹理图像来存储高度值,然后使用该高度值来提升(或降低)顶
点位置。含有高度信息的图像称为高度图,使用高度图更改对象的顶点的方法称为高度贴
图①。高度图通常将高度信息编码为灰度颜色:(0,0,0)(黑色)=低高度,(1,1,1)(白色)=
高高度。这样一来通过算法或使用“画图”程序就可以轻松创建高度图。图像的对比度越
高,其表示的高度变化越大。这些概念将在图10.12(显示随机生成的地图)和图10.13(显
示有组织的模式的地图)中说明。

二、代码

1.c++主程序

#include "glew/glew.h"
#include "glfw/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "camera.h"
#include "Utils.h"
#include "Sphere.h"
#include <iostream>
#include <fstream>
#include <string>using namespace std;static const int screenWidth = 1920;
static const int screenHeight = 1080;
int width = 0, height = 0;static const float pai = 3.1415926f;
float toRadians(float degrees) { return degrees * 2.f * pai / (float)360.f; }static const int numVAOs = 1;
static const int numVBOs = 4;float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float sphereX = 0.f, sphereY = 0.f, sphereZ = 0.f;
float lightLocX = 0.f, lightLocY = 0.f, lightLocZ = 0.f;GLuint renderingProgram = 0;
GLuint vao[numVAOs] = { 0 };
GLuint vbo[numVBOs] = { 0 };// variable allocation for display
GLuint mvLoc = 0, projLoc = 0, nLoc = 0;
GLuint globalAmbLoc = 0, ambLoc = 0, diffLoc = 0, specLoc = 0, posLoc = 0, mAmbLoc = 0, mDiffLoc = 0, mSpecLoc = 0, mShinLoc = 0;
float aspect = 0;
glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f), invTrMat(1.f);
glm::vec3 currentLightPos(0.f);
float lightPos[3] = { 0.f };
float rotAmb = 0.f;Sphere mySphere(96);
int numSphereVertices = 0;
int numSphereIndices = 0;GLuint colorTexture = 0;
GLuint normalTexture = 0;
GLuint heightTexture = 0;// white light
float globalAmbient[4] = { 0.1f, 0.1f, 0.1f, 1.f };
float lightAmbient[4] = { 0.f, 0.f, 0.f, 1.f };
float lightDiffuse[4] = { 1.0f, 1.0f, 1.f, 1.f };
float lightSpecular[4] = { 1.f, 1.f, 1.f, 1.f };// silver material
float* matAmbi = Utils::silverAmbient();
float* matDiff = Utils::silverDiffuse();
float* matSpec = Utils::silverSpecular();
float  matShin = Utils::silverShininess();Camera camera(glm::vec3(0.f, 0.f, 1.f));
//float cameraX = 0.f, cameraY = 0.f, cameraZ = 5.f;
GLboolean keys[1024] = { GL_FALSE };
GLboolean b_firstMouse = GL_TRUE;
float deltaTime = 0.f;float lastFrame = 0.f;
float lastLocX = 0.f;
float lastLocY = 0.f;void do_movement()
{if (keys[GLFW_KEY_W]){camera.ProcessKeyboard(FORWARD, deltaTime);}if (keys[GLFW_KEY_S]){camera.ProcessKeyboard(BACKWARD, deltaTime);}if (keys[GLFW_KEY_A]){camera.ProcessKeyboard(LEFT, deltaTime);}if (keys[GLFW_KEY_D]){camera.ProcessKeyboard(RIGHT, deltaTime);}/*if (keys[GLFW_KEY_ESCAPE]){glfwSetWindowShouldClose(window, GL_TRUE);}*/
}void key_press_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)){glfwSetWindowShouldClose(window, GL_TRUE);}if (action == GLFW_PRESS){keys[key] = GLFW_TRUE;  //这里一定一定不能写成“==“,否则  按键WSAD按键失效!!!!!!!}else if (action == GLFW_RELEASE){keys[key] = GLFW_FALSE;    //这里一定一定不能写成“==“,否则  按键WSAD按键失效!!!!!!!}
}void mouse_move_callback(GLFWwindow* window, double xPos, double yPos)
{if (b_firstMouse){lastLocX = xPos;lastLocY = yPos;b_firstMouse = GL_FALSE;}float xOffset = xPos - lastLocX;float yOffset = lastLocY - yPos;lastLocX = xPos;lastLocY = yPos;camera.ProcessMouseMovement(xOffset, yOffset);}void mouse_scroll_callback(GLFWwindow* window, double xPos, double yPos)
{camera.ProcessMouseScroll(yPos);
}void setupVertices()
{int numSphereVertices = mySphere.getNumVertices();numSphereIndices = mySphere.getNumIndices();vector<int> ind = mySphere.getIndices();vector<glm::vec3> vert = mySphere.getVertices();vector<glm::vec2> text = mySphere.getTexCoords();vector<glm::vec3> norm = mySphere.getNormals();vector<glm::vec3> tang = mySphere.getTangents();vector<float> pValuse;vector<float> tValues;vector<float> nValues;vector<float> tanValues;for (int i = 0; i< mySphere.getNumIndices(); i++){//pValuse.push_back(vert[ind[i]].x);pValuse.push_back(vert[ind[i]].x);pValuse.push_back(vert[ind[i]].y);pValuse.push_back(vert[ind[i]].z);tValues.push_back(text[ind[i]].s);tValues.push_back(text[ind[i]].t);nValues.push_back(norm[ind[i]].x);nValues.push_back(norm[ind[i]].y);nValues.push_back(norm[ind[i]].z);tanValues.push_back(tang[ind[i]].x);tanValues.push_back(tang[ind[i]].y);tanValues.push_back(tang[ind[i]].z);}glGenVertexArrays(numVAOs, vao);glBindVertexArray(vao[0]);glGenBuffers(numVBOs, vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glBufferData(GL_ARRAY_BUFFER, pValuse.size() * sizeof(float), &pValuse[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &tValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glBufferData(GL_ARRAY_BUFFER, nValues.size() * sizeof(float), &nValues[0], GL_STATIC_DRAW);glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);glBufferData(GL_ARRAY_BUFFER, tanValues.size() * sizeof(float), &tanValues[0], GL_STATIC_DRAW);
}void installLights(glm::mat4 vMatrix)
{glm::vec3 transformed = glm::vec3(vMatrix * glm::vec4(currentLightPos, 1.f));lightPos[0] = transformed.x;lightPos[1] = transformed.y;lightPos[2] = transformed.z;// get the locations of the light and material fields in the shaderglobalAmbLoc = glGetUniformLocation(renderingProgram, "globalAmbient");ambLoc = glGetUniformLocation(renderingProgram, "light.ambient");diffLoc = glGetUniformLocation(renderingProgram, "light.diffuse");specLoc = glGetUniformLocation(renderingProgram, "light.specular");posLoc = glGetUniformLocation(renderingProgram, "light.position");mAmbLoc = glGetUniformLocation(renderingProgram, "material.ambient");mDiffLoc = glGetUniformLocation(renderingProgram, "material.diffuse");mSpecLoc = glGetUniformLocation(renderingProgram, "material.specular");mShinLoc = glGetUniformLocation(renderingProgram, "material.shininess");//  set the uniform light and material values in the shaderglUniformMatrix4fv(globalAmbLoc, 1, GL_FALSE, globalAmbient);glUniformMatrix4fv(ambLoc, 1, GL_FALSE, lightAmbient);glUniformMatrix4fv(diffLoc, 1, GL_FALSE, lightDiffuse);glUniformMatrix4fv(specLoc, 1, GL_FALSE, lightSpecular);glUniformMatrix3fv(posLoc, 1, GL_FALSE, lightPos);glUniformMatrix4fv(mAmbLoc, 1, GL_FALSE, matAmbi);glUniformMatrix4fv(mDiffLoc, 1, GL_FALSE, matDiff);glUniformMatrix4fv(mSpecLoc, 1, GL_FALSE, matSpec);glUniform1f(mShinLoc, matShin);/*glProgramUniform4fv(renderingProgram, globalAmbLoc, 1, globalAmbient);glProgramUniform4fv(renderingProgram, ambLoc, 1, lightAmbient);glProgramUniform4fv(renderingProgram, diffLoc, 1, lightDiffuse);glProgramUniform4fv(renderingProgram, specLoc, 1, lightSpecular);glProgramUniform3fv(renderingProgram, posLoc, 1, lightPos);glProgramUniform4fv(renderingProgram, mAmbLoc, 1, matAmbi);glProgramUniform4fv(renderingProgram, mDiffLoc, 1, matDiff);glProgramUniform4fv(renderingProgram, mSpecLoc, 1, matSpec);glProgramUniform1f(renderingProgram, mShinLoc, matShin);*/
}void init(GLFWwindow* window)
{renderingProgram = Utils::createShaderProgram("vertShader.vert", "fragShader.frag");cameraX = 0.f, cameraY = 0.f, cameraZ = 2.f;sphereX = 0.f, sphereY = 0.f, sphereZ = -1.f;lightLocX = 3.f, lightLocY = 2.f, lightLocZ = 3.f;   //试着改变光源位置,看变化效果glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(toRadians(45.f), aspect, 0.01f, 1000.f);setupVertices();colorTexture = Utils::loadTexture("earthspec1kBLUE.jpg");normalTexture = Utils::loadTexture("earthspec1kNORMAL.jpg");heightTexture = Utils::loadTexture("earthspec1kNEG.jpg");
}void display(GLFWwindow* window, double currentTime)
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.1f, 0.2f, 0.5f, 1.f);glUseProgram(renderingProgram);deltaTime = currentTime - lastFrame;lastFrame = currentTime;do_movement();//这句必须要有,否则鼠标中键失效pMat = glm::perspective(camera.Zoom, aspect, 0.1f, 1000.f);//没有这句,背景就没在相机视点上了,把圆环移到相机的位置//mMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, 4.5f));vMat = camera.GetViewMatrix();mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");nLoc = glGetUniformLocation(renderingProgram, "norm_matrix");glfwGetFramebufferSize(window, &width, &height);aspect = (float)width / (float)height;pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);//vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));mMat = glm::translate(glm::mat4(1.f), glm::vec3(sphereX, sphereY, sphereZ));mMat = glm::rotate(mMat, toRadians(35.f), glm::vec3(0.f, 1.f, 0.f));mMat = glm::rotate(mMat, rotAmb, glm::vec3(0.f, 1.f, 0.f));rotAmb += 0.002f;mvMat = vMat * mMat;invTrMat = glm::transpose(glm::inverse(mvMat));currentLightPos = glm::vec3(lightLocX, lightLocY, lightLocZ);installLights(mvMat);  //vMatglUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));glUniformMatrix4fv(nLoc, 1, GL_FALSE, glm::value_ptr(invTrMat));glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(1);glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(2);glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);glEnableVertexAttribArray(3);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, colorTexture);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, normalTexture);glActiveTexture(GL_TEXTURE2);glBindTexture(GL_TEXTURE_2D, heightTexture);glEnable(GL_CULL_FACE);glFrontFace(GL_CCW);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glDrawArrays(GL_TRIANGLES, 0, mySphere.getNumIndices());
}void window_size_callback(GLFWwindow* window, int newWidth, int newHeight)
{aspect = (float)newWidth / (float)newHeight;glViewport(0, 0, newWidth, newHeight);pMat = glm::perspective(toRadians(45.f), aspect, 0.01f, 1000.f);
}int main(int argc, char** argv)
{int glfwState = glfwInit();if (GLFW_FALSE == glfwState){cout << "GLFW initialize failed, invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "Sphere vertex height map", nullptr, nullptr);if (!window){cout << "GLFW create window failed, invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwMakeContextCurrent(window);int glewState = glewInit();if (GLEW_OK != glewState){cout << "GLEW initialize failed, invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;glfwTerminate();exit(EXIT_FAILURE);}glfwSetWindowSizeCallback(window, window_size_callback);glfwSetCursorPosCallback(window, mouse_move_callback);glfwSetScrollCallback(window, mouse_scroll_callback);glfwSetKeyCallback(window, key_press_callback);glfwSwapInterval(1);init(window);while (!glfwWindowShouldClose(window)){display(window, glfwGetTime());glfwSwapBuffers(window);glfwPollEvents();}glfwDestroyWindow(window);glfwTerminate();exit(EXIT_SUCCESS);return 0;
}

2.着色器程序

1.顶点着色器

#version 460 corelayout(location = 0) in vec3 vertPos;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 vertNormal;
layout(location = 3) in vec3 vertTangent;out vec3 varyingLightDir;
out vec3 varyingVertPos;
out vec3 varyingNormal;
out vec3 varyingTangent;
out vec2 tc;layout(binding = 0) uniform sampler2D t;
layout(binding = 1) uniform sampler2D n;
layout(binding = 2) uniform sampler2D h;struct PositionalLight
{vec4 ambient;vec4 diffuse;vec4 specular;vec3 position;
};struct Material
{vec4 ambient;vec4 diffuse;vec4 specular;float shininess;
};uniform vec4 globalAmbient;
uniform PositionalLight light;
uniform Material material;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 norm_matrix;void main(void)
{varyingNormal = (norm_matrix * vec4(vertNormal, 1.f)).xyz;varyingTangent = (norm_matrix * vec4(vertTangent, 1.f)).xyz;vec4 P1 = vec4(vertPos, 1.f);vec4 P2 = vec4((vertNormal * ((texture(h, texCoord).r) / 15.f)), 1.f);vec4 P = vec4((P1.xyz + P2.xyz), 1.f);varyingVertPos = (mv_matrix * P).xyz;varyingLightDir = light.position - varyingVertPos;tc = texCoord;gl_Position = proj_matrix * mv_matrix * P;  //MVP
}

2.片元着色器

#version 460 corein vec3 varyingLightDir;
in vec3 varyingVertPos;
in vec3 varyingNormal;
in vec3 varyingTangent;
in vec2 tc;out vec4 fragColor;layout(binding = 0) uniform sampler2D t;
layout(binding = 1) uniform sampler2D n;
layout(binding = 2) uniform sampler2D h;struct PositionalLight
{vec4 ambient;vec4 diffuse;vec4 specular;vec3 position;
};struct Material
{vec4 ambient;vec4 diffuse;vec4 specular;float shininess;
};uniform vec4 globalAmbient;
uniform PositionalLight light;
uniform Material material;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform mat4 norm_matrix;vec3 CalcBumpedNormal()
{vec3 Normal = normalize(varyingNormal);vec3 Tangent = normalize(varyingTangent);Tangent = normalize(Tangent - dot(Tangent, Normal) * Normal);vec3 bitangent = cross(Tangent, Normal);vec3 bumpMapNormal = texture(n, tc).xyz;bumpMapNormal = bumpMapNormal * 2.f - 1.f;mat3 TBN = mat3(Tangent, bitangent, Normal);vec3 newNormal = TBN * bumpMapNormal;newNormal = normalize(newNormal);return newNormal;
}void main(void)
{// normalize the light, normal, and view vectors:vec3 L = normalize(varyingLightDir);vec3 V = normalize(varyingVertPos);//vec3 N = CalcBumpedNormal();
//  vec3 N = normalize(varyingNormal);
//vec3 N = CalcBumpedNormal();vec3 N = CalcBumpedNormal();// get the angle between the light and surface normal:float cosTheta = dot(L, N);// compute light reflection vector, with respect N:vec3 R = normalize(reflect(-L, N));// angle between the view vector and reflected light:float cosPhi = dot(V, R);// compute ADS contributions (per pixel):fragColor = 0.5f * texture(t, tc) + 0.5f * (fragColor = globalAmbient * material.ambient+ light.ambient * material.ambient+ light.diffuse * material.diffuse * max(cosTheta, 0.0f)+ light.specular * material.specular * pow(max(cosPhi, 0.f), material.shininess));}

运行效果

源码下载

源码下载地址

openGL使用高度贴图模拟地球表面凹凸效果相关推荐

  1. 【UnityShader】凹凸映射之高度贴图和法线贴图

    目录 基础知识 高度纹理 Unity 中的法线纹理类型 法线纹理 基础知识 纹理的另一种场景的应用就是凹凸映射.凹凸映射的目的是使用一张纹理来修改模型表面的法线,以便为模型提供更多的细节.这种方法不会 ...

  2. OpenGL基础49:高度贴图(下)

    接上文:OpenGL基础48:高度贴图(上) 四.陡峭视差映射 上文计算纹理偏移的方法是最简单的,但问题也比较大:当你斜视贴图的时候可以看到非常明显的错误 这里有另一种方法,这种方法类似于找连续函数在 ...

  3. openGL增强表面细节----高度贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.代码 主程序c++ 效果 前言 现在我们扩展法线贴图的概念--从纹理图像用于扰动法向量到扰乱顶点位置本身.实 际上,以这种方式修 ...

  4. Unity Shader - Heightmap 高度贴图

    目录:Unity Shader - 知识点目录(先占位,后续持续更新) 原文:Heightmap 版本:2019.1 Heightmap 高度贴图(也称为视差映射)是一个类似于法线映射的概念,但是这种 ...

  5. 【视觉高级篇】25 # 如何用法线贴图模拟真实物体表面

    说明 [跟月影学可视化]学习笔记. 什么是法线贴图? 法线贴图就是在原物体的凹凸表面的每个点上均作法线,通过RGB颜色通道来标记法线的方向,你可以把它理解成与原凹凸表面平行的另一个不同的表面,但实际上 ...

  6. Unity URP管线的PBR材质及Tessallation Shader(Height Map高度贴图)

    在使用URP管线的过程中发现默认的URP管线的shader是没有提供height map参数设置的,经过查找才知道URP管线中height map相关的功能需要自己写shader开启Tessallat ...

  7. OpenGL cubemap 立方体贴图实例

    OpenGL cubemap 立方体贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include ...

  8. OpenGL Lightmap光照贴图的实例

    OpenGL Lightmap光照贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include ...

  9. OpenGL envmapsphere球形环境图的实例

    OpenGL envmapsphere球形环境图 先上图,再解答. 按下E键 完整主要的源代码 源代码剖析 先上图,再解答. 按下E键 完整主要的源代码 #include <vmath.h> ...

  10. OpenGL立方体纹理贴图

    OpenGL正方体纹理贴图 0. 写在最前面 1. 正方体顶点属性构建 2. 绑定多个VAO.VBO 3. 创建多个纹理 4. 渲染循环 5. 实现代码 6. 多个立方体纹理贴图 0. 写在最前面 要 ...

最新文章

  1. 1小时教你做360度全景“小星球”效果图 Skillshare – Create a Panoramic ‘Little Planet’ from Anywhere
  2. ssh报错:Could not load host key:/etc/ssh/ssh_host_rsa_keyssh_host_ecdsa_keyssh_host_ed25519_key...
  3. 苹果手机耗电快_iPhone12用5G耗电快,苹果回应
  4. java关键字整理_【java基础知识整理】java基础语法之关键字
  5. 机器学习中向量化编程总结记录
  6. 经典问题之「分支预测」
  7. Windows编程—获取Chrome浏览器的安装目录
  8. 前后端分离的项目,如何解决登录问题
  9. MQTT 控制报文 - SUBSCRIBE订阅报文,SUBACK,UNSUBSCRIBE,UNSUBACK - 第5章
  10. 用Win2003做×××借线
  11. mysql front 视图_mysql 视图
  12. Word打开文件错误提示用文本恢复转换器打开文件
  13. Linux虚拟机断电后开机出现:Entering emeryency mode. Exit the shell to continue.
  14. bbox regresion
  15. 据说程序员写完代码是这个样子,99%的人都中枪了
  16. “产教融合,共享生态” CIE 2017中国IT教育博鳌论坛圆满召开
  17. 解决Office 2010打开文件提示“文件已损坏,无法打开。”的问题
  18. [转载]树莓派随身工具箱:中间人劫持获取控制权
  19. 音频预训练模型 Audio and Speech Pre-trained Models
  20. 德勤发布《2021技术趋势》报告

热门文章

  1. 清洁机器人--屏幕显示LCD方案之MCU SPI 接口驱动ST7789 LCD显示
  2. 防火墙NAT映射-端口映射-从零开始学RouterOS系列05
  3. 基于FPGA的二进制转BCD设计(附代码)
  4. HTML5七夕情人节表白网页制作【雪花爱心】HTML+CSS+JavaScript 爱心代码 爱心制作 表白代码 告白网页制作
  5. 你需要知道的物联网开放平台
  6. 2019保定中考计算机时间安排,2019年保定中考考试时间安排,保定中考考试科目时间安排表...
  7. 【图算法】(3) 网络的基本静态几何特征(二),附networkx完整代码
  8. win10用android手柄游戏手柄,win10系统使用游戏手柄的步骤
  9. Scrum敏捷开发实践
  10. astah建ER图总结