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

2023-11-01

openGL系列文章目录

前言

现在我们扩展法线贴图的概念——从纹理图像用于扰动法向量到扰乱顶点位置本身。实
际上,以这种方式修改对象的几何体具有一定的优势,例如使表面特征沿着对象的边缘可
见,并使特征能够响应阴影贴图。我们将会看到,它还可以帮助构建地形。
一种实用的方法是使用纹理图像来存储高度值,然后使用该高度值来提升(或降低)顶
点位置。含有高度信息的图像称为高度图,使用高度图更改对象的顶点的方法称为高度贴
图①。高度图通常将高度信息编码为灰度颜色:(0,0,0)(黑色)=低高度,(1,1,1)(白色)=
高高度。这样一来通过算法或使用“画图”程序就可以轻松创建高度图。图像的对比度越
高,其表示的高度变化越大。这些概念将在图1(显示随机生成的地图)和图1(显
示有组织的模式的地图)中说明。
在这里插入图片描述
图1
改变顶点位置是否有用取决于改变的模型。顶点操作可以在顶点着色器中轻松完成,当
模型顶点细节级别够高(例如在足够高精度的球体中)时,改变顶点高度的方法效果很好。
但是,当模型的顶点数量很少(例如立方体的角)时,渲染对象的表面需要依赖于光栅器
中的顶点插值来填充细节。当顶点着色器中可用于改变高度的顶点很少时,许多像素的高
度将无法从高度图中检索,而需要由插值生成,从而导致表面细节较差。当然,在片段着
色器中是不可能进行顶点操作的,因为这时顶点已被光栅化为像素位置。
程序10.4 展示了一个将顶点“向外”(即在表面法向量的方向上)移动的顶点着色器代
码。它通过将顶点法向量乘以从高度图检索所得的值,然后将该乘积与顶点位置相加,以
“向外”移动顶点。
在这里插入图片描述
图2

一、高度贴图原理

图10.14(见彩插)展示了通过在画图程序中涂鸦创建的简单高度图(左上角)。高度图
图像中还绘制了一个白色矩形。绿色版本的高度图(左下角)用作纹理。使用程序10.4 中
展示的着色器将高度图应用于100×100 的矩形网格模型时,会产生类似“地形”的感觉(如
图10.14 右图所示)。注意白色矩形是如何生成右边的悬崖的。
图10.14 展示的渲染结果还算可以,因为模型(网格和球体)有足够数量的顶点来对高
度贴图值进行采样。也就是说,模型具有大量的顶点,而高度图相对粗糙并且以低分辨率
充分地采样。然而,仔细观察仍然会发现存在分辨率伪影,例如沿图10.14 中地形右侧凸起
的矩形盒子的左下边缘。凸起的矩形盒子两侧看起来不是完美矩形,而且颜色有渐变效果,
其原因是底层网格100 像素×100 像素的分辨率无法与高度图中的白色矩形完全对齐,从而
导致纹理的光栅化坐标沿侧面产生伪影。
当尝试将其应用于要求更严苛的高度贴图时,在顶点着色器中进行高度贴图的限制会进
一步暴露。考虑图10.5 中展示的月球图像。法线贴图在捕获图像细节方面表现非常出色(如
图10.9 和图10.11 所示),而且由于它是灰度图,因此尝试将其作为高度图应用似乎很自然。
但是,基于顶点着色器的高度贴图会无法胜任这个任务,因为顶点着色器中采样的顶点数
(即使对于精度=500 的球体)比起图像中的细节级别,仍然太少。相较之下,法线贴图能够
很好地捕获细节,因为在片段着色器中对法线贴图的采样是像素级的。
在这里插入图片描述
图3

二、代码实现

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 "ImportedModel.h"
#include "Utils.h"

static const float pai = 3.1415926f;
float toRadians(float degrees) { return degrees * 2.f * pai / (float)360.f; }

static const int screenWidth = 1920;
static const int screenHeight = 1080;
int width = 0, height = 0;

static const int numVAOs = 1;
static const int numVBOs = 3;

GLuint renderingProgram = 0;
GLuint vao[numVAOs] = { 0 };
GLuint vbo[numVBOs] = { 0 };

float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float gndLocX = 0.f, gndLocY = 0.f, gndLocZ = 0.f;
GLuint mvLoc = 0, projLoc = 0;
float aspect = 0.f;
glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f);

ImportedModel ground("grid.obj");
int numGroundVertices = 0;

GLuint heightMap = 0;
GLuint heightTexture = 0;


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(void)
{
	numGroundVertices = ground.getNumVertices();
	vector<glm::vec3> vert = ground.getVertices();
	vector<glm::vec2> text = ground.getTextureCoords();
	vector<glm::vec3> norm = ground.getNormals();

	vector<float> pValues;
	vector<float> tValues;
	vector<float> nValues;

	for (int i=0; i<ground.getNumVertices(); i++)
	{
		pValues.push_back(vert[i].x);
		pValues.push_back(vert[i].y);
		pValues.push_back(vert[i].z);

		tValues.push_back(text[i].s);
		tValues.push_back(text[i].t);

		nValues.push_back(norm[i].x);
		nValues.push_back(norm[i].y);
		nValues.push_back(norm[i].z);
	}

	glGenVertexArrays(numVAOs, vao);
	glBindVertexArray(vao[0]);

	glGenBuffers(numVBOs, vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
	glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &pValues[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);
}

void init(GLFWwindow* window)
{
	renderingProgram = Utils::createShaderProgram("vertShader.vert", "fragShader.frag");
	cameraX = 0.03f, cameraY = 0.03, cameraZ = 0.8f;
	gndLocX = 0.f, gndLocY = 0.f, gndLocZ = 0.f;

	glfwGetFramebufferSize(window, &width, &height);
	aspect = (float)width / (float)height;
	pMat = glm::perspective(toRadians(45.f), aspect, 0.01f, 1000.f);

	setupVertices();

	heightTexture = Utils::loadTexture("heightTexture.jpg");
	heightMap = Utils::loadTexture("height.jpg");
}

void display(GLFWwindow* window, double currentTime)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.0f, 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");

	//vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));
	mMat = glm::translate(glm::mat4(1.f), glm::vec3(gndLocX, gndLocY, gndLocZ));
	mMat = glm::rotate(mMat, toRadians(25.f), glm::vec3(1.f, 0.f, 0.f));

	mvMat = vMat * mMat;

	glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
	glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));

	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);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, heightTexture);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, heightMap);

	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	glDrawArrays(GL_TRIANGLES, 0, ground.getNumVertices());
}

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 (glfwState == GLFW_FALSE)
	{
		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, "Height Mapped Terrain", 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);
	}

	glfwSwapInterval(1);

	glfwSetWindowSizeCallback(window, window_size_callback);
	glfwSetCursorPosCallback(window, mouse_move_callback);
	glfwSetScrollCallback(window, mouse_scroll_callback);
	glfwSetKeyCallback(window, key_press_callback);

	init(window);

	while (!glfwWindowShouldClose(window))
	{
		display(window, glfwGetTime());
		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwDestroyWindow(window);
	glfwTerminate();
	exit(EXIT_SUCCESS);

	return 0;
}

2.着色器程序

1.顶点着色器

#version 460 core

layout(location = 0) in vec3 vertPos;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 vertNormal;

out vec2 tc;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

layout(binding = 0) uniform sampler2D t; // for texture
layout(binding = 1) uniform sampler2D h; // for height map

void main(void)
{
	vec4 p = vec4(vertPos, 1.f) + vec4(vertNormal * ((texture(h, texCoord).r / 5.f)), 1.f);
	tc = texCoord;
	// "p"是高度图所改变的顶点位置
	// 由于高度图是灰度图,因此使用其任何颜色分量
	// 都可以(我们使用"r")。除以5.0 用来调整高度
	gl_Position = proj_matrix * mv_matrix * p;
}

2.片元着色器

#version 460 core

in vec2 tc;
out vec4 fragColor;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

layout(binding = 0) uniform sampler2D t; // for texture
layout(binding = 1) uniform sampler2D h; // for height map

void main(void)
{
	fragColor = texture(t, tc);
}

运行效果

在这里插入图片描述

源码下载

源码下载地址

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openGL增强表面细节--高度贴图 的相关文章

  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • glut 库中缺少 glutInitContextVersion()

    我正在练习一些 opengl 代码 但是当我想通过以下方式强制 opengl 上下文使用特定版本的 opengl 时glutInitContextVersion 它编译过程失败并给出以下消息 使用未声明的标识符 glutInitContex
  • 为什么OpenGL使用float而不是double? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 将四元数旋转转换为旋转矩阵?

    基本上 给定一个四元数 qx qy qz qw 我如何将其转换为OpenGL旋转矩阵 我也对哪个矩阵行是 向上 向右 向前 等感兴趣 我有一个四元数的相机旋转 我需要在向量中 以下代码基于四元数 qw qx qy qz 其中顺序基于 Boo
  • 三角形纹理映射OpenGL

    我正在开发一个使用 Marching Cubes 算法并将数据更改为 3D 模型的项目 现在我想在 OpenGL 中为我的 3D 模型使用纹理映射 我首先尝试了一个简单的示例 它将图片映射到三角形上 这是我的代码 int DrawGLSce
  • 如何仅剪切剪切平面的交集(而不是并集)?

    在 OpenGL JOGL 中 当使用多个剪切平面时 似乎会应用所有剪切平面的并集 我想要的是路口要应用的所有剪裁平面 这可能吗 请参阅下面的简化二维示例 Edit An example of clipping by vertex shad
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 致命错误 gl.h 包含在 glew.h 之前

    include
  • 在 OpenGL 中只使用纹理的 Alpha 通道?

    嘿 我正在尝试将恒定颜色绘制到帧缓冲区 并使用 RGBA 纹理中的 Alpha 通道将其混合 我一直在研究 glBlendFunc 和 glBlendColor 但似乎无法找到忽略纹理中的 RGB 值的方法 我想我必须自己提取 alpha
  • 编译 GLUI 库,VS2010 给我一个奇怪的命名空间错误

    我有一个针对我所在班级的 OpenGL 项目 它基于 GLUI 提供的 GLUI 库无法工作 这就是我尝试自己编译它的原因 因此 我从 SourceForge 下载了源代码并尝试编译 glui 库 它给了我这个 但我找不到任何相关信息 1
  • 如何在 Visual Studio 2012 中安装 GLUT 和 OpenGL?

    我今天刚安装了Visual Studio 2012 我想知道如何在该平台上安装GLUT和OpenGL OpenGL 应该已经存在 可能会缺少 Freeglut GLUT GLUT 现在已经非常过时并且没有得到积极的支持 所以你当然应该使用
  • 不明确的 OpenGL 默认相机位置

    在我的Opengl程序中 在我应用透视投影矩阵之前 每当我绘制一些对象时 我都会在世界坐标系的原点处绘制它 但是几乎所有Opengl教程都指出相机 我的投影视图 位于原点朝向正 z 轴 这取决于您稍后如何处理投影矩阵中的 z 值 但是如果这
  • 如何使用现代 OpenGL 在透视投影中绘制对象的正交轴? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我有带有透视投影的 3D 场景 我还可以选择场景中的一个对象 我需要为选定的对象绘制轴 问题是轴不会在透视投影中保存其大小 如果物体远离眼睛
  • 移动/调整大小期间 opengl 窗口冻结

    我正在使用 LWJGL 开发游戏 移动窗口时 计划将来添加调整大小代码 渲染循环冻结 我希望它在移动时继续以某种方式运行 LWJGL 不包括 glutMainLoop Display属于OpenGL 而不是Java 相关代码 regular
  • Windows下使用GLEW使用OpenGL扩展

    我一直在 Windows 上使用 OpenGL 扩展痛苦的方式 https stackoverflow com questions 14413 using opengl extensions on windows GLEW 是更简单的方法吗
  • 如何计算正切和副法线?

    谈谈OpenGL着色语言 GLSL 中的凹凸贴图 镜面高光之类的东西 I have 顶点数组 例如 0 2 0 5 0 1 0 2 0 4 0 5 法线数组 例如 0 0 0 0 1 0 0 0 1 0 0 0 世界空间中点光源的位置 例如
  • 渲染缓冲区大于窗口大小 - OpenGL

    我正在尝试绘制大于屏幕尺寸 即 320x480 的渲染缓冲区 512x512 执行 glReadPixels 后 图像看起来是正确的 除非图像的尺寸超过了屏幕尺寸 在本例中 超过了水平 320 和垂直 480 是什么原因导致这种异常现象呢
  • 按像素值偏移 gl_Position 或 gl_Vertex

    我的属性包含像素值 我想用这个属性值来偏移我的 gl vertex 问题是我的 gl vertex 以世界单位为单位 而 offset attribute 以像素为单位 如果我将屏幕尺寸作为统一发送 然后将像素转换为 1 到 1 值 并将其
  • OpenGL - 自动生成 glDrawArrays 的索引/步幅参数

    我正在渲染一个包含大量数据点 gt 1M 的网格结构 我的数据结构如图所示 所以我的索引缓冲区的内容看起来像这样0 100 1 101 2 102 3 103 我对索引缓冲区的巨大尺寸有点恼火 我需要它来定义我的三角形带 是否有可能告诉 O
  • 实例着色器矩阵的设置

    我想绘制实例立方体 我可以打电话GL DrawArraysInstanced PrimitiveType Triangles 0 36 2 成功地 我的问题是所有立方体都绘制在相同的位置和相同的旋转 我如何为每个立方体单独更改它 要创建不同

随机推荐

  • 分类精度评价代码matlab,matlab实现混淆矩阵评价指标(精度,召回率,F1分数)...

    声明 转自https blog csdn net TIME LEAF article details 83443908 混淆矩阵的分析直接参考https blog csdn net guomutian911 article details
  • SpringCloud Alibaba2021.0.1.0 使用openfeign报错No Feign Client for loadBalancing defined

    原因是SpringCloud Alibaba2021 0 1没有内置Ribbon了 使用openfeign需要自定义引入负载均衡jar包loadbalance
  • Redisson-实现分布式锁

    配置redisson 引入必要依赖
  • netty实现简单时事通讯_使用 RSocket 进行反应式数据传输

    在微服务架构中 不同服务之间通过应用协议进行数据传输 典型的传输方式包括基于 HTTP 协议的 REST 或 SOAP API 和基于 TCP 字节流的 gRPC 等 HTTP 协议的优势在于其广泛的适用性 有非常多的服务器和客户端实现的支
  • 关于z-index的总结

    z index的作用 很多时候需要把一个元素覆盖到另一个元素之上 比如登入弹出框等 这个时候就需要z index属性出场了 所以呢 z index就是调节层的显示优先级 决定哪个显示在最上方 作用范围就是Positioned element
  • Vmware虚拟机找不到.vmdk文件,不能开机

    Vmware虚拟机找不到 vmdk文件 不能开机 背景 公司的虚拟机平台是宿主机和存储组成的 虚拟机文件是挂载存储上的 由于虚拟机的命名有点乱 更改了一下 顺便把存储上的命名也更改了吗 在开机的时候出现报错 找不到 vmdk文件 原因 当系
  • 统计指定数字的个数

    编写函数统计指定数字的个数 前言 学习python的日常 提示 以下是本篇文章正文内容 下面案例可供参考 题目 本题要求实现一个统计整数中指定数字的个数的简单函数 CountDigit number digit 其中number是整数 di
  • webstorm中怎么搜索文件

    Ctrl N 文件搜索 Ctrl SHIFT R 关键字搜索
  • windows搭建ftp服务器、抓取虚拟机数据包、局域网流量监听

    先保证三台主机在同一局域网下 可以相互ping通 控制面板 gt 程序 gt 程序和功能 gt 启用或关闭windows功能 Web管理工具也要选上 进入管理工具 配置登录用户的权限 访问成功 使用kali登录ftp服务器 用户名 anon
  • MySQL服务器断电无法启动处理过程

    问题描述 2021 09 14 09 02 42 f24 InnoDB Operating system error number 1117 in a file operation InnoDB Some operating system
  • SpringBoot之统一返回格式与统一异常处理

    文章目录 导入Jar包 配置统一结果返回 配置全局异常处理 效果测试 在任何接口返回数据时 正确的返回格式 code 状态码 data 数据 message 接口响应信息 一般接口需要的就是这三个数据 code 200 data succe
  • WEB项目中出现The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in ei问题的解决方法

    web项目出现如上问题 据查是版本问题 JSTL 1 0 的声明是 JSTL1 1 的声明是 项目中 已经是 jstl 1 2 版本了 页面中也全部是用这种方式 javaee5之后就只有 jstl jar 这一个jar包了 没有standa
  • FLASH:一种高效的Transformer设计

    背景 近年来 Transformer凭借其优秀的设计 在文本 图像 语音等方向大杀四方 但是由于其attention的二次复杂度限制了其在长序列上的应用 本文提出了一种快 速度快 省 省显存 的模型FLASH Fast Linear Att
  • Allegro 干货知识分享--如何在Allegro中添加泪滴

    背景介绍 有时候在PCB绘制完成后需要对PCB进行添加泪滴的操作 添加泪滴的作用主要是 信号传输时平滑阻抗 减少阻抗的急剧跳变 避免高频信号传输时由于线宽突然变小而造成反射 焊接时可以保护焊盘 避免多次焊接时焊盘的脱落 生产时可以避免蚀刻不
  • Java与C#比较,哪个语言更是适合你?

    Java与C 比较 哪个语言更是适合你 先来说一说Java和c 的一些语言细节上的区别 第1个方面是数据类型方面 c 支持nullable数据类型 而Java不支持 c 支持指针类型 而Java不支持 c 支持无符号整形型 而Java不支持
  • 给一串字符串,打乱字符串顺序

    import java util Random public class Pratice 给一串字符串 打乱字符串顺序 修改字符串有两个思路 1 subString 2 字符数组 public static void main String
  • 4.0寸86盒显示屏调试(三)

    读取了个把星期也没读取出正确的ID号 最终放弃了读取 考虑是不是液晶屏根本没有输出功能 在使用SPI驱动以后 也没有显示白屏或者任何可以让人感觉驱动正确的现象 最终也放弃了在SPI上搞出个现象 转而使用RGB协议直驱 但还是没有结果 最后还
  • 百奥赛图财报解读:CRO业务枝繁叶茂,“千鼠万抗”遍地生花

    命运对勇士说 你无法抵御风暴 勇士回应 我就是风暴 这段对话是对中国创新药行业最好的诠释 回顾中国创新药近十年高速发展期 上千家创新药公司先后诞生 行业被资本推动一路 狂飙 根据医药魔方数据 创新药一级市场报道的融资额从2013年的36亿元
  • 计算机毕业设计-基于SSM的音乐播放器管理系统

    项目摘要 随着社会的发展 计算机的优势和普及使得音乐播放器管理系统的开发成为必需 音乐播放器管理系统主要是借助计算机 通过对首页 音乐推荐 付费音乐 论坛信息 个人中心 后台管理等信息进行管理 减少管理员的工作 同时也方便广大用户对个人所需
  • openGL增强表面细节--高度贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 高度贴图原理 二 代码实现 1 c 主程序 2 着色器程序 运行效果 源码下载 前言 现在我们扩展法线贴图的概念 从纹理图像用于扰动法向量到扰乱顶点位置本身 实 际上