使用OpenGL 立方体贴图

2023-11-09

openGL系列文章目录

前言

对于室外3D 场景,通常可以通过在地平线上创造一些逼真的效果,来增强其真实感。
当我们极目远眺,目光越过附近的建筑和森林,我们习惯于看到远处的大型物体,例如:
云、群山或太阳(或夜空中的星星和月亮)。但是,将这些对象作为单个模型添加到场景中
可能会产生高到无法承受的性能成本。天空盒或天空穹顶提供了有效且相对简单的方法,
用来生成令人信服的地平线景观。

一、OpenGL 立方体贴图

构建天空盒的另一种方法是使用OpenGL 纹理立方体贴图。OpenGL 立方体贴图比我们
在上一节中看到的简单方法稍微复杂一点。但是,使用OpenGL 立方体贴图有自己的优点,
例如减少接缝以及支持环境贴图。
OpenGL 纹理立方体贴图类似于稍后将要研究的3D 纹理,它们都使用3 个纹理坐标访
问——通常标记为(s, t, r)——而不是我们目前为止用到的两个。OpenGL 纹理立方体贴图
的另一个特性是,其中的图像以纹理图像的左上角(而不是通常的左下角)作为纹理坐标
(0, 0, 0),这通常是混乱产生的源头。
程序9.1 中展示的方法通过读入单个图像来为立方体贴图添加纹理,而程序9.2 中展示
的loadCubeMap()函数则读入6 个单独的立方体面图像文件。正如我们在第5 章中所学的,
有许多方法可以读取纹理图像,我们选择使用SOIL2 库。在这里,SOIL2 用于实例化和加
载OpenGL 立方体贴图也非常方便。我们先找到需要读入的文件, 然后调用
SOIL_load_OGL_cubemap(),其参数包括6 个图像文件和一些其他参数,类似于我们在第5
章中看到的SOIL_load_OGL_texture()。在使用OpenGL 立方体贴图时,无须垂直翻转纹理,
OpenGL 会自动进行处理,注意,loadCubeMap()函数放在“Utils.cpp”文件中。
init()函数现在包含一个函数调用以启用GL_TEXTURE_CUBE_MAP_SEAMLESS,它告
诉OpenGL 尝试混合立方体相邻的边以减少或消除接缝。在display()中,立方体的顶点像以
前一样沿管线向下发送,但这次不需要发送立方体的纹理坐标。我们将会看到,OpenGL 纹
理立方体贴图通常使用立方体的顶点位置作为其纹理坐标。之后禁用深度测试并绘制立方
体。然后为场景的其余部分重新启用深度测试。
完成后的OpenGL 纹理立方体贴图使用了int 类型的标识符进行引用。与阴影贴图时一
样,通过将纹理包裹模式设置为“夹紧到边缘”,可以减少沿边框的伪影。在这种情况下,
它还可以帮助进一步缩小接缝。请注意,这里需要为3 个纹理坐标s、t 和r 都设置纹理包
裹模式。
在片段着色器中使用名为samplerCube 的特殊类型的采样器访问纹理。在纹理立方体贴
图中,从采样器返回的值是沿着方向向量(s, t, r)从原点“看到”的纹素。因此,我们通常可
以简单地使用传入的插值顶点位置作为纹理坐标。在顶点着色器中,我们将立方体顶点位
置分配到输出纹理坐标属性中,以便在它们到达片段着色器时进行插值。另外需要注意,
在顶点着色器中,我们将传入的视图矩阵转换为3×3,然后再转换回4×4。这个“技巧”
有效地移除了平移分量,同时保留了旋转(回想一下,平移值在转换矩阵的第四列中)。这
样,就将立方体贴图固定在了摄像机位置,同时仍允许合成相机“环顾四周”。

二、使用步骤

1.代码

#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 "Torus.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

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;

float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float torLocX = 0.f, torLocY = 0.f, torLocZ = 0.f;
GLuint renderingProgram = 0, renderingProgramCubeMap = 0;

static const int numVAOs = 1;
static const int numVBOs = 5;
GLuint vao[numVAOs] = { 0 };
GLuint vbo[numVBOs] = { 0 };

GLuint brickTexture = 0, skyboxTexture = 0;
float rotAmt = 0.f;

// variable allocation for display
GLuint vLoc = 0, mvLoc = 0, projLoc = 0;
int width = 0, height = 0;
float aspect = 0.f;
glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f);


Torus myTorus(0.8f, 0.2f, 48);
int numTorusVertices = 0, numTorusIndices = 0;

Camera camera(glm::vec3(0.f, 0.f, 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)
{
	float cubeVertexPositions[108] =
	{
		-1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
		1.0f, -1.0f, -1.0f, 1.0f,  1.0f, -1.0f, -1.0f,  1.0f, -1.0f,
		1.0f, -1.0f, -1.0f, 1.0f, -1.0f,  1.0f, 1.0f,  1.0f, -1.0f,
		1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f, 1.0f,  1.0f, -1.0f,
		1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f, 1.0f,  1.0f,  1.0f,
		-1.0f, -1.0f,  1.0f, -1.0f,  1.0f,  1.0f, 1.0f,  1.0f,  1.0f,
		-1.0f, -1.0f,  1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
		-1.0f, -1.0f, -1.0f, -1.0f,  1.0f, -1.0f, -1.0f,  1.0f,  1.0f,
		-1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f, -1.0f,
		1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,  1.0f,
		-1.0f,  1.0f, -1.0f, 1.0f,  1.0f, -1.0f, 1.0f,  1.0f,  1.0f,
		1.0f,  1.0f,  1.0f, -1.0f,  1.0f,  1.0f, -1.0f,  1.0f, -1.0f
	};

	numTorusVertices = myTorus.getNumVertices();
	numTorusIndices = myTorus.getNumIndices();

	vector<int> ind = myTorus.getIndices();
	vector<glm::vec3> vert = myTorus.getVertices();
	vector<glm::vec2> text = myTorus.getTexCoords();
	vector<glm::vec3> norm = myTorus.getNormals();

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

	for (int i=0; i<numTorusVertices; 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, sizeof(cubeVertexPositions), cubeVertexPositions, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &pValues[0], GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
	glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &tValues[0], GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
	glBufferData(GL_ARRAY_BUFFER, nValues.size() * sizeof(float), &nValues[0], GL_STATIC_DRAW);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(int), &ind[0], GL_STATIC_DRAW);
}

void init(GLFWwindow* window)
{
	renderingProgram = Utils::createShaderProgram("vertShader.vert", "fragShader.frag");
	renderingProgramCubeMap = Utils::createShaderProgram("vertCubeShader.vert", "fragCubeShader.frag");

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

	setupVertices();
	
	brickTexture = Utils::loadTexture("brick1.jpg");
	skyboxTexture = Utils::loadCubeMap("cubeMap");  // expects a folder name
	//开启GL_TEXTURE_CUBE_MAP_SEAMLESS在天空盒子的边缘将对两个交界面进行采样混合,否则边缘将采用单边像素,会出现明显的裂缝。
	glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

	torLocX = 0.f, torLocY = 0.f, torLocZ = 0.f;
	cameraX = 0.f, cameraY = 0.f, cameraZ = 5.f;
}

void display(GLFWwindow* window, double currentTime)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.f, 0.5f, 1.f, 1.f);

	//vMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, cameraZ));

	// draw cube map
	glUseProgram(renderingProgramCubeMap);

	deltaTime = currentTime - lastFrame;
	lastFrame = currentTime;

	do_movement();
	//这句必须要有,否则鼠标中键失效
	pMat = glm::perspective(camera.Zoom, aspect, 0.01f, 1000.f);

	vMat = camera.GetViewMatrix();

	//没有这句,背景就没在相机视点上了,把圆环移到相机的位置
	mMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, 4.f));

	mvLoc = glGetUniformLocation(renderingProgramCubeMap, "mv_matrix");
	glUniformMatrix4fv(vLoc, 1, GL_FALSE, glm::value_ptr(mvMat));

	projLoc = glGetUniformLocation(renderingProgramCubeMap, "proj_matrix");
	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);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, skyboxTexture);

	//开启剔除操作效果
	glEnable(GL_CULL_FACE);
	//GL_CCW 表示窗口坐标上投影多边形的顶点顺序为逆时针方向的表面为正面。
	//GL_CW    表示窗口坐标上投影多边形的顶点顺序为顺时针方向的表面为正面。
	glFrontFace(GL_CCW);
	glDisable(GL_DEPTH_TEST);
	glDrawArrays(GL_TRIANGLES, 0, 36);
	glEnable(GL_DEPTH_TEST);

	// draw scene (in this case it is just a torus)
	glUseProgram(renderingProgram);

	mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
	projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");

	mMat = glm::translate(glm::mat4(1.f), glm::vec3(torLocX, torLocY, torLocZ));
	mMat = glm::rotate(mMat, toRadians(35.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));

	//vbo[0] 是立方体纹理贴图

	glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(0);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(1);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(2);

	glBindBuffer(GL_ARRAY_BUFFER, vbo[4]);
	glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(3);

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

	glClear(GL_DEPTH_BUFFER_BIT);
	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);
	glDisable(GL_LEQUAL);
	glDrawArrays(GL_TRIANGLES, 0, 36);
	glEnable(GL_DEPTH_TEST);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
	glDrawElements(GL_TRIANGLES, numTorusIndices, GL_UNSIGNED_INT, 0);
}

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

	GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "skybox opengl six face", nullptr, nullptr);
	if (!window)
	{
		cout << "GLFW create window failed,invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
		glfwTerminate();
		exit(EXIT_FAILURE);
	}

	glfwMakeContextCurrent(window);
	glfwSetWindowSizeCallback(window, window_size_callback);
	//glfwSetKeyCallback(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);

	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 position;
layout(location = 1) in vec2 texCoord;
out vec2 tc;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

layout(binding = 0) uniform sampler2D samp;

void main(void)
{
	tc = texCoord;
	gl_Position = proj_matrix * mv_matrix * vec4(position, 1.f);
}

2.片元着色器

#version 460 core

in vec2 tc;
out vec4 fragColor;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
layout(binding = 0) uniform sampler2D samp;

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

  1. 立方体顶点着色器
#version 460 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;

out vec3 tc;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

layout(binding = 0) uniform sampler2D samp;

void main(void)
{
	tc = position;
	mat4 v3_matrix = mat4(mat3(mv_matrix));
	gl_Position = proj_matrix * v3_matrix * vec4(position, 1.f);
}

4.立方体片元着色器

#version 460 core

in vec3 tc;
out vec4 fragColor;

uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

layout(binding = 0) uniform samplerCube samp;

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

运行结果

在这里插入图片描述

注意

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;

其中 location = 0,一定要和程序的顶点缓冲区vbo索引一致,否则渲染会出问题

如果写成这样:
在这里插入图片描述
运行结果
在这里插入图片描述
或者写成这样
在这里插入图片描述
中间圆环的纹理都会出问题

源码下载

源码下载地址

参考

计算机图形学编程 使用OpenGL和C++

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

使用OpenGL 立方体贴图 的相关文章

  • 如何将 3D 图像输出到 3D 电视?

    我有一台 3D 电视 如果我不至少尝试让它显示我自己创作的漂亮 3D 图像 我就会逃避我的责任 作为一个极客 我之前已经完成了非常基本的 OpenGL 编程 因此我了解所涉及的概念 假设我可以为自己渲染一个简单的四面体或立方体并使其旋转一点
  • 使用 Opengl 绘制立方体 3D

    我想使用 OpenGL 绘制 3D 立方体这是我的代码如何纠正错误 float ver 8 3 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
  • 哪个对缓存最友好?

    我试图很好地掌握面向数据的设计以及如何在考虑缓存的情况下进行最佳编程 基本上有两种情况我无法完全确定哪个更好以及为什么 是拥有一个对象向量更好 还是拥有对象原子数据的多个向量更好 A 对象向量示例 struct A GLsizei mInd
  • (定义一个宏)方便OpenGL命令调试?

    有时插入条件打印和检查需要很长时间glGetError 使用二分搜索的形式来缩小范围 其中第一个函数调用是 OpenGL 首先报告错误 我认为如果有一种方法可以构建一个宏 我可以包装所有可能失败的 GL 调用 并有条件地调用 那就太酷了gl
  • 如何用opengl制作2D地形?

    我想制作一个简单的二维地形 只有一些颠簸和高度变化 我想过只使用随机数来描述某个顶点的高度 但我不知道如何从中制作一个网格 我正在寻找一种方法来查找地形的顶点和索引缓冲区 我该怎么做呢 您可以仅将 GL POLYGON 与所有顶点的列表一起
  • 法线在 openGL 中表现得很奇怪

    我一直在为 openGl 编写一个 obj 加载器 几何体加载得很好 但法线总是混乱的 我尝试在两个不同的程序中导出模型 但似乎没有任何效果 据我所知 这就是将法线放入 GL TRIANGLES 的方法 glNormal3fv norm1
  • glutPostRedisplay 不在循环内工作

    我试图让一个人在 y 轴上跳跃 所以我使用 2 秒的循环 第一秒它应该向下移动并弯曲膝盖 第二秒它应该向上移动 然后在起始位置完成 现在我刚刚开始让这个人在第一秒内跪下并弯曲膝盖 我还没有编写动画的其余部分 问题是 glutPostRedi
  • 简单的线框格式?

    我正在寻找一种用于线框模型的简单文件格式 我知道 VRML u3D 等 但这些对于我的需求来说似乎很重要 我的标准是 必须有明确的规格 要么是开放的 要么是非常完善 记录的 我只需要 想要 简单的模型 顶点和边 我不想处理面孔或物体 如果格
  • lnk1104:无法打开“LIBC.lib”链接

    使用 GLee 将着色器写入我的 OpenGL 项目并编译后 我收到了错误LNK1104 cannot open file LIBC lib 我尝试按照其他人的建议添加它并忽略它 但没有解决问题 有没有其他方法可以解决我错过的这个问题 以下
  • 使用 GLSL 着色器在同一片段着色器中定义的多个子例程类型无法正常工作

    我正在开发一个使用 GLSL 着色器的程序 我编写了 2 种不同的方法来用 2 种不同的方法计算 ADS 环境光 漫反射 镜面反射 着色 为了正确完成这项工作 我使用子例程来使用一种或另一种方法来计算 ADS 着色 这是片段着色器代码的一部
  • Eclipse 标记 OpenGL 函数无法解析

    我尝试在 Eclipse C C 中使用一些 OpenGL 函数 一些 标准 函数如 GlClear 可以被 eclipse 识别 而其他函数如 glBindBuffer 和 glEnableVertexAttribArray 则不能 它们
  • 使用draw()而不是eventloop时的pyglet

    我正在尝试用 pyglet 画一个圆 但当我使用 draw 函数而不是 app run 循环时 它是不可见的 有什么建议我可以做什么吗 谢谢 from math import from pyglet gl import window pyg
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • GLSL NVidia 方形神器

    当 GLSL 着色器在以下 GPU 上生成不正确的图像时 我遇到了问题 GT 430 GT 770 GTX 570显卡760 但在这些上正常工作 英特尔高清显卡 2500英特尔高清4000英特尔4400显卡740MRadeon HD 631
  • 三角形纹理映射OpenGL

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

    在 OpenGL JOGL 中 当使用多个剪切平面时 似乎会应用所有剪切平面的并集 我想要的是路口要应用的所有剪裁平面 这可能吗 请参阅下面的简化二维示例 Edit An example of clipping by vertex shad
  • OpenGL:伽玛校正图像看起来不线性

    我使用 OpenGL 进行渲染 当我将线性值写入默认帧缓冲区 没有任何伽玛校正 时 它们在我的显示器上显示为线性 这违背了我认为我所知道的关于伽马校正的一切 如下所述 http gamedevelopment tutsplus com ar
  • 更改 GLUT 调用以与 MFC/C++ 一起使用

    我有一个使用 GLUT 进行 OpenGL 渲染的程序 现在我需要它位于 MFC 项目内部 以便它可以与另一个程序组件一起使用 我已经按照这个教程进行操作 http www codeguru com cpp g m opengl openf
  • glDrawElements 只绘制半个四边形

    这是我的功能 void Object draw2 if mIsInitialised return Tell OpenGL about our vertex and normal data glEnableClientState GL VE
  • SSBO 是更大的 UBO?

    我目前正在 OpenGL 4 3 中使用 UBO 进行渲染 以将所有常量数据存储在 GPU 上 诸如材料描述 矩阵等内容 它可以工作 但是 UBO 的小尺寸 我的实现为 64kB 迫使我多次切换缓冲区 减慢渲染速度 我正在寻找类似的方法来存

随机推荐

  • linux 线程局部存储,tls_windows

    线程局部存储 线程局部存储 thread local storage TLS 是一个使用很方便的存储线程局部数据的系统 利用TLS机制可以为进程中所有的线程关联若干个数据 各个线程通过由TLS分配的全局索引来访问与自己关联的数据 这样 每个
  • v-model绑定checkbox无法动态更新视图

    在vue2中使用v model绑定checkbox
  • Python爬虫(入门+进阶)学习笔记 1-6 浏览器抓包及headers设置(案例一:爬取知乎)

    爬虫的一般思路 抓取网页 分析请求 解析网页 寻找数据 储存数据 多页处理 本节课主要讲授如何通过谷歌浏览器开发者工具分析真实请求的方法 寻找真实请求的三个步骤 分析 使用谷歌浏览器开发者工具分析网页的请求 测试 测试URL请求中每个参数的
  • echarts实现颜色渐变的环状图(包括自定义各种配置项的属性)

    实现效果 实现代码 option color new echarts graphic LinearGradient 1 1 0 0 offset 0 color F2A635 offset 0 9 color ffffff new echa
  • 为Qt应用程序的用户添加帮助文档

    qt5 简单文本查看器例子 Qt Assistant支持交互式帮助 并使您能够向Qt应用程序的用户显示客户文档 以下示例说明如何将Qt Assistant用作应用程序的帮助查看器 使用Qt Assistant作为应用程序的自定义help查看
  • Oracle V$SESSION详解

    V SESSION是APPS用户下面对于SYS V SESSION 视图的同义词 在本视图中 每一个连接到数据库实例中的session都拥有一条记录 包括用户session及后台进程如DBWR LGWR arcchiver等等 V SESS
  • 大数据环境下的“隐形隐私”保护问题

    导语 隐形隐私 泄漏问题一直我们乃至全球最难解决的问题 数据安全不止是一个企业发展的核心关键 更关系到企业单位的生死存亡 企业单位重要客户信息泄露并在市面上大肆流通发生之后我们在想尽各种方法亡羊补牢 可是我们数据安全难道不是要从最一开始就做
  • 针对初学者,解决一些问题【Kali】手把手教你设置Kali源地址以及更新源和安装所有工具命令

    文章目录 一 设置添加修改源地址 1 首先在命令提示符中输入以下命令打开源列表文件 2 按i进入编辑模式 3 在下面源地址中至少选择一个复制粘贴进去 4 添加进入以后按ESC键退出编辑模式 按 输入wq保存退出 二 更新源命令 三 软件包操
  • TCP为什么需要三次握手

    tcp为什么要第三次握手 time wait是做什么的 tcp有几种状态 画出所有的状态转换图 晚上看到的面试题 TCP三次握手的印象很深 但为什么需要3次握手 还是想不起来了 简单而言 如果不是三次握手的话 那么到底需要几次握手最佳呢 2
  • 关于毕业求职的就业经验-写给我亲爱的校友们

    提示 希望下面的文章对大家能有所帮助 文章目录 前言 一 毕业季的几种选择 1 考研 2 就业 3 其他 二 到了毕业季应该怎么去找到自己心怡的工作 三 需要掌握的基本技能 以我嵌入式开发角度 四 该怎么去跳槽到更好的公司 五 未来规划 1
  • SPARK安装

    首先是结论 最终我没能在win10上运行起来spark 官方给的quickstart http spark apache org docs latest api python getting started quickstart html
  • Matlab学习1.0

    1 Matlab通用命令 1 常用命令 cd 显示 or改变当前文件夹 dir 显示当前文件夹下的文件 clc 清空工作窗中显示的内容 load 加载指定文件的变量 diary 日志文件命令 调用DOS命令 home 光标移动到窗口最左上角
  • 网络安全知识库

    0x00 前言 本篇用来整理所有的零散的知识 作为一个技能树或者技能表来进行引导 CTF 加解密合集 CTF Web合集 0x01 Http 1 http头 1 1 本地访问识别 如何伪造http头 让后端认为是本地访问 0x02 Web
  • Python爬虫反反爬:CSS反爬加密彻底破解!

    刚开始搞爬虫的时候听到有人说爬虫是一场攻坚战 听的时候也没感觉到特别 但是经过了一段时间的练习之后 深以为然 每个网站不一样 每次爬取都是重新开始 所以 爬之前谁都不敢说会有什么结果 前两天 应几个小朋友的邀请 动心思玩了一下大众点评的数据
  • css动画效果之transition(动画过渡效果属性)

  • pandas dataframe 读取 xlsx 文件

    refer to https medium com kasiarachuta reading and writingexcel files in python pandas 8f0da449cc48 dframe pd read excel
  • github代码推送总是失败

    github代码推送问题 因为github仓库代码的推送总是失败 所以改了一个方案采用ssh的方式来进行代码的推送 并记录操作步骤 方案 https方式换成ssh方式 git ssh 生成 假如已经生成的话 可以略过此步骤 ssh keyg
  • Android启动service的方法

    在 Android 中启动 service 的方法如下 创建 service 的类 并在 AndroidManifest xml 文件中注册该 service 使用 Intent 类来启动 service 例如 Intent intent
  • [转]公司管理混乱,从哪里入手?

    案例分析 我们是一个40人左右的小公司 规模虽小 但管理起来感觉力不从心 经常碰到工人抵抗 情绪化 上班迟到 旷工 不服从管理 即使勉强接受 也不会用心去做 草草应付了事 每次都提议是否弄个规章制度 但也是白纸一张 到了月底 实施不了 因为
  • 使用OpenGL 立方体贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一 OpenGL 立方体贴图 二 使用步骤 1 代码 2 着色器程序 运行结果 注意 源码下载 参考 前言 对于室外3D 场景 通常可以通过在地平线上创造一些逼真的效果 来