OpenGl 游戏编程笔记 第七章:纹理映射 (texture mapping) (一)

OpenGL之纹理坐标及纹理映射 为了实现纹理贴图我们需要做三件事:将一张贴图加载到OpenGL中,提供纹理坐标和顶点(将纹理对应匹配到顶点上),并使用纹理坐标从纹理中进行取样操作取得像素颜色。由于三角形会被缩放、旋转、平移变换导致最后会以不同的结果投影显示到屏幕上,而且由于camera的不同操作看上去也会很不一样。GPU要做的就是让纹理紧跟三角形图元顶点的移动使其看上去真实(如果纹理看上去明显游离在三角形上产生错位就不真实了)。为实现这个效果开发者需要为每个顶点提供一系列纹理坐标。 阅读详情

转载http://caobeixingqiu.is-programmer.com/posts/18999.html#sec-4.3

OpenGl 游戏编程笔记 第七章:纹理映射 (texture mapping) (一)

本章你将学到

  • 纹理映射基础知识
  • 纹理坐标
  • 纹理对象及绑定
  • 纹理过滤
  • mipmap和自动生成mipmap
  • 纹理参数, 外包模式, 细节级别
  • 纹理环境和纹理函数

1 概述

     概括的说, 纹理映射机制允许你将一个图像关联到一个多边形上,从而呈现出真实视觉效果。例如, 你可以将书的封面图像应用到一个方形上, 这样这个方形看起来就像是一本书了。 你可以将地球的地图通过纹理映射应用到一个球体上, 那么这个球体就是一个3D的具真实感的地球了。纹理映射在当今的3D图形应用上处处皆是。今天的游戏都是通过纹理映射来作为虚拟真实的第一个步骤。

    纹理映射是一个二维的数组。数组中的每一项称之为纹理点( texel )。 虽然这个数组是二维的, 但是可以映射到非二维的对象上, 如球体或者其他的 3D 对象模型上。

    比较常见的是, 开发者在他们的图形应用中运用二维纹理, 当然一维或者三维的纹理也并非未闻。二维纹理有宽度和宽度决定二维。一维纹理也有宽度和高度, 只是高度被设为值 1(单位:像素 pixel). 而三维纹理不仅具有宽度和高度, 还有深度, 所以三维为纹理又称为立体纹理。我们讨论的主要是二维纹理。

2 预备知识: 纹理坐标

    在 OpenGl 中是通过指定纹理坐标来将纹理映射到多边形上去的. 在纹理坐标系中, 左下角是 (0,0), 右上角是 (1,1). 2D 纹理的坐标中通过指定 (s,t) (s为x轴上,t为y轴上, 取值0~1). 1D, 3D, 4D纹理坐标系中对应的需要指定 (s), (s,t,r), (s,t, r,q).

    纹理坐标需要通过函数 glTexCoord() 来设置, 此函数:

 
void glTexCoord{1234}{sifd}(TYPE coords);
void glTexCoord{1234}{sifd}v(TYPE coords);

    如将 2D 纹理坐标设为 (0.2, 0.4):

?
1
glTexCoord2f( 0 .2f, 0 .4f);

    每次通过 glVertex() 指定一个顶点时, 当前的纹理坐标会被应用到这个点上. 所以每指定一个新的顶点, 需要同时修改纹理坐标:

?
1
2
3
4
5
6
glBegin(GL_POLYGON);
         glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, 0.5f); //左下角
         glTexCoord2f(1.0f, 0.0f); glVertex3f(0.5f, 0.5f, 0.5f); // 右下角
         glTexCoord2f(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); // 右上角
         glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); // 左上角
glEnd();

    至此, 我们知道了纹理坐标如何赋值.且看如何创建纹理:

3 使用纹理映射

    纹理就是应用到多边形上的图像. 这些图像可以从文件中加载, 或是在内存中生成. 一旦你将图像数据加载到了内存中, 你需要指定其为纹理映射来使用它. 指定其为纹理映射, 首先需要生成一个纹理对象, 其中存储着纹理的诸如图像数据, 如何应用等信息.

    纹理是一个OpenGL状态, 因而通过 glEnable() 和 glDisable() 来开闭, 参数是 GL_TEXTURE_1D,  GL_TEXTURE_2D, GL_TEXTURE_3D,  GL_TEXTURE_CUBE_MAP.

3.1 纹理对象

    纹理对象是内部数据类型, 存储着纹理数据和选项等. 你不能直接访问它, 但是可以通过一个整数的 ID 来作为其句柄 (handler) 来跟踪之. 为了分配到一个唯一的 ID, OpenGL 提供了glGenTextures() 函数来获取一个有效的 ID 标识值:

 
void glGenTexture(Glsizei n, GLuint *texture);

    texture 是一个数组, 用于存储分配到的n个ID值. 在调用一次 glGenTextures() 后, 会将分配到的 ID 标识为'已用', 虽然直到绑定后才真正为'已用'.

    分配3个纹理对象 ID:

?
1
2
unsigned int textureObjects[3];
glGenTexture(3, textureObjects);

3.2 纹理绑定

    在第一次绑定一个纹理对象时, 会将一系列初始值来适应你的应用. 函数 glBindTexture() 用于绑定操作:

 
void glBindTexture(GLenum target, GLuint texture);

    target 指定了纹理类型: GL_TEXTURE_1D,  GL_TEXTURE_2D,  GL_TEXTURE_3D,  GL_TEXTURE_CUBE_MAP.  texure 是你希望绑定的纹理对象的 ID.

    一个被绑定的纹理对象直到被删除,或被另外的纹理对象绑定到 target 上才被解除绑定. 当一个纹理对象绑定到 target 上后, OpenGL 的后续的纹理操作都是基于这个纹理对象的。

?
1
2
3
4
5
6
7
8
9
10
glBindTexture (GL_TEXTURE_2D, textureObject[0]);
// 后面的对 GL_TEXTURE_2D 的纹理操作影响 textureObject[0]
 
glBindTexture (GL_TEXTURE_3D, textureObject[1]);
// 后面的对 GL_TEXTURE_3D 的纹理操作影响 textureObject[1]
// 对 GL_TEXTURE_2D 的纹理操作依然影响 textureObject[0]
 
glBindTexture (GL_TEXTURE_2D, textureObject[2]);
// 后面的对 GL_TEXTURE_2D 的纹理操作影响 textureObject[2]
// 对 GL_TEXTURE_3D 的纹理操作依然影响 textureObject[1]

3.3 删除纹理对象

    创建一个纹理对象后, OpenGL为其分配内存, 所以当不再使用一个纹理对象时, 为防止内存泄露, 必须删除. 删除纹理对象的函数: glDeleteTexture() :

 
void glDeleteTexure(Glsizei n, Gluint *texture);

    texture 指定了要删除的纹理对象的 ID (n个). 在删除后, texture 中的各个对象 ID 会置为0.

3.4 驻留纹理

    显卡有一块固定大小的内存区域专门用于存储纹理数据。当数据超量时,会将一部分纹理数据移除到系统内存中(通常是最近最少使用的纹理数据). 当这些移除的纹理被再次使用时,会影响击中率, 因为它们会被再次移入显卡的内存中。你可以查看一个纹理对象是否驻留在显卡内存中未被移出, 通过函数 glAreTexturesResident() :

 
GLboolean glAreTexturesResident (GLsizei n, GLuint *textures, GLboolean *residents);

    texture 中每一项纹理对象的驻留情况会存储在 resident 参数中返回。 若 textures 中有一项纹理对象不在内存驻留内存, 函数会返回 GL_FALSE.

3.5 纹理优先级

    纹理的优先级是针对驻留显卡内存而言。优先级设置函数 glPrioritizeTextures() :

 
void glPrioritizeTextures (GLsizei n, GLuint *textures, GLclampf *priorities)

    前两个参数 textures 和 n 指定了要设置优先级的纹理对象数组。 priorities 是 textures 中每一项纹理对象对应的优先级, priorities 中每一项的优先级取值区间是 [0,1], 0为优先级最低, 1 为最高。 glPrioritizeTextures() 函数会忽略掉那些未使用的和优先级要设为 0 的纹理对象。

4 指定纹理

    OpenGL 提供了三个函数来指定纹理: glTexImage1D(), glTexImage2D(), glTexImage3D(). 这三个版本用于相应维数的纹理, 例如如果纹理是3D纹理,则需要有 glTexImage3D() 来指定。

4.1 2D 纹理

 
void glTexImage2D (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* texels);

    参数 target 是 GL_TEXTURE_2D (二维纹理) 或 GL_PROXY_TEXTURE_2D (二维代理纹理), 代理纹理暂且不提。

    参数 level 指定了纹理映射细节的级别,用在mipmap中。 基本的纹理图像级别为0, 在后面的mipmap部分讲解。

    参数 internalFormat 指定了纹理存储在显存中的内部格式, 取值在下表, 为兼容 OpenGL1.0 internalFormat 可以取值 1,2,3,4 分别对应常量 LUMINANCE, LUMINANCE_ALPHA,  RGB,  RGBA.

纹理内部格式
格式注解
GL_ALPHAAlpha 值
GL_DEPTH_COMPONENT深度值
GL_LUMINCE灰度值
GL_LUMINANCE_ALPHA灰度值和 Alpha 值
GL_INTENSITY亮度值
GL_RGBRed, Green, Blue三原色值
GL_RGBARed, Green, Blue 和 Alpha 值

    参数 width 和 height 定义了纹理映射的大小,前面已经说过纹理映射就是一个二维数组。 和 glDrawPixels() 一样, 纹理映射的宽度和高度必须是 2 的整数次幂。

    参数 border 注明了纹理是否有边框。无边框取值为 0, 有边框取值为 1, 边框的颜色由 GL_TEXTURE_BORDER_COLOR 选项设置。

    接下来的三个参数主要定义了图像数据的格式。

    参数 format 定义了图像数据数组 texels 中的格式。可以取值如下:

图像数据数组 texels 格式
格式注解
GL_COLOR_INDEX颜色索引值
GL_DEPTH_COMPONENT深度值
GL_RED红色像素值
GL_GREEN绿色像素值
GL_BLUE蓝色像素值
GL_ALPHAAlpha 值
GL_RGBRed, Green, Blue 三原色值
GL_RGBARed, Green, Blue 和 Alpha 值
GL_BGRBlue, Green, Red 值
GL_BGRABlue, Green, Red 和 Alpha 值
GL_LUMINANCE灰度值
GL_LUMINANCE_ALPHA灰度值和 Alpha 值

    参数 type 定义了图像数据数组 texels 中的数据类型。可取值如下

图像数据数组 texels 中数据类型
数据类型注解
GL_BITMAP一位(0或1)
GL_BYTE带符号8位整形值(一个字节)
GL_UNSIGNED_BYTE不带符号8位整形值(一个字节)
GL_SHORT带符号16位整形值(2个字节)
GL_UNSIGNED_SHORT不带符号16未整形值(2个字节)
GL_INT带符号32位整形值(4个字节)
GL_UNSIGNED_INT不带符号32位整形值(4个字节)
GL_FLOAT单精度浮点型(4个字节)
GL_UNSIGNED_BYTE_3_3_2压缩到不带符号8位整形:R3,G3,B2
GL_UNSIGNED_BYTE_2__3_REV压缩到不带符号8位整形:B2,G3,R3
GL_UNSIGNED_SHORT_5_6_5压缩到不带符号16位整形:R5,G6,B5
GL_UNSIGNED_SHORT_5_6_5_REV压缩到不带符号16位整形:B5,G6,R5
GL_UNSIGNED_SHORT_4_4_4_4压缩到不带符号16位整形:R4,G4,B4,A4
GL_UNSIGNED_SHORT_4_4_4_4_REV压缩到不带符号16位整形:A4,B4,G4,R4
GL_UNSIGNED_SHORT_5_5_5_1压缩到不带符号16位整形:R5,G5,B5,A1
GL_UNSIGNED_SHORT_1_5_5_5_REV压缩到不带符号16位整形:A1,B5,G5,R5
GL_UNSIGNED_INT_8_8_8_8压缩到不带符号32位整形:R8,G8,B8,A8
GL_UNSIGNED_INT_8_8_8_8_REV压缩到不带符号32位整形:A8,B8,G8,R8
GL_UNSIGNED_INT_10_10_10_2压缩到32位整形:R10,G10,B10,A2
GL_UNSIGNED_INT_2_10_10_10_REV压缩到32位整形:A2,B10,G10,R10

    你可能会注意到有压缩类型, 先看看 GL_UNSIGNED_BYTE_3_3_2, 所有的 red, green 和 blue 被组合成一个不带符号的8位整形中,在 GL_UNSIGNED_SHORT_4_4_4_4 中是把 red, green , blue 和 alpha 值打包成一个不带符号的 short 类型。

    最后一个参数是 texels, 这个指针指向实际的图像数据(你自己生成的或是从文件中加载的)。OpenGL 会按照 type 参数指定的格式来读取这些数据,

    例如, 假设你加载了一个 RGBA 图像到 textureData 中( 宽高为 textureWidth, textureHeight).你想要用它来指定一个纹理, 可以这样做:

?
1
2
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0,
         GL_RGBA, GL_UNSIGNED_BYTE, textureData);

    执行完这个函数后, 纹理会加载,等待被使用。

4.2 1D 纹理

    1D 纹理其实就是 2D 纹理的特殊形式(高度等于1)。这类纹理常常用来描绘颜色边界从而创造出阴影效果。创建 1D 纹理的函数如下:

 
void glTExImage1D (GLenum target, GLint level, GLint internalFormat, GLsizei width,
GLint border, GLenum format, GLenum type, const GLvoid *texels);

    函数中的参数同 glTexImage2D(), 不同的是 height 参数没有被给出(因为定值1), 参数 target 也需要指定为 *GL_TEXTURE_1D*。

    下面是简单的代码, 用于创建32个纹理点宽度的 RGBA 纹理:

?
1
2
3
unsigned char imageData[128];
...
glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

4.3 3D 纹理

    创建 3D 纹理的函数:

 
glTexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *texels);

    函数参数同 glTexImage1D() 和 glTexImage2D() 大部分相同,不同的是多了一个深度参数 depth, 指定了纹理的第三维。

    下面的代码片段, 用于创建一个 16*16*16 个纹理点的 RGB 纹理:

?
1
2
3
...
glTexImage3D (GL_TEXTURE_3D, 0, GL_RGB, 16, 16, 16, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, imageData);

4.4 Cube Map 纹理

    一个 Cube Map 纹理是由6个2D纹理组成。对应的, 需要通过 glTexImage2D() 来指定6个 target 参数: GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,  GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,  GL_TEXTURE_CUBE_MAP_NEGATIVE_Z.

5 纹理过滤

    将纹理映射到多边形上, 实际上是将纹理的图像数据空间映射到帧缓冲图像空间上。所以, 你必须保证纹理图像加载完成。 纹理图像被映射到多边形上可能会造成失真。纹理图像映射到多边形上去,屏幕上的一个点可能是纹理点的一个部分(如果视口设置的离纹理很近), 也有可能屏幕上的一个像素点是多个纹理的集合(如果视口设置的足够远). 纹理过滤就是告诉 OpenGL 在纹理到屏幕像素点的映射中如何计算最终显示的图像数据。

    在纹理过滤中, 放大器处理一个屏幕像素点代表一个纹理点的一部分的情况;缩小器处理一个像素点代表多个纹理点的情况. 你可以通过下面函数来告诉 OpenGL 怎样处理这两种情况:

 
void glTexParameter{if}(GLenum target, GLenum pname, T param);
void glTexParameter{if}v(GLenum target, GLenum pname, T params);
glTexParameter 不仅仅设置放大器和缩小器, 在本章中,由于只涉及纹理,所以只讨论纹理相关的参数取值.

   参数 target 指的是纹理目标, 可以是 GL_TEXTURE_1D, GL_TEXTURE_2D*, GL_TEXTURE_3D 或 GL_TEXTURE_CUBE_MAP 。 指定纹理放大过滤器需要指定参数 pname 为 GL_TEXTURE_MAG_FILTER, 指定纹理缩小过滤器需要指定参数 pname 为 GL_TEXTURE_MIN_FILTER.

当指定为 GL_TEXTURE_MAG_FILTER, 参数 param 取值 GL_NEAREST 或 GL_LINEAR. 对放大过滤器而言, 使用 GL_NEAREST 将告诉 OpenGL 使用离像素点中心最近的纹理来渲染, 这被称作 点样( point sampling); 使用 GL_LINEAR 告诉 OpenGL 会使用离像素点中心最近的四个纹理的平均值来渲染. 这被称作 双线性过滤( bilinear filtering)。

缩小过滤器比放大过滤器的取值更广, 下表是指定缩小过滤器时, 参数 param 的取值, 下面表中的值是为了增强渲染质量。

缩小过滤器的参数
过滤参数注解
GL_NEAREST使用像素点中心最近的点渲染
GL_LINEAR使用双线性过滤
GL_NEAREST_MIPMAP_NEAREST 
GL_NEAREST_MIPMAP_LINEAR 
GL_LINEAR_MIPMAP_NEAREST 
GL_LINEAR_MIPMAP_LINEAR 

    在缩小过滤器中, 有4个参数处理mipmap, 这将会在后面的mipmap部分讲解。

默认情况下, 放大过滤器的参数为 GL_LINEAR, 缩小过滤器为 GL_NEAREST_MIPMAP_LINEAR.

在渲染纹理时, OpenGL 会先检查当前的纹理是否加载完成,同时也会处理其他事情,如在选用缩小过滤器的mipmap处理时会验证mipmap的所有级别是否被定义。 如果纹理未完成, 纹理会被禁用。因为缩小过滤器的缺省值使用mipmap,所以你必须指定所有的mipmap级别或是将缩小过滤器的参数设为 *GL\_LINEAR* 或*GL\_NEAREST*.
 

6 简单例程

    在初始化函数 init() 中创建了纹理对象, 设定了过滤模式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
bool CGfxOpenGL::init ()
{
     glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
 
     // 启用 2D 纹理
     glEnable (GL_TEXTURE_2D);
 
     m_textureOne = new CTargaImage;
 
     // 加载纹理图像
     if (!m_textureOne->Load ( "rock.tga" ))
         return false ;
 
     // 创建纹理对象,
     glGenTextures (1, &m_textureObjectOne);
 
     // 绑定纹理对象
     glBindTexture (GL_TEXTURE_2D, m_textureObjectOne);
 
     // 设定缩放器的过滤参数
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
     // 为纹理对象指定纹理图像数据
     glTExImage2D (GL_TEXTURE_2D, 0, GL_RGB, m_textureOne->GetWidth(),
                   m_textureOne->GetHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE,
                   m_textureOne->GetImage());
 
     // 创建第二个纹理对象
     glGenTexture (1, &m_textureObjectTown);
     glBindTexture (GL_TEXTURE_2D, m_textureObjectTwo);
 
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, m_textureOne->GetWidth(),
                   m_textureOne->GetHeight(), 0, GL_TGB, GL_UNSIGNED_BYTE,
                   m_textureOne->GetImage());
 
     // 初始化运动变量
     m_zPos = -0.5f;
     m_zMoveNegative = true ;
 
     return true ;
}

    在 init() 函数中, 我们先启用 2D 纹理( glEnable() ), 然后加载图像到 CTargaImage 类中(详见第6章), 然后通过 glGenTextures() 获得一个未被使用的纹理对象, 继而绑定, 指定缩放器的过滤模式, 最后为纹理指定图像数据(通过 glTexImage2D() ). 然后同样的流程创建了第二个纹理对象, 使用了同样的纹理图像数据。只是缩放器的过滤参数做了下更改。

    主要的渲染函数有两个 DrawPlane(), Render() :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void CGfxOpenGL::DrawPlane ()
{
     glBegin (GL_TRIANGLE_STRIP);
         glTexCoord2f (1.0, 0.0); glVertex3f (2.0, -2.0, -2.0);
         glTexCoord2f (0.0, 0.0); glVertex3f (-2.0, -2.0, -2.0);
         glTexCoord2f (1.0, 1.0); glVertex3f (2.0, -2.0, 2.0);
         glTexCoord2f (0.0, 1.0); glVertex3f (-2.0, -2.0, 2.0);
     glEnd();
}
 
void CGfxOpenGL::Render ()
{
     // 清除屏幕和深度缓存
     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
     // 重置当前矩阵
     glLoadIdentity ();
 
     // 绘制左边的多边形
     glPushMatrix ();
             //
             glTranslatef (-3.0, 0.0, m_zPos);
             glRotatef (90.0, 1.0, 0.0, 0.0);
         
             // 绑定纹理
             glBindTexture (GL_TEXTURE_2D, m_textureObjectOne);
         
             // 绘制 Plane
             DrawPlane ();
     glPopMatrix();
 
     // 同样地, 绘制右边多边形
     glPushMatrix ();
             glTranslatef (3.0, 0.0, m_zPos);
             glRotatef (90.0, 1.0, 0.0, 0.0);
             glBindTexture (GL_TEXTURE_2D, m_textureObjectTwo);
             DrawPlane ();
     glPopMatrix();
 
}

    在 DrawPlane() 中, 我们指定了纹理坐标然后绘制多边形的顶点。在 Render() 中,我们先绑定好纹理对象, 然后绘制多边形。

 

纹理映射(Texture Mapping) 具体而言,为物体表面的各个点设定纹理坐标(通常以二维的UV坐标来表示,U坐标对应纹理图像的水平方向,取值范围一般是0到1,类比图像的横坐标;在图形渲染过程中,根据物体表面各点的纹理坐标去查找纹理图像中对应位置的像素颜色值,随后把获取到的这些颜色值应用到物体表面对应的点上,就好像给物体“穿上”了带有特定图案和颜色的“外衣”一样。例如,要让一个简单的长方体模型呈现出木质纹理,就可以把一张木质纹理的图片通过合理的纹理映射,依据长方体表面各点的纹理坐标与纹理图像建立联系,使得长方体看起来像是用木头制作而成的。 阅读详情

相关推荐

OpenGL:OpenGL纹理映射技术_2024-07-20_10-20-21.Tex

环境映射、立方体贴图和纹理阵列是OpenGL中用于创建高级纹理效果的技术。通过使用这些技术,可以创建出非常逼真的反射效果和动态的纹理效果。在实际应用中,这些技术可以被用来增强游戏、虚拟现实和3D可视化等场景的真实感。

917

OpenGL第十一讲——纹理映射

openGL纹理

weixin_47524903的博客 9259

别再死磕公式了!用Python+NumPy手把手实现机器人逆运动学数值求解(附避坑指南)

本文详细介绍了如何使用Python和NumPy实现机器人逆运动学(Inverse Kinematics, IK)的数值求解方法,包括牛顿-拉弗森法、雅可比矩阵计算及奇异位形处理。通过实战代码和避坑指南,帮助开发者快速掌握现代机器人学中的核心算法,提升工程实践能力。

weixin_30687051的博客 126

计算机图形学笔记(四)纹理映射

计算机图形学笔记(四)纹理映射

qq_15017307的博客 3027

SAP HR模块配置假期日历和缺勤类型

SAP的HR模块。业务顾问在实施时一般会配置未来10年的假期日历,到期后再进行配置。同时,增加请假类型(缺勤信息类型)。记录这一过程。

福来阁86号技师的妖孽日常 5523

关于自制的《航空学报》latex模板(非官网模板)

《航空学报》的官网只提供了word模板,并且该期刊投稿只需要pdf版本不需要源文件。为方便latex爱好者撰写论文,提供该模板及说明给广大科研人士~

qq_37105055的博客 4689

OpenGl 第七章:纹理映射 (texture mapping)

本章你将学到 纹理映射基础知识纹理坐标纹理对象及绑定纹理过滤mipmap和自动生成mipmap纹理参数, 外包模式, 细节级别纹理环境和纹理函数 Table of Contents 1 概述2 预备知识: 纹理坐标3 使用纹理映射 3.1 纹理对象3.2 纹理绑定3.3 删除纹理对象3.4 驻留纹理3.5 纹理优先级 4 指定纹理 4.1 2D 纹理4.2

cjneo的专栏 4290

【Rcode】生存分析: KM & COX回归& 随机森林& nomogram

本文使用了R——survival包下的lung数据进行方法测试: 1)KM 2) Cox回归:多因素 3)随机森林因子(根据cox回归结果) 4)nomogram ( 根据cox回归结果,建立了中位生存时间,1年5年生存率的概率计算) -------------------????????‍♀️本文只有干货,非常干!????----------------------------- 一、数据加载 #生存分析 library("survival") library("survminer") data("

weixin_43172152的博客 9273

OpenGL 纹理映射

纹理映射 (texture mapping) 本章你将学到 纹理映射基础知识纹理坐标纹理对象及绑定纹理过滤mipmap和自动生成mipmap纹理参数, 外包模式, 细节级别纹理环境和纹理函数 Table of Contents 1 概述2 预备知识: 纹理坐标3 使用纹理映射 3.1 纹理对象3.2 纹理绑定3.3 删除纹理对象3.4 驻留纹理3.

梧桐下的四叶草 756

addr2line解析不出来行号的解决方式(汇编解析高阶版)

摘要:本文针对AEC crash问题中addr2line无法解析行号的情况,通过llvm-addr2line和反汇编分析,定位到CamX::AECBEStats17::AdjustROIParams函数中的乘法溢出问题。关键发现包括: 常规addr2line只能解析到函数名但无具体行号 llvm-addr2line解析出多个可能溢出点(行196/204/211/218/270/271) 反汇编显示6个条件分支跳转到溢出处理函数 源码分析确认这些位置均存在乘法运算 最终通过汇编级调试工具成功定位UBsan报告

168

vue3+vite:引入tailwindcss不生效的原因,详细解决Tailwind配置没问题但就是不生效的情况,配置正确无报错但样式没有生效(包括tailwindcss在Vue2使用不生效解决方案)

vue3 tailwind使用教程以及tailwind不生效的问题,vue3+vite引入tailwindcss不生效的原因,tailwindcss配之后不生效怎么办,如何解决tailwinscss不生效的原因,Vue3项目使用tailwindcss在Vue2使用,不生效解决,如何解决使用 Tailwind CSS 后出现的样式不生效的问题?tailwindcss配之后不生效 tailwindcss不生效,为什么我的 Tailwind css 类没生效,解决使用 Tailwind 时样式不生效的问题,配置没

✅ 精选推荐文章 4127

OpenGl 编程指南笔记 第九章:纹理映射 (texture mapping)

<br />本章你将学到纹理映射基础知识 纹理坐标 纹理对象及绑定 纹理过滤 mipmap和自动生成mipmap 纹理参数, 外包模式, 细节级别 纹理环境和纹理函数 Table of Contents1 概述2 预备知识: 纹理坐标3 使用纹理映射3.1 纹理对象3.2 纹理绑定3.3 删除纹理对象3.4 驻留纹理3.5 纹理优先级4 指定纹理4.1 2D 纹理4.2 1D 纹理4.3 3D 纹理4.4 Cube Map 纹理5 纹理过滤6 简单例程1 概述<br />概括的说, 纹理映射机制允许你将一个

hitxiaya的专栏 4918

Ubuntu零基础入门到精通【1.2讲】:Ubuntu 与 Linux 的关系 —— 你用的到底是什么?

🏆 本文收录于 《滚雪球学 Ubuntu》 专栏。 本专栏面向有一定计算机基础,但尚未系统学习 Linux / Ubuntu 的读者,采用“滚雪球式学习法”:先装好、再会用、再理解、再优化、再实战,带你从第一次进入 Ubuntu 桌面 / 终端开始,逐步掌握 Ubuntu 的日常使用、命令操作、软件安装、系统配置、开发环境搭建与服务器部署能力。

**My Coding Family** 3102

纹理映射 (texture mapping)

转载地址 点击打开链接 http://caobeixingqiu.is-programmer.com/posts/18999.html

ruihaha的专栏 1272

多体动力学分析软件:SIMPACK_(17).SIMPACK高级编程与脚本

自定义力和约束可以用于模拟更复杂和现实的物理场景。SIMPACK 提供了接口,允许用户通过 Python 脚本来实现自定义力和约束。以下是一个示例,展示如何定义一个自定义力函数并应用于模型。# 定义自定义力函数"""自定义力函数:param t: 时间:param position: 位置:param velocity: 速度:return: 力"""# 创建一个新的 SIMPACK 模型# 添加一个刚体# 添加一个关节# 添加一个自定义力# 设置仿真参数# 运行仿真。

kkchenjj的博客 1419

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

opengl地球贴纹理_一文看懂材质/纹理 Material, Texture, Shading, Shader 的区别

在计算机图形学和三维设计中,有几个容易混淆的概念。今天我们来一举拿下。概念整理可以这么总结:Material 是表现 Shading 的数据集。其他几个概念都是生成这一数据集的资源或者工具。这么多概念,无非是为了完成一个共同目标:用计算机表现真实可信的 Shading。Shading 是真实世界中的光影效果,它是由物体表面材质、灯光、观察者的视角等多种因素共同决定的。要实现计算机的模拟生成,是一个...

weixin_39702714的博客 963

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

第七章:纹理映射 (texture mapping) (一)

本章你将学到 纹理映射基础知识 纹理坐标 纹理对象及绑定 纹理过滤 mipmap和自动生成mipmap 纹理参数, 外包模式, 细节级别 纹理环境和纹理函数 Table of Contents 1 概述 2 预备知识: 纹理坐标 3 使用纹理映射 3.1 纹理对象 3.2 纹理绑定 3.3 删除纹理对象 3.4 驻留纹理 3.5 纹理优先级 ...

ld326的专栏 525

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C++实现球体纹理映射:从UV坐标到OpenGL渲染的完整指南

纹理映射是计算机图形学中一项基础而关键的技术,它通过建立三维模型表面点与二维图像像素之间的对应关系,为模型赋予丰富的表面细节。其核心原理在于坐标变换,即利用UV坐标系将纹理图像“包裹”到三维几何体上。这项技术的工程价值在于,它实现了视觉细节与几何复杂度的解耦,无需增加模型面数即可显著提升渲染真实感。在游戏开发、数据可视化、仿真模拟等应用场景中,纹理映射是构建沉浸式三维体验的基石。本文聚焦于参数化曲面中最经典的案例——球体,深入探讨如何通过经纬度映射将二维图案贴合到球面,并剖析OpenGL实现中UV坐标计算、

weixin_30652491的博客 337

视差映射Parallax Mapping教程:如何用深度偏移让贴图呈现真实凹凸感

**视差映射(Parallax Mapping)** 是 OpenGL 进阶渲染中让二维贴图呈现"伪三维"凹凸效果的核心技术。本文基于开源项目 noteForOpenGL(OpenGL 学习脚印配套代码)中的视差映射示例,讲解**基于深度偏移的贴图原理**:只需读取高度图的一个像素值,就能把采样坐标沿视线方向"推远"或"拉近",从而让砖墙、地板等平面在视觉上拥有真实的立体厚度,全程无需增加任何几何

gitblog_00463的博客 463

UV Texture Coordinates and Texture Mapping - OpenGL / DirectX

UV Texture Coordinates and Texture Mapping - OpenGL / DirectX Posted byCory Grossat9:49 AM Because I am not in school right now, I have been getting pretty heavy into WebGL graphics trying t

wanglang3081的专栏 2485

LIBGDX版NEHE OPENGL- 6. Texture Mapping

大概看过nehe的texture mapping代码之后,发现都是将一个纹理图片,按坐标映射的方式,来对应到点。 所以下面这段代码,对于了解这种映射方式的朋友来说,应该很好理解。 package com.kyugao.screen; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Screen; import com.badlog

q26335804的专栏 1277

OpenGL学习笔记34-Shadow Mapping

Shadow Mapping Advanced-Lighting/Shadows/Shadow-Mapping 阴影是由于遮挡而缺乏光的结果。当一个光源的光线因为被其他物体遮挡而没有击中物体时,该物体处于阴影中。阴影为被照亮的场景添加了大量的真实感,使观者更容易观察物体之间的空间关系。它们给我们的场景和物体更大的深度感。举个例子,看看下面有阴影和没有阴影的场景: 你可以看到,有了阴影,物体之间的关系变得更加明显。例如,只有当我们有阴影的时候,其中一个立方体浮在其他立方体的上方才会很明显。 阴影的

wangxingxing321的博客 717

Learn OpenGL 23 阴影映射

阴影是光线被阻挡的结果;当一个光源的光线由于其他物体的阻挡不能够达到一个物体的表面的时候,那么这个物体就在阴影中了。阴影能够使场景看起来真实得多,并且可以让观察者获得物体之间的空间位置关系。场景和物体的深度感因此能够得到极大提升,下图展示了有阴影和没有阴影的情况下的不同:你可以看到,有阴影的时候你能更容易地区分出物体之间的位置关系,例如,当使用阴影的时候浮在地板上的立方体的事实更加清晰。阴影还是比较不好实现的,因为当前实时渲染领域还没找到一种完美的阴影算法。

Mr_Dongzheng的博客 905

Unity Shader:Projective Texture Mapping

Projective-Texture-Mapping是用于投影一个texture到一个物体上。 大概过程是,通过设置一个摄像机在投影点上,获取投影摄像机的 VP 矩阵。在shader中利用该VP矩阵,来计算相对于投影机的uv坐标,从而利用该uv值来采样投影texture。 具体描述见:GPU 编程与CG 语言之阳春白雪下里巴人 中的12.3节。 Shader "Custom/Projec...

weixin_30760895的博客 293

OpenGL基础52:阴影映射(上)

参考于:https://learnopengl.com/#!Advanced-Lighting/Shadows/Shadow-Mapping 一、游戏中的阴影 阴影是光线被阻挡的结果,当一个光源的光线由于其他物体的阻挡不能够达到一个物体的表面的时候,那么这个物体就在阴影中了。理论上阴影无处不在,但是想要渲染出很好的阴影效果,并不是一件特别容易的事,目前实时渲染领域还没找到一种完美的阴影算法,尽管有不少近似阴影技术,但它们都有自己的弱点和不足 minecraft游戏截图 目前较多使用的一种技术...

加载中... 2377
上一篇: opengl 遇到的基础问题
下一篇: Stencil Buffer(模板缓冲区)
Savitch
博客等级 码龄16年 84粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值