OpenGL学习例程精析(3d纹理)

2023-11-06

OpenGL学习例程精析(3d纹理)

代码分析

3d纹理的配置要比2d纹理复杂一些

glPixelStorei

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

让字节对齐从默认的4字节对齐改成1字节对齐(选择1的话,无论图片本身是怎样都是绝对不会出问题的,以效率的牺牲为代价)
涉及到cpu把纹理传给gpu要按照像素的方式,这样提取出来就是整齐的rgba格式

PACK —— 把像素从一堆X的状态转变到规则的状态(把一堆泥土装载进一个花盆,把散散的货物装上货柜,或者把一堆各样的文件打包成一个rar压缩包,等等);
UNPACK —— 把像素从规则的状态转变到一堆X的状态(把花盆里的泥倒出来,把货柜中的货物卸载到盐田港,或者解压压缩包,等等)。

从本地内存向GPU的传输(UNPACK),包括各种glTexImage、glDrawPixel;从GPU到本地内存的传输(PACK),包括glGetTexImage、glReadPixel等

完整代码

#include <GL/glut.h>
#include <GL/glext.h>
#include <stdlib.h>
#include <stdio.h>

#ifdef GL_VERSION_1_2
#define iWidth 16
#define iHeight 16
#define iDepth 16

static GLubyte image[iDepth][iHeight][iWidth][3]; //深度,高度,宽度+3个颜色通道
static GLuint texName;

/*  Create a 16x16x16x3 array with different color values in
*  each array element [r, g, b].  Values range from 0 to 255.
*/
PFNGLTEXIMAGE3DPROC glTexImage3D;  //定义一个glTexImage3D指针

void makeImage(void)		//造纹理
{
	int s, t, r;

	for (s = 0; s < 16; s++)
		for (t = 0; t < 16; t++)
			for (r = 0; r < 16; r++) {
				image[r][t][s][0] = (GLubyte) (s * 17);
				image[r][t][s][1] = (GLubyte) (t * 17);
				image[r][t][s][2] = (GLubyte) (r * 17);
			}
}

void init(void)
{    
	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_FLAT);      //两点之间的着色模式为片状,另一个参数可以写为,GL_SMOOTH这样绘制出来的就是渐变效果
	//glShadeModel(GL_SMOOTH);   
	glEnable(GL_DEPTH_TEST);	//启用深度测试

	makeImage();				//产生纹理
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, &texName);
	glBindTexture(GL_TEXTURE_3D, texName);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	//q是一个缩放因子,相当于顶点坐标中的w。实际应用在纹理读取中的坐标应该是s/q,t/q,r/q。默认情况下,q是1.0。通常情况下貌似没什么用,但是在一些产生纹理坐标的高级算法比如阴影贴图中
	//s、t、r分别相当于普通坐标系中的x、y、z三个方向。分别对应glTexImage3D中的参数width、height、depth。
	glTexImage3D = reinterpret_cast< PFNGLTEXIMAGE3DPROC>( ::wglGetProcAddress( "glTexImage3D") );  //使能glTexImage3D指针
	glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
	glEnable(GL_TEXTURE_3D);
	
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBegin(GL_QUADS);
	glTexCoord3f(0.0, 0.0, 0.0); glVertex3f(-2.25, -1.0, 0.0);
	glTexCoord3f(0.0, 1.0, 0.0); glVertex3f(-2.25, 1.0, 0.0);
	glTexCoord3f(1.0, 1.0, 1.0); glVertex3f(-0.25, 1.0, 0.0);
	glTexCoord3f(1.0, 0.0, 1.0); glVertex3f(-0.25, -1.0, 0.0);

	glTexCoord3f(0.0, 0.0, 1.0); glVertex3f(0.25, -1.0, 0.0);
	glTexCoord3f(0.0, 1.0, 1.0); glVertex3f(0.25, 1.0, 0.0);
	glTexCoord3f(1.0, 1.0, 0.0); glVertex3f(2.25, 1.0, 0.0);
	glTexCoord3f(1.0, 0.0, 0.0); glVertex3f(2.25, -1.0, 0.0);
	glEnd();
	glFlush();
}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -4.0);
}

void keyboard(unsigned char key, int x, int y)
{
	switch (key) {
  case 27:
	  exit(0);
	  break;
	}
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(250, 250);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	init();

	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutKeyboardFunc (keyboard);
	glutMainLoop();
	return 0; 
}
#else
int main(int argc, char** argv)
{
	fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
	fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
	fprintf (stderr, "you may be able to modify this program to make it run.\n");
	return 0;
}
#endif

最终效果

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

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

OpenGL学习例程精析(3d纹理) 的相关文章

  • glDrawElements 在 PyOpenGL 中绘制立方体

    我最近开始通过 Python 学习 OpenGL 这要归功于几个教程 尤其是 Nicolas P Rougier 的教程 http www labri fr perso nrougier teaching opengl http www l
  • VBO - 没有指数化的指数化

    我正在尝试将 VBO 与元素数组缓冲区一起用于我的三角形 如下所示 glBindBuffer GL ARRAY BUFFER g Buffer 0 glVertexPointer 3 GL FLOAT 0 BUFFER OFFSET 0 g
  • 将 CVPixelBuffer 渲染到 NSView (macOS)

    我有一个CVPixelBuffer我正在尝试在屏幕上有效地绘制 转变为低效率的方式NSImage可以工作 但速度非常慢 丢掉了大约 40 的帧数 因此 我尝试使用将其渲染在屏幕上CIContext s drawImage inRect fr
  • 如何以编程方式在 qml 中渲染 vtk 项目?

    到目前为止 我了解到我们在 QML 中有两个线程 我们的主应用程序线程和我们的 场景图 线程 http doc qt io qt 5 qtquick visualcanvas scenegraph html http doc qt io q
  • 从文件中读取 GLSL 着色器

    我正在尝试从如下所示的文件中读取顶点和片段着色器 version 330 core in vec3 ourColor out vec4 color void main color vec4 ourColor 1 0f but when i
  • OpenGL Z 偏置(多边形偏移)限制

    我有两个共面的多边形 我尝试做 glEnable GL POLYGON OFFSET FILL glPolygonOffset 0 1 并期望其中一个明显 位于 另一个之上 这种情况直到大约 70 75 个单位之外 近剪裁平面为 1 远剪裁
  • 使用 openGL、SOIL 加载图像

    我尝试了很多使用 SOIL 在 openGL 中加载和显示图像的示例 运行下面的源代码时 它仅显示一个没有图像的白色四边形 我尝试打开一个名为 foto 的图像 我将图像文件放在程序的文件夹中 bool keyStates new bool
  • OpenGL 说“from_param 收到了一个不连续的数组”

    安装 Yosemite 后 我必须升级 numpy PyOpenGL 等 现在 以前运行的程序给了我以下堆栈跟踪 file latebind pyx line 44 in OpenGL accelerate latebind Curry c
  • 在 OpenGL 中,为什么 glVertexAttribPointer 要求“指针”参数以 void* 形式传入?

    规格为glVertexAttribPointer如下 void glVertexAttribPointer GLuint index GLint size GLenum type GLboolean normalized GLsizei s
  • OpenGL 和加载/读取 AoSoA(混合 SoA)格式的数据

    假设我有以下 AoSoA 格式的简化结构来表示顶点或点 struct VertexData float px 4 position x float py 4 position y 也就是说 每个实例VertexData存储4个顶点 我见过的
  • 使用 Qt 在 xoverlay 之上绘制

    我希望在使用 Xoverlay 渲染的视频流之上绘制一些 UI 我正在使用 gstreamer 播放视频并使用 xoverlay 在 xvimagesink 上渲染它 我的小部件继承自 QGLWidget 我希望使用 QPainter 绘制
  • 即使在顶点着色器中使用,glGetUniformLocation()也会返回-1

    我正在尝试用法线渲染一个简单的立方体 我使用以下代码来初始化着色器 void initShader const char vertexShaderPath const char fragmentShaderPath cout lt lt I
  • 为什么我的 FPS 相机一劳永逸地滚动?

    如果我忽略四元数代数的肮脏细节 我想我理解了旋转和平移变换背后的数学 但仍然不明白我做错了什么 为什么我的相机一劳永逸地滚动 更具体地说 我应该如何从相机的方向 旋转矩阵 计算相机视图矩阵 我正在用 Python 编写一个简约的 3d 引擎
  • 不理解 gluOrtho2D 函数

    我不能做什么gluOrtho2D 函数是做什么的 是否将原点固定在 OpenGL 窗口上的某个特定点或其他位置 这是因为gluOrtho2D 1 1 1 1 将原点固定在窗口的中间 如果它在某个时刻没有修复原点 那么有什么方法可以修复原点
  • 使用 C# 截取任何外部应用程序的屏幕截图

    我们有一个 C WPF 应用程序 我们想要在其中截取我们启动的任意应用程序的屏幕截图 即 我们可以引用我们启动的进程 应用程序可能已最小化或位于其他窗口后面 但我们仍然只需要单个应用程序的图像 而不是重叠像素 我知道使用 BitBlt 或的
  • 如果我用opengl绘图的话SDL Renderer就没用了吗?

    我正在学习 SDL2 但我也在使用使用 OpenGL 调用的 imgui 库 从我在网上各种博客上读到的内容来看 我无法轻松混合 SDL2 渲染器和 opengl 调用 我要么使用其中之一 要么使用另一个 我读过的大多数教程都使用渲染器 所
  • PyQt5 的 OpenGL 模块和版本控制问题(调用不正确的 _QOpenGLFunctions_(ver))

    我一直在努力得到PyQt5 helloGL 示例代码 https github com baoboa pyqt5 blob master examples opengl hellogl py编译 当我尝试构建解决方案时 我得到 Traceb
  • 为什么拥有单独的投影矩阵但结合模型和视图矩阵会有好处?

    当您学习 3D 编程时 您会被告知用 3 个变换矩阵来思考是最简单的 模型矩阵 该矩阵对于每个模型都是独立的 它根据需要旋转和缩放对象 最后将其移动到 3D 世界中的最终位置 模型矩阵将模型坐标转换为世界坐标 视图矩阵 对于大量对象 如果不
  • OpenGL - 两个纹理的幂

    OpenGL 使用二次幂纹理 这是因为由于 MipMapping 某些 GPU 只接受 2 的幂纹理 当绘制比实际更大的纹理时 使用这些二次方纹理会导致问题 我想到了一种方法来解决这个问题 即仅在我们使纹理小于实际大小时使用 PO2 比率
  • Opengl 像素完美 2D 绘图

    我正在研究 2d 引擎 它已经工作得很好 但我不断收到像素错误 例如 我的窗口是 960x540 像素 我从 0 0 到 959 0 画一条线 我希望扫描线 0 上的每个像素都会被设置为一种颜色 但事实并非如此 最右边的像素没有被绘制 当我

随机推荐

  • Sqli-labs靶场详细攻略Less 23-28a

    Less 23 28a Less 23 GET Error based strip comments 这一关还是使用get方法进行注入 不过这次对 这些用于注释的字符做了过滤 这样我们可以使用两个 进行绕过 第一个 用于闭合原代码语句中的前
  • 【建议收藏】11+实战技巧,让你轻松从Vue过渡到React

    前言 在这个卷神辈出的时代 只是熟练Vue的胖头鱼 已经被毒打过多次了 面试中曾被质疑 你居然不会React 我无语凝噎 不知说啥是好 这篇文章尝试将Vue中一些常见的功能在React中实现一遍 如果你恰巧是Vue转React 或者Reac
  • Shell笔记--Shell使用系统变量、自定义变量、特殊变量和运算符

    目录 1 Shell使用系统变量 2 Shell使用自定义变量 3 特殊变量 3 1 n 3 2 3 3 和 3 4 4 运算符 1 Shell使用系统变量 常用的系统变量有 HOME PWD SHELL USER 等 echo HOME
  • Spring 基础教程之三:JavaBean生命周期

    Spring中Bean 的生命周期 在学习 spring 的过程中 bean 的生命周期理解对学习 spring 有很大的帮助 下面我就分别介绍在 ApplicationContext 和 BeanFactory 中 Bean 的生命周期
  • CrtIsValidHeapPointer(block)错误

    删除线格式 CrtIsValidHeapPointer block 内存错误 今天写代码时VS2019报了 CrtIsValidHeapPointer block 的错误 VS报错 https img blog csdnimg cn 202
  • chatgpt赋能python:免费的Python编程软件:开发者必备工具!

    免费的Python编程软件 开发者必备工具 Python是一门广受欢迎的编程语言 它已经成为了很多公司和开发者的首选语言 Python的出现改变了编程的方式 它具有简单 易懂 易读 易写 易拓展等特点 因此成为了很多新手入门的语言 Pyth
  • 火山视窗超级列表框-报表列表框操作

    本源码转载自利快云https www lkuaiy com 火山视窗超级列表框 报表列表框操作 想要使用本组件首选需要配置mfc扩展界面支持类库模块 超级列表框组件是火山中非常常用的一个组件 共有几种类型 大图标列表框 小图标列表框 普通列
  • 各种加密算法比较

    各种加密算法比较 算法选择 对称加密AES 非对称加密 ECC 消息摘要 MD5 数字签名 DSA 对称加密算法 加解密密钥相同 名称 密钥长度 运算速度 安全性 资源消耗
  • 根据文件夹修改时间自动打包ZIP

    Automatically package to zip file based on the modification time of the folder echo off set file dist for A in file do s
  • R-CNN算法详解

    这是一篇比较早的Object Detection算法 发表在2014年的CVPR 也是R CNN系列算法的开山之作 网上可以搜到很多相关的博客讲解 本篇博文没有按论文顺序来讲述 而是结合自己经验来看这个算法 希望给初学者一个直观的感受 细节
  • 普通人如何通过网络实现在家赚钱?

    作者 杨小二 来源 杨小二的小江湖 前言 2020年1月份的时候 在网上看到一则新闻说 2020年底前全面取消事业编制 32种事业工种打破铁饭碗 这件事情 在我们这个IT圈里还引起了大家的一些讨论 本想着考个公务员来养老 看来是没有希望了
  • Redis的哨兵模式以及工作原理

    Redis的哨兵模式以及工作原理 哨兵的作用 通过发送命令 让Redis服务器返回监控其运行状态 包括主服务器和从服务器 当哨兵监测到master宕机 会自动将slave切换成master 然后通过发布订阅模式通知其他的从服务器 修改配置文
  • C#读取硬盘物理序列号-非管理员权限

    using System using System Collections Generic using System Text using System Runtime InteropServices namespace SCBLL Com
  • 服务器(Linux系统)指定目录安装Anaconda教程

    1 下载 通过weg命令下载 Xshell终端输入命令 wget c https repo anaconda com archive Anaconda3 2020 11 Linux x86 64 sh 输入后开始下载 我这里用的pychar
  • VC++如何计算一段代码的执行时间

    单位为毫秒 在程序调试的过程中 VS2010包含
  • java/php/net/python会员健身系统管理设计

    本系统带文档lw万字以上 答辩PPT 查重 如果这个题目不合适 可以去我上传的资源里面找题目 找不到的话 评论留下题目 或者站内私信我 有时间看到机会给您发 本课题要求实现一套会员健身系统管理 系统功能包括会员 个人资料管理 教练信息管理
  • 使用 VS2022 配置 QT 开发环境的步骤

    使用 VS2022 配置 QT 开发环境的步骤 QT 是一个跨平台的 C GUI 库 可以在 Windows Mac Linux 等操作系统上运行 在 Visual Studio 2022 中配置 QT 的开发环境 可以让开发者在 Wind
  • Label Assignment

    前言 今天在研究四点模型的时候 了解到一个新概念 Label Assignment 记录一下 Label assignment 参考文档 目标检测中的Label Assignment Label assignment 主要是指检测算法在训练
  • 文件翻转教学python

    目录 第1关 读文件全部内容到一个字符串 第2关 读文件前n个字符 第3关 逐行读取并输出文件内容 第4关 读取文件到列表中 第5关 读取文件中的数据到二维列表 第6关 将唐诗写入到文件中 第1关 读文件全部内容到一个字符串 任务描述 本关
  • OpenGL学习例程精析(3d纹理)

    OpenGL学习例程精析 3d纹理 代码分析 glPixelStorei 完整代码 最终效果 代码分析 3d纹理的配置要比2d纹理复杂一些 glPixelStorei glPixelStorei GL UNPACK ALIGNMENT 1