OpenGL官方文档中的入门教程源代码:在3维空间中自由移动

news2024/11/27 8:39:22

OpenGL官方文档中的入门教程源代码:在3维空间中自由移动

  • 项目总览:
  • 一、开发前的准备工作
        • 1.将以上链接中的三个文件分别放到自己硬盘的一个文件夹中:例如D盘/OpenGL/...
        • 2.打开VS2022创建一个项目,右击窗体选择属性
        • 3.配置这3个文件的一些环境到你的项目中,这里可以参考:[这节视频](https://www.bilibili.com/video/BV11W411N7b9/?spm_id_from=333.999.0.0&vd_source=ee4dc98d9036bcc310740dff78231cf7),同时这也是一节非常好的OpenGL课程,感谢傅老师!
  • 二、代码目录
        • 1.头文件Camera.h
        • 2.源文件Camera.cpp
        • 3.头文件Shader.h
        • 4.源文件Shader.cpp
        • 5.源文件main.cpp
  • 三、着色器
        • 1.顶点着色器vertexSource.txt
        • 2.片段着色器fragmentSource.txt
  • 四、效果展示:

项目总览:

1.开发语言:C++语言
2.IDE:VS2022
3.开发用时:一周
4.本项目是OpenGL官方文档https://learnopengl.com中《入门》栏目的案例,素材和函数功能都可在官方文档找到。
5.源码已上传到我的GitHub,链接:https://github.com/2394799692/OpenGLpractice1 或点此跳转


以下是本篇文章正文内容,欢迎朋友们进行指正,一起探讨,共同进步。——来自读研路上的lwj。QQ:2394799692(请标明来意)

一、开发前的准备工作

链接:https://pan.baidu.com/s/1dtXE22PZw14hif0ui3r2qA?pwd=z22g 提取码:z22g

1.将以上链接中的三个文件分别放到自己硬盘的一个文件夹中:例如D盘/OpenGL/…

在这里插入图片描述

2.打开VS2022创建一个项目,右击窗体选择属性

在这里插入图片描述

3.配置这3个文件的一些环境到你的项目中,这里可以参考:这节视频,同时这也是一节非常好的OpenGL课程,感谢傅老师!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、代码目录

在这里插入图片描述

1.头文件Camera.h

定义源文件Camera.cpp中所使用到的函数和变量,这两个文件的作用是定义鼠标为摄像机的位置,从而实现在3维坐标中上下左右的移动

#pragma once

#include <glm.hpp>
#include <gtc/matrix_transform.hpp>

class Camera
{
public:
	Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup);
	Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup);

	glm::vec3 Position;
	glm::vec3 Forward;
	glm::vec3 Right;
	glm::vec3 Up;
	glm::vec3 WorldUp;
	float Pitch;
	float Yaw;
	float SenseX = 0.001f;
	float SenseY = 0.001f;
	float speedZ = 0;
	glm::mat4 GetViewMatrix();
	void ProcessMouseMovement(float deltaX, float deltaY);
	void UpdateCameraPos();
private:
	void UpdateCameraVectors();
};

2.源文件Camera.cpp

#include "Camera.h"

Camera::Camera(glm::vec3 position, glm::vec3 target, glm::vec3 worldup)
{
	Position = position;
	WorldUp = worldup;
	Forward = glm::normalize(target - position);//转为单位向量
	Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思
	Up = glm::normalize(glm::cross(Forward, Right));
}
Camera::Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup)
{
	Position = position;
	WorldUp = worldup;
	Pitch = pitch;
	Yaw = yaw;
	Forward.x = glm::cos(Pitch) * glm::sin(Yaw);
	Forward.y = glm::sin(Pitch);		   
	Forward.z = glm::cos(Pitch) * glm::cos(Yaw);
	Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思
	Up = glm::normalize(glm::cross(Forward, Right));
}


glm::mat4 Camera::GetViewMatrix()
{
	return glm::lookAt(Position, Position + Forward, WorldUp);
}
void Camera::UpdateCameraVectors()
{
	Forward.x = glm::cos(Pitch) * glm::sin(Yaw);
	Forward.y = glm::sin(Pitch);
	Forward.z = glm::cos(Pitch) * glm::cos(Yaw);
	Right = glm::normalize(glm::cross(Forward, WorldUp));//cross是叉乘的意思
	Up = glm::normalize(glm::cross(Forward, Right));
}
void Camera::ProcessMouseMovement(float deltaX, float deltaY)
{
	Pitch -= deltaY* SenseX;
	Yaw -= deltaX* SenseY;
	UpdateCameraVectors();
}
void Camera::UpdateCameraPos()
{
	Position += Forward*speedZ*0.01f;
}

3.头文件Shader.h

结合shader.cpp和着色器资源实现渲染/着色功能

#pragma once
#include<string>
using namespace std;
class Shader
{
public:
	Shader(const char* vertexPath,const char* fragmentPath);
	string vertexString;
	string fragmentString;
	const char* vertexSource;
	const char* fragmentSource;
	unsigned int ID;//shader program id
	void use();

private:
	void checkCompileErrors(unsigned int ID, std::string type);
};

4.源文件Shader.cpp

#include "Shader.h"
#include<iostream>
#include<fstream>
#include<sstream>
#define GLEW_STATIC
#include<GL/glew.h>
#include<GLFW/glfw3.h>
using namespace std;
//shader命名空间下的shader方法
Shader::Shader(const char* vertexPath, const char* fragmentPath)
{
	ifstream vertexFile;
	ifstream fragmentFile;
	stringstream vertexSStream;
	stringstream fragmentSStream;

	vertexFile.open(vertexPath);
	fragmentFile.open(fragmentPath);
	vertexFile.exceptions(ifstream::failbit || ifstream::badbit);
	fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);
	try
	{
		if (!vertexFile.is_open() || !fragmentFile.is_open())
		{
			throw exception("open file error");
		}
		vertexSStream << vertexFile.rdbuf();
		fragmentSStream << fragmentFile.rdbuf();

		vertexString = vertexSStream.str();
		fragmentString = fragmentSStream.str();

		vertexSource = vertexString.c_str();
		fragmentSource = fragmentString.c_str();

		unsigned int vertex, fragment;//承载gpu返还的shader
		vertex = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vertex, 1, &vertexSource, NULL);
		glCompileShader(vertex);
		checkCompileErrors(vertex, "VERIEX");

		fragment = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fragment, 1, &fragmentSource, NULL);
		glCompileShader(fragment);
		checkCompileErrors(fragment, "FRAGMENT");

		ID = glCreateProgram();
		glAttachShader(ID, vertex);
		glAttachShader(ID, fragment);
		glLinkProgram(ID);
		checkCompileErrors(ID, "PROGRAM");

		glDeleteShader(vertex);
		glDeleteShader(fragment);
	}
	catch (const std::exception& ex)
	{
		printf(ex.what());
	}
}

void Shader::use() {
	glUseProgram(ID);
}
void Shader::checkCompileErrors(unsigned int ID, string type)
{
	int success;
	char infoLog[512];
	if (type != "PROGRAM")
	{
		glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
		if (!success)
		{
			glGetShaderInfoLog(ID, 512, NULL, infoLog);
			cout << "shader compile error:" << infoLog << endl;
		}
	}
	else
	{
		glGetProgramiv(ID, GL_LINK_STATUS, &success);
		if (!success)
		{
			glGetProgramInfoLog(ID, 512, NULL, infoLog);
			cout << "program link error:" << infoLog << endl;
		}

	}
}

5.源文件main.cpp

#include<iostream>
#define GLEW_STATIC
#include<GL/glew.h>
#include<GLFW/glfw3.h>

#include "Shader.h"

#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include "Camera.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
//float vertices[] = {
//	//     ---- 位置 ----       ---- 颜色 ----     - 纹理坐标 -
//		 0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // 右上
//		 0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // 右下
//		-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // 左下
//		-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // 左上
//};
float vertices[] = {
	-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
};
unsigned int indices[] = {
	0,1,2,
	2,3,0
}; 

glm::vec3 cubePositions[] = {
  glm::vec3(0.0f,  0.0f,  0.0f),
  glm::vec3(2.0f,  5.0f, -15.0f),
  glm::vec3(-1.5f, -2.2f, -2.5f),
  glm::vec3(-3.8f, -2.0f, -12.3f),
  glm::vec3(2.4f, -0.4f, -3.5f),
  glm::vec3(-1.7f,  3.0f, -7.5f),
  glm::vec3(1.3f, -2.0f, -2.5f),
  glm::vec3(1.5f,  2.0f, -2.5f),
  glm::vec3(1.5f,  0.2f, -1.5f),
  glm::vec3(-1.3f,  1.0f, -1.5f)
};

float lastX;
float lastY;
bool firstMouse = true;
//引入class类
	//Camera camera(glm::vec3(0,0,3.0f),glm::vec3(0,0,0),glm::vec3(0,1.0f,0));
Camera camera(glm::vec3(0, 0, 3.0f), glm::radians(15.0f), glm::radians(180.0f), glm::vec3(0, 1.0f, 0));
void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
	{
		glfwSetWindowShouldClose(window, true);
	}
	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
	{
		camera.speedZ=1.0f;
	}
	else if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
	{
		camera.speedZ = -1.0f;
	}
	else {
		camera.speedZ = 0;
	}

}
void mouse_callback(GLFWwindow* window, double xPos, double yPos)
{
	if (firstMouse == true)
	{
		lastX = xPos;
		lastY = yPos;
		firstMouse = false;
	}
	float deltaX, deltaY;
	deltaX = xPos - lastX;
	deltaY = yPos - lastY;

	lastX = xPos;
	lastY = yPos;
	camera.ProcessMouseMovement(deltaX, deltaY);
	/*printf("%f \n", deltaX);*/
}
int main()
{
	glfwInit();//初始化
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	//打开一个窗体
	GLFWwindow* window = glfwCreateWindow(800, 600, "My OpenGL Game", NULL, NULL);
	if (window == NULL)
	{
		printf("open window failed.");
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//消失鼠标
	glfwSetCursorPosCallback(window, mouse_callback);
	//init glew
	glewExperimental = true;
	if (glewInit() != GLEW_OK)
	{
		printf("Init GLEW failed.");
		glfwTerminate();
		return -1;
	}
	
	glViewport(0, 0, 800, 600);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);//背面剔除,正面:GL_FRONT
	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//显示边框
	glEnable(GL_DEPTH_TEST);//做深度缓冲

	Shader* myShader = new Shader("vertexSource.txt", "fragmentSource.txt");

	unsigned int VAO;
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO); 

	unsigned int VBO;
	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	unsigned int EBO;
	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	/*glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);*/
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(2);

	unsigned int TexBufferA;
	glGenTextures(1, &TexBufferA);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, TexBufferA);

	int width, height, nrChannel;
	stbi_set_flip_vertically_on_load(true);//图像翻转
	unsigned char* data = stbi_load("container.jpg", &width, &height, &nrChannel, 0);
	if (data)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		printf("load image failed.");
	}
	stbi_image_free(data);

	unsigned int TexBufferB;//载入笑脸
	glGenTextures(1, &TexBufferB);
	glActiveTexture(GL_TEXTURE3);
	glBindTexture(GL_TEXTURE_2D, TexBufferB);
	unsigned char* data2 = stbi_load("awesomeface.png", &width, &height, &nrChannel, 0);
	if (data2)
	{
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
		printf("load image failed.");
	}
	stbi_image_free(data2);
	

	glm::mat4 trans;
	//trans = glm::translate(trans, glm::vec3(-0.01f, 0, 0));//平移
	//trans = glm::rotate(trans,glm::radians(45.0f), glm::vec3(0, 0, 1.0f));//旋转45度
	//trans = glm::scale(trans, glm::vec3(2.0f, 2.0f, 2.0f));//缩放
	glm::mat4 modelMat;
	modelMat = glm::rotate(modelMat, glm::radians(-45.0f), glm::vec3(0, 1.0f, 1.0f));
	glm::mat4 viewMat;
	//viewMat = glm::translate(viewMat, glm::vec3(0, 0, -3.0f));
	//viewMat = camera.GetViewMatrix();
	glm::mat4 projMat;
	projMat = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
	
	
	while (!glfwWindowShouldClose(window))
	{
		/*glm::mat4 trans;//定义在里面每次重置角度不会转太快
		trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0));
		trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0, 0, 1.0f));*/
		processInput(window);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		/*glClear(GL_COLOR_BUFFER_BIT);*/
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//加了一个清除上一轮深度缓冲
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TexBufferA);
		glActiveTexture(GL_TEXTURE3);
		glBindTexture(GL_TEXTURE_2D, TexBufferB);
		glBindVertexArray(VAO);
		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
		viewMat = camera.GetViewMatrix();
		for (int i = 0; i < 10; i++) {
			glm::mat4 modelMat2;
			modelMat2 = glm::translate(modelMat2, cubePositions[i]);
			myShader->use();
			glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);
			glUniform1i(glGetUniformLocation(myShader->ID, "ourFace"), 3);
			//glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "transform"), 1, GL_FALSE, glm::value_ptr(trans));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "modelMat"), 1, GL_FALSE, glm::value_ptr(modelMat2));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));

			glDrawArrays(GL_TRIANGLES, 0, 36);
			//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		}
		

		glfwSwapBuffers(window);
		glfwPollEvents();
		camera.UpdateCameraPos();
	}
	glfwTerminate();
	return 0;
}

三、着色器

1.顶点着色器vertexSource.txt

顶点着色器(Vertex Shader)是几个可编程着色器中的一个。如果我们打算做渲染的话,现代OpenGL需要我们至少设置一个顶点和一个片段着色器。

#version 330 core                                
layout (location=0) in vec3 aPos;                
layout (location=1) in vec3 aColor;    
layout (location=2) in vec2 aTexCoord;    

//uniform mat4 transform;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;

out vec4 vertexColor;
out vec2 TexCoord;
void main(){                                     
    gl_Position=projMat*viewMat*modelMat*vec4(aPos.x,aPos.y,aPos.z,1.0f);  
    vertexColor=vec4(aColor.x,aColor.y,aColor.z,1.0f);
    TexCoord=aTexCoord;
}

2.片段着色器fragmentSource.txt

片段着色器(Fragment Shader)是第二个也是最后一个我们打算创建的用于渲染三角形的着色器。片段着色器所做的是计算像素最后的颜色输出。

#version 330 core           
in vec4 vertexColor;             
in vec2 TexCoord;

uniform sampler2D ourTexture;
uniform sampler2D ourFace;


out vec4 FragColor; 
void main(){                
    FragColor = mix(texture(ourTexture,TexCoord),texture(ourFace,TexCoord), 0.2);
    //如果第三个值是0.0,它会返回第一个输入;如果是1.0,会返回第二个输入值。0.2会返回80%的第一个输入颜色和20%的第二个输入颜色,即返回两个纹理的混合色。
} 


四、效果展示:

视频效果:

OpenGL入门demo


图片效果:
在这里插入图片描述

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

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

相关文章

SQL Server全套教程(基于SQL语句----预览版)

SQL Server全套教程全程干货1. 数据库的基础操作1.1.0 创建数据库1.1.1 查看及修改数据库1.1.3 分离、附加和删除数据库1.1.4 数据库的备份和还原2.数据库表的相关操作2.1.0 常用数据类型2.1.1 表结构的创建2.1.2 表结构的查看及修改2.1.3 表约束的创建2.1.4 表约束的修改2.1.5…

2013款别克凯越危险警告灯不亮故障诊断方案设计

目 录 一、预约与准备工作 1 &#xff08;一&#xff09;工作描述 1 &#xff08;二&#xff09;预约 1 &#xff08;三&#xff09;准备工作 1 1、分析故障可能原因 1 2、工具、量具准备 1 3、辅料准备 2 二、接车、问诊与制单 2 &#xff08;一&#xff09;接车、问诊 2 &am…

mysql笔记

幻读 概念 一个事务中的两次同样的查询不一致。 解决幻读&#xff1a; RR&#xff1a;使用select ... for update加排他锁 for update的引入是为了幂等性问题&#xff0c;如果不加for update可能出现并发问题。 【参考&#xff1a;MySQL幻读详解及解决方法_学而不思则忘的博…

Word处理控件Aspose.Words功能演示:从 Java 中的 Word 文档中提取图像

图像通常用于表示 Word 文档中的重要信息。在文本旁边包含图像使内容更具吸引力。在某些情况下&#xff0c;您可能需要以编程方式提取嵌入在 Word 文档中的图像。为此&#xff0c;本文介绍了如何使用 Java 从 Word 文档中提取图像。 Aspose.Words for . java 最新下载&#xf…

著名歌唱家大衣哥太豪横了,参加商演被主办方请到五星级酒店就餐

自从农民歌唱家大衣哥&#xff0c;被前好友谷传民起诉后&#xff0c;他的人气不降反升&#xff0c;各种商演邀约也都不断。就在前几天&#xff0c;农民歌唱家大衣哥在商演结束后&#xff0c;被主办方邀请到五星级大酒店&#xff0c;享受了一顿丰盛的晚餐。 作为普通老百姓来说&…

【场景化解决方案】北极星深度集成钉钉PaaS,让OKR管理更加敏捷高效

方案简介 北极星OKR作为一款企业数字化目标管理软件&#xff0c;致力于为企业客户提供专业高效的数字化系统和一站式服务支持&#xff0c;助力企业管理转型升级。如今通过与钉钉的深度融合&#xff0c;在信息的反馈与交互和团队的协作上&#xff0c;营造了更加敏捷的场景&…

leetcode93. 复原 IP 地址

文章目录题目思考代码和注释总结题目 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0…

Linux——Bash脚本基本用法总结

文章目录基本语法基于语法awk&#xff08;分割命令返回值&#xff09;sed&#xff08;处理行内容&#xff09;融合正则指令条件语句条件判断符1. if2. while额外方法在脚本中使用命令行指令并获取返回值延时打印当前时间基本语法 基于语法 awk&#xff08;分割命令返回值&…

用友YonSuite“数智飞轮”用场景化告别产品与客户间的“翻译”

我们无疑是幸运的。淘宝、美团、掌上银行APP……这些诞生不过10年左右的移动互联网产物&#xff0c;用简单便捷的操作改变了我们千百年来衣食住行的方式。 相对而言&#xff0c;企业多少有点“不幸”。信息化建设虽然已经开展了20余年&#xff0c;但依然没享受到科技的便捷&am…

Java基础-继承

子类继承父类后构造器的特点&#xff1a; 子类中所有的构造器默认都会先访问父类中的无参的构造器&#xff0c;再执行自己。 为什么&#xff1f; 子类在初始化的时候&#xff0c;有可能会使用到父类中的数据&#xff0c;如果父类没有完成初始化&#xff0c;子类将无法使用父类…

一维离散数据的分区均匀采样

原理 原理类似文章点云梯度下采样中提到的梯度下采样。 大致采样思路如下&#xff1a; Step1&#xff1a;计算出每个待采样点 pip_ipi​ 的梯度 GiG_iGi​&#xff0c;并计算节点点云整体的平均梯度作为梯度阈值 GtG_tGt​。 Step2&#xff1a;比较 GiG_iGi​ 与梯度阈值 G…

基于BP神经网络的轨迹跟踪(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

002.组合|||——回溯算法

1.题目链接&#xff1a; 216. 组合总和 III 2.解题思路&#xff1a; 2.1.题目要求&#xff1a; 给一个元素数量k和一个元素和n&#xff0c;要求从范围[1,2,3,4,5,6,7,8,9]中返回所有元素数量为k和元素和为n的组合。&#xff08;每个数字只能使用一次&#xff09; 比如输入k…

大话游戏循环Game Loop——PythonC++

目录 前言 什么是游戏循环&#xff1f; 游戏循环的意义 从结构上来看&#xff1a; 从功能上来看&#xff1a; 正文 一个简单的游戏循环 阻塞游戏循环 现代基础游戏循环 “时间” 固定帧率游戏循环 时间驱动不固定帧率游戏循环 灵活帧率更新 之后的新问题 总结 …

网络基础—网关、网段、子网掩码

接上个笔记&#xff0c;工作时发现看似在一个网段的2个IP地址却ping不通&#xff0c;这里就是子网掩码发挥了作用。 IP地址 首先从最熟悉的IP地址开始介绍&#xff0c;IP地址是唯一标识&#xff0c;由32个0和1构成&#xff0c;长度为32bit&#xff0c;如00001010000000000000…

序列模型之循环神经网络(二)

目录 一.语言模型和序列生成 二.新序列采样 三.带有神经网络的梯度消失 四.GRU单元 一.语言模型和序列生成 上图的例子就是咱们的手机上的语音转文字输入差不多&#xff0c;说一句话&#xff0c;可能有多种可能的句子&#xff0c;那么到底是哪一种呢&#xff0c;咱们的语言…

【EDA365电子论坛】硬件人经历南下、北上,回乡创业,后悔了吗?

南下&#xff1f;北上&#xff1f;留下来&#xff1f;亦或是回乡&#xff1f;这些问题或许是每个电子人都曾遇到过的&#xff0c;如果可以&#xff0c;谁不想留在自己所熟悉的地方呢&#xff0c;但生活&#xff0c;总会让你想要的更多&#xff0c;只能选择再前行一步。 前几天在…

LeetCode题目笔记——2486. 追加字符以获得子序列

文章目录题目描述题目难度——中等方法一&#xff1a;一次遍历代码/C总结这个是上周末的周赛题目&#xff0c;当时忘做了&#xff0c;晚上的时候才想起&#xff0c;可惜了&#xff0c;题目还挺有意思的&#xff0c;类似的好像在以前做过&#xff0c;题目联机在这题目链接 题目…

你好,法语!A2知识点总结(4)

4.固定表达 4.1 devoir faire 4.2 ne…que ne…que&#xff1a;只…,仅仅 注意 用ne…que替换句子 Ex : En ce moment, il mange surtout des crales. En ce moment, il ne mange que des crales. 1)Elle lit surtout des romans. Il fait surtout du tennis.Ils s’intres…

NeRF算法Keras实现教程

在这个教程中&#xff0c;我们展示了 Ben Mildenhall 等人的研究论文 NeRF&#xff1a;将场景表示为用于视图合成的神经辐射场的最小实现。作者提出了一种巧妙的方法&#xff0c;通过神经网络对体积场景函数进行建模来合成场景的新颖视图。 为了帮助你直观地理解这一点&#x…