optimizeinplace

2023-11-17

上篇介绍了.X文件网格的渲染方法,如果需要创建自己的网格文件,并将它渲染出来,那么可以考虑创建一个空的网格,然后读取网格文件内容,将顶点,材质和纹理数据写入以上的网格相关缓冲区中。

创建一个自定义顶点格式的空Mesh网格可由 D3DXCreateMeshFVF来实现,来看看它的具体信息说明:

Creates a mesh object using a flexible vertex format (FVF) code.

 HRESULT D3DXCreateMeshFVF( 
   DWORD   NumFaces  , 
   DWORD   NumVertices  , 
   DWORD   Options  , 
   DWORD   FVF  , 
   LPDIRECT3DDEVICE9   pD3DDevice  , 
   LPD3DXMESH *   ppMesh 
 ); 
Parameters
NumFaces
[in] Number of faces for the mesh. The valid range for this number is greater than 0, and one less than the max DWORD value, typically 232 - 1, because the last index is reserved.
NumVertices
[in] Number of vertices for the mesh. This parameter must be greater than 0.
Options
[in] Combination of one or more flags from the D3DXMESH enumeration, specifying creation options for the mesh.
FVF
[in] Combination of D3DFVF that describes the vertex format for the returned mesh. This function does not support D3DFVF_XYZRHW.
pD3DDevice
[in] Pointer to an IDirect3DDevice9 interface, the device object to be associated with the mesh.
ppMesh
[out] Address of a pointer to an ID3DXMesh interface, representing the created mesh object.
Return Values

If the function succeeds, the return value is D3D_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.


空网格创建出来后,用ID3DXMesh接口的LockVertexBuffer函数取得顶点缓冲区的指针,这样就可以将文件的顶点数据写入已锁定的缓冲区内,最后还要调用UnlockVertexBuffer来进行解锁。

来看看 LockVertexBuffer函数的具体信息说明:

Locks a vertex buffer and obtains a pointer to the vertex buffer memory.

 HRESULT LockVertexBuffer( 
   DWORD   Flags  , 
   LPVOID *   ppData 
 ); 
Parameters
Flags

Combination of zero or more locking flags that describe the type of lock to perform. For this method, the valid flags are:

  • D3DLOCK_DISCARD
  • D3DLOCK_NO_DIRTY_UPDATE
  • D3DLOCK_NOSYSLOCK
  • D3DLOCK_READONLY
  • D3DLOCK_NOOVERWRITE
[in] For a description of the flags, see D3DLOCK.

 

ppData
[out, retval] VOID* pointer to a buffer containing the vertex data.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

When working with vertex buffers, you are allowed to make multiple lock calls; however, you must ensure that the number of lock calls match the number of unlock calls. DrawPrimitive calls will not succeed with any outstanding lock count on any currently set vertex buffer.


来看看参数Flags可以使用的D3DLOCK的具体定义:

A combination of zero or more locking options that describe the type of lock to perform.

#define Description
D3DLOCK_DISCARD The application discards all memory within the locked region. For vertex and index buffers, the entire buffer will be discarded. This option is only valid when the resource is created with dynamic usage (see D3DUSAGE).
D3DLOCK_DONOTWAIT Allows an application to gain back CPU cycles if the driver cannot lock the surface immediately. If this flag is set and the driver cannot lock the surface immediately, the lock call will return D3DERR_WASSTILLDRAWING. This flag can only be used when locking a surface created using IDirect3DDevice9::CreateOffscreenPlainSurface, IDirect3DDevice9::CreateRenderTarget, or IDirect3DDevice9::CreateDepthStencilSurface. This flag can also be used with a back buffer.
D3DLOCK_NO_DIRTY_UPDATE By default, a lock on a resource adds a dirty region to that resource. This option prevents any changes to the dirty state of the resource. Applications should use this option when they have additional information about the set of regions changed during the lock operation.
D3DLOCK_NOOVERWRITE Indicates that memory that was referred to in a drawing call since the last lock without this flag will not be modified during the lock. This can enable optimizations when the application is appending data to a resource. Specifying this flag enables the driver to return immediately if the resource is in use, otherwise, the driver must finish using the resource before returning from locking.
D3DLOCK_NOSYSLOCK The default behavior of a video memory lock is to reserve a system-wide critical section, guaranteeing that no display mode changes will occur for the duration of the lock. This option causes the system-wide critical section not to be held for the duration of the lock.

The lock operation is time consuming, but can enable the system to perform other duties, such as moving the mouse cursor. This option is useful for long-duration locks, such as the lock of the back buffer for software rendering that would otherwise adversely affect system responsiveness.

D3DLOCK_READONLY The application will not write to the buffer. This enables resources stored in non-native formats to save the recompression step when unlocking.


再来看看UnlockVertexBuffer函数的具体信息说明:

Unlocks a vertex buffer.

 HRESULT UnlockVertexBuffer(); 
Parameters

None.

Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.


同样,利用ID3DXMesh接口的LockIndexBuffer和UnlockIndexBuffer函数,可锁定顶点索引缓冲区,并写入三角形面的顶点索引值,然后解锁。

LockIndexBuffer的具体使用信息如下所示:

Locks an index buffer and obtains a pointer to the index buffer memory.

 HRESULT LockIndexBuffer( 
   DWORD   Flags  , 
   LPVOID *   ppData 
 ); 
Parameters
Flags

Combination of zero or more locking flags that describe the type of lock to perform. For this method, the valid flags are:

  • D3DLOCK_DISCARD
  • D3DLOCK_NO_DIRTY_UPDATE
  • D3DLOCK_NOSYSLOCK
  • D3DLOCK_READONLY
[in] For a description of the flags, see D3DLOCK.

 

ppData
[out, retval] VOID* pointer to a buffer containing the index data. The count of indices in this buffer will be equal to ID3DXBaseMesh::GetNumFaces * 3.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

When working with index buffers, you are allowed to make multiple lock calls. However, you must ensure that the number of lock calls match the number of unlock calls. DrawPrimitive calls will not succeed with any outstanding lock count on any currently set index buffer.


该函数使用信息说明中提到的GetNumFaces用来获取该网格包含的三角形面数,信息说明如下所示:

Retrieves the number of faces in the mesh.

 DWORD GetNumFaces(); 
Parameters

None.

Return Values

Returns the number of faces in the mesh.


再来看看
UnlockIndexBuffer的使用说明:

Unlocks an index buffer.

 HRESULT UnlockIndexBuffer(); 
Parameters

None.

Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.


接着我们可以利用ID3DXMesh接口的LockAttributeBuffer函数锁定属性缓冲区,并取得缓冲区的指针,然后将每个三角形面的子集号写入,最后调用该接口的UnlockAttributeBuffer函数将缓冲区解锁。

来看看LockAttributeBuffer的使用说明:

Locks the mesh buffer that contains the mesh attribute data, and returns a pointer to it.

 HRESULT LockAttributeBuffer( 
   DWORD   Flags  , 
   DWORD **   ppData 
 ); 
Parameters
Flags

Combination of zero or more locking flags that describe the type of lock to perform. For this method, the valid flags are:

  • D3DLOCK_DISCARD
  • D3DLOCK_NO_DIRTY_UPDATE
  • D3DLOCK_NOSYSLOCK
  • D3DLOCK_READONLY
[in] For a description of the flags, see D3DLOCK.

 

ppData
[out] Address of a pointer to a buffer containing a DWORD for each face in the mesh.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

If ID3DXMesh::Optimize has been called, the mesh will also have an attribute table that can be accessed using the ID3DXBaseMesh::GetAttributeTable method.


再来看看UnlockAttributeBuffer的使用说明:

Unlocks an attribute buffer.

 HRESULT UnlockAttributeBuffer(); 
Parameters

None.

Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.


如果网格没有提供各顶点的法向量坐标数据,可使用ID3DXMesh接口的CloneMeshFVF函数复制生成一个包含法向量的网格,然后调用D3DXComputeNormals计算各顶点的法向量。

来看看CloneMeshFVF的使用说明:

Clones a mesh using a flexible vertex format (FVF) code.

 HRESULT CloneMeshFVF( 
   DWORD   Options  , 
   DWORD   FVF  , 
   LPDIRECT3DDEVICE9   pDevice  , 
   LPD3DXMESH *   ppCloneMesh 
 ); 
Parameters
Options
[in] A combination of one or more D3DXMESH flags specifying creation options for the mesh.
FVF
[in] Combination of FVF codes, which specifies the vertex format for the vertices in the output mesh. For the values of the codes, see D3DFVF.
pDevice
[in] Pointer to an IDirect3DDevice9 interface representing the device object associated with the mesh.
ppCloneMesh
[out, retval] Address of a pointer to an ID3DXMesh interface, representing the cloned mesh.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

Remarks

ID3DXBaseMesh::CloneMeshFVF is used to reformat and change the vertex data layout. This is done by creating a new mesh object. For example, use it to to add space for normals, texture coordinates, colors, weights, etc. that were not present before.

ID3DXBaseMesh::UpdateSemantics updates the vertex declaration with different semantic information without changing the layout of the vertex buffer. This method does not modify the contents of the vertex buffer. For example, use it to relabel a 3D texture coordinate as a binormal or tangent or vice versa.


以及D3DXComputeNormals的使用说明:

Computes unit normals for each vertex in a mesh. Provided to support legacy applications. Use D3DXComputeTangentFrameEx for better results.

 HRESULT D3DXComputeNormals( 
   LPD3DXBASEMESH   pMesh  , 
   CONST DWORD *   pAdjacency 
 ); 
Parameters
pMesh
[in, out] Pointer to an ID3DXBaseMesh interface, representing the normalized mesh object. This function may not take an ID3DXPMesh progressive mesh as input.
pAdjacency
[in] Pointer to an array of three DWORDs per face that specify the three neighbors for each face in the created progressive mesh. This parameter is optional and should be set to NULL if it is unused.
Return Values

If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

Remarks

The input mesh must have the D3DFVF_NORMAL flag specified in its flexible vertex format (FVF).

A normal for a vertex is generated by averaging the normals of all faces that share that vertex.

If adjacency is provided, replicated vertices are ignored and "smoothed" over. If adjacency is not provided, replicated vertices will have normals averaged in from only the faces explicitly referencing them.

This function simply calls D3DXComputeTangentFrameEx with the following input parameters:

D3DXComputeTangentFrameEx( pMesh,
                           D3DX_DEFAULT,
                           0,
                           D3DX_DEFAULT,
                           0,
                           D3DX_DEFAULT,
                           0,
                           D3DDECLUSAGE_NORMAL,
                           0,
                           D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS,
                           pAdjacency,
                           -1.01f,
                           -0.01f,
                           -1.01f,
                           NULL,
                           NULL);

下面的代码通过复制的方法生成了一个具有顶点法向量信息的网格:

LPD3DXMESH mesh;
LPD3DXMESH mesh_clone = NULL;

mesh->CloneMeshFVF(mesh->GetOptions(), mesh->GetFVF() | D3DFVF_NORMAL, _d3d_device, &mesh_clone);

D3DXComputeNormals(mesh_clone, NULL);


Mesh数据的优化

.X文件的网格数据装入缓冲区后,每个网格子集的数据可以进行优化,以提高子集渲染速度。对于顶点缓冲区来说,可以把位于同一个子集的顶点进行连续排放,减少三角形面的索引,也可以对邻接的顶点进行压缩,节省内存消耗和提高顶点的命中率。对于顶点索引缓冲区来说,该缓冲区提供了网格的所有三角形面的构成信息,如果把位于同一个子集的三角形面集中连续排放,就可以使属性缓冲区的子集编号按序排列。

ID3DXMesh接口提供了OptimizeInplace 函数进行网格数据各种类型的优化,它的使用说明如下所示:

Generates a mesh with reordered faces and vertices to optimize drawing performance. This method reorders the existing mesh.

 HRESULT OptimizeInplace( 
   DWORD   Flags  , 
   CONST DWORD *   pAdjacencyIn  , 
   DWORD *   pAdjacencyOut  , 
   DWORD *   pFaceRemap  , 
   LPD3DXBUFFER *   ppVertexRemap 
 ); 
Parameters
Flags
[in] Combination of one or more D3DXMESHOPT flags, specifying the type of optimization to perform.
pAdjacencyIn
[in] Pointer to an array of three DWORDs per face that specifies the three neighbors for each face in the source mesh. If the edge has no adjacent faces, the value is 0xffffffff.
pAdjacencyOut
[out] Pointer to an array of three DWORDs per face that specifies the three neighbors for each face in the optimized mesh. If the edge has no adjacent faces, the value is 0xffffffff. If the value supplied for this argument is NULL, adjacency data is not returned.
pFaceRemap
[out] An array of DWORDs, one per face, that identifies the original mesh face that corresponds to each face in the optimized mesh. If the value supplied for this argument is NULL, face remap data is not returned.
ppVertexRemap
[out] Address of a pointer to an ID3DXBuffer interface, which contains a DWORD for each vertex that specifies how the new vertices map to the old vertices. This remap is useful if you need to alter external data based on the new vertex mapping. If the value supplied for this argument is NULL, vertex remap data is not returned.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_CANNOTATTRSORT, E_OUTOFMEMORY.

Remarks

Before running ID3DXMesh::OptimizeInplace, an application must generate an adjacency buffer by calling ID3DXBaseMesh::GenerateAdjacency. The adjacency buffer contains adjacency data, such as a list of edges and the faces that are adjacent to each other.

Note     This method will fail if the mesh is sharing its vertex buffer with another mesh, unless the D3DXMESHOPT_IGNOREVERTS is set in Flags.


下面来看看参数Flags可以使用的网格优化类型D3DXMESHOPT的具体定义:

Specifies the type of mesh optimization to be performed.

typedef enum D3DXMESHOPT
{
    D3DXMESHOPT_COMPACT = 0x01000000,
    D3DXMESHOPT_ATTRSORT = 0x02000000,
    D3DXMESHOPT_VERTEXCACHE = 0x04000000,
    D3DXMESHOPT_STRIPREORDER = 0x08000000,
    D3DXMESHOPT_IGNOREVERTS = 0x10000000,
    D3DXMESHOPT_DONOTSPLIT = 0x20000000,
    D3DXMESHOPT_DEVICEINDEPENDENT = 0x40000000,
} D3DXMESHOPT, *LPD3DXMESHOPT;
Constants
D3DXMESHOPT_COMPACT
Reorders faces to remove unused vertices and faces.
D3DXMESHOPT_ATTRSORT
Reorders faces to optimize for fewer attribute bundle state changes and enhanced ID3DXBaseMesh::DrawSubset performance.
D3DXMESHOPT_VERTEXCACHE
Reorders faces to increase the cache hit rate of vertex caches.
D3DXMESHOPT_STRIPREORDER
Reorders faces to maximize length of adjacent triangles.
D3DXMESHOPT_IGNOREVERTS
Optimize the faces only; do not optimize the vertices.
D3DXMESHOPT_DONOTSPLIT
While attribute sorting, do not split vertices that are shared between attribute groups.
D3DXMESHOPT_DEVICEINDEPENDENT
Affects the vertex cache size. Using this flag specifies a default vertex cache size that works well on legacy hardware.
Remarks

The D3DXMESHOPT_STRIPREORDER and D3DXMESHOPT_VERTEXCACHE optimization flags are mutually exclusive.

The D3DXMESHOPT_SHAREVB flag has been removed from this enumeration. Use D3DXMESH_VB_SHARE instead, in D3DXMESH.


D3DXLoadMeshFromX函数装入.X文件时,会自动为网格填充一个三角形面的邻接数组缓冲区,也可以利用 ID3DXMesh接口提供的GenerateAdjacency函数来生成,下面是该函数的具体使用说明:

Generate a list of mesh edges, as well as a list of faces that share each edge.

 HRESULT GenerateAdjacency( 
   FLOAT   Epsilon  , 
   DWORD *   pAdjacency 
 ); 
Parameters
Epsilon
[in] Specifies that vertices that differ in position by less than epsilon should be treated as coincident.
pAdjacency
[in] Pointer to an array of three DWORDs per face to be filled with the indices of adjacent faces. The number of bytes in this array must be at least 3 * ID3DXBaseMesh::GetNumFaces * sizeof(DWORD).
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be one of the following: D3DERR_INVALIDCALL, E_OUTOFMEMORY.

Remarks

After an application generates adjacency information for a mesh, the mesh data can be optimized for better drawing performance.

The order of the entries in the adjacency buffer is determined by the order of the vertex indices in the index buffer. The adjacent triangle 0 always corresponds to the edge between the indices of the corners 0 and 1. The adjacent triangle 1 always corresponds to the edge between the indices of the corners 1 and 2 while the adjacent triangle 2 corresponds to the edge between the indices of the corners 2 and 0.


下面的代码段给出了利用OptimizeInplace进行优化的示例:

    // Generates a mesh with reordered faces and vertices to optimize drawing performance. 
    // This method reorders the existing mesh.
    _mesh->OptimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
        (DWORD*) _adjacency_buffer->GetBufferPointer(), NULL, NULL, NULL);

值得一提的是,进行D3DXMESHOPT_ATTRSORT优化操作后,将生成一个Attribute Table,它是一个D3DXATTRIBUTERANGE类型的数组,反映了优化后的子集的三角形面的划分和顶点的划分。 D3DXATTRIBUTERANGE的具体定义如下所示:

Stores an attribute table entry.

typedef struct D3DXATTRIBUTERANGE {
    DWORD AttribId;
    DWORD FaceStart;
    DWORD FaceCount;
    DWORD VertexStart;
    DWORD VertexCount;
} D3DXATTRIBUTERANGE, *LPD3DXATTRIBUTERANGE;
Members
AttribId
Attribute table identifier.
FaceStart
Starting face.
FaceCount
Face count.
VertexStart
Starting vertex.
VertexCount
Vertex count.
Remarks

An attribute table is used to identify areas of the mesh that need to be drawn with different textures, render states, materials, and so on. In addition, the application can use the attribute table to hide portions of a mesh by not drawing a given attribute identifier (AttribId) when drawing the frame.

The LPD3DXATTRIBUTERANGE type is defined as a pointer to the D3DXATTRIBUTERANGE structure.

typedef D3DXATTRIBUTERANGE* LPD3DXATTRIBUTERANGE;
可以调用ID3DXMesh接口的GetAttribute方法来获得指向属性表的指针和属性表的大小,该函数具体说明如下: 

Retrieves either an attribute table for a mesh, or the number of entries stored in an attribute table for a mesh.

 HRESULT GetAttributeTable( 
   D3DXATTRIBUTERANGE *   pAttribTable  , 
   DWORD *   pAttribTableSize 
 ); 
Parameters
pAttribTable
[in, out] Pointer to an array of D3DXATTRIBUTERANGE structures, representing the entries in the mesh's attribute table. Specify NULL to retrieve the value for pAttribTableSize.
pAttribTableSize
[in, out] Pointer to either the number of entries stored in pAttribTable or a value to be filled in with the number of entries stored in the attribute table for the mesh.
Return Values

If the method succeeds, the return value is D3D_OK. If the method fails, the return value can be D3DERR_INVALIDCALL.

Remarks

An attribute table is created by ID3DXMesh::Optimize and passing D3DXMESHOPT_ATTRSORT for the Flags parameter.

An attribute table is used to identify areas of the mesh that need to be drawn with different textures, render states, materials, and so on. In addition, the application can use the attribute table to hide portions of a mesh by not drawing a given attribute identifier when drawing the frame.



好了,现在来看一个例子。

需要在工程中设置链接d3dx9.lib d3d9.lib dinput8.lib dxguid.lib winmm.lib。
由于文件中用到了GE_APP和GE_INPUT这两个类,它的具体使用说明请参阅 主窗口和DirectInput的封装。
文件中同时还用到了GE_TIMER这个类,它的具体使用说明请参阅 游戏中时间的封装

源码与素材下载

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

optimizeinplace 的相关文章

  • 如何快速转载CSDN中的博客

    前言 对于喜欢逛CSDN的人来说 看别人的博客确实能够对自己有不小的提高 有时候看到特别好的博客想转载下载 但是不能一个字一个字的敲了 这时候我们就想快速转载别人的博客 把别人的博客移到自己的空间里面 当然有人会说我们可以收藏博客啊 就不需
  • 【转载】KaTeX 数学公式大全

    文章目录 转载自 前言 受支持的功能 声调记号 定界符 括号之类 定界符大小 5
  • 到底什么是非线性规划?

    本文转自新浪博客 到底什么是非线性优化 作者 那些年的那些偏执 网址 http blog sina com cn s blog 7445c2940102x3x4 html 作者系在读博士生 文章写的非常浅显易懂 本文除转载之外 做简单修改整
  • 使用ipmitool命令检测电源模块状态

    1 通过ipmitool检查电源模块状态 https mp weixin qq com s Z1g79Q1aMhOT9Xm9fvIkjg 2 通过ipmitool获取服务器各元件温度信息 https mp weixin qq com s E
  • C# 中的委托和事件(详解)

    C 中的委托和事件 委托和事件在 NET Framework 中的应用非常广泛 然而 较好地理解委托和事件对很多接触 C 时间不长的人来说并不容易 它们就像是一道槛儿 过了这个槛的人 觉得真是太容易了 而没有过去的人每次见到委托和事件就觉得
  • 渗透测试技术题(面试、笔试)

    本篇文章主要涉及一下几个方面 java view plain copy 对称加密非对称加密 什么是同源策略 cookie存在哪里 可以打开吗 xss如何盗取cookie tcp udp的区别及tcp三次握手 syn攻击 证书要考哪些 DVW
  • 网络面试题及答案

    1 标准网络线的颜色排列顺序 568B 橙白 橙 绿白 蓝 蓝白 绿 棕白 棕 568A 绿白 绿 橙白 蓝 蓝白 橙 棕白 棕 直通线一般都用 A线序或 B线序 交叉线一端是 568A 一端 是 568B 2 按照数据访问速度排序 硬盘
  • ChatGPT实用用法10大场景

    之前的文章中 我们提到了ChatGPT的一些局限性 比如它会一本正经地胡说八道 所以如果使用方法不对 反而会耽误时间甚至被误导 但要是用对了 真的会事半功倍 让我们褪去ChatGPT无所不知无所不能的光环 看看现阶段的它有哪些靠谱的用法吧
  • 使用GCD处理后台线程和UI线程的交互(转自唐巧的技术博客)

    使用GCD FEB 22ND 2012 什么是GCD Grand Central Dispatch GCD 是Apple开发的一个多核编程的解决方法 该方法在Mac OS X 10 6雪豹中首次推出 并随后被引入到了iOS4 0中 GCD是
  • ios-消息中心 NSNotificationCenter 的介绍

    1 通知中心概述 通知中心实际上是在程序内部提供了消息广播的一种机制 通知中心不能在进程间进行通信 实际上就是一个二传手 把接收到的消息 根据内部的一个消息转发表 来将消息转发给需要的对象 通知中心是基于观察者模式的 它允许注册 删除观察者
  • Android 控件 RecyclerView 看这篇就够了

    Android 控件 RecyclerView 概述 RecyclerView是什么 从Android 5 0开始 谷歌公司推出了一个用于大量数据展示的新控件RecylerView 可以用来代替传统的ListView 更加强大和灵活 Rec
  • Advanced Installer汉化版教程(打包程序,安装包制作)

    Advanced Installer汉化版教程 转载 打包程序 安装包制作 下载地址 http www crsky com soft 6776 html 1 新建一个安装工程 2 详细的设置工程文件 A 设置产品信息以及在控制面板里的一些信
  • [转载]QT框架的一个截图工具

    原文标题 Snipaste 开发了三年的截图工具 但不只是截图 原文作者 levie 一直以来都想要入门QT 但是却一直没有付诸行动 昨天在无意间发现了 这个开发者的截图工具 虽然我还没有使用 但是看上去却很能吸引目光 便重新激发了我开始学
  • Android Rxjava:最简单易懂的诠释 看这篇

    1 前言 Rxjava 具有链式调用 使用简单 事件与结果松耦合的特点 Rxjava 之所以深受欢迎它包含 非常多操作符 能通过 链式形 优雅整洁的代码几乎能实现所有的功能需求 本文特点 图多字少 逻辑简单 之前面试中被问了很多Rxjava
  • Python面试题

    Python语言特性 1 Python的函数参数传递 看两个如下例子 分析运行结果 代码一 a 1 def fun a a 2 fun a print a 1 代码二 a def fun a a append 1 fun a print a
  • kaggle冠军代码汇总

    https www cnblogs com rw rongwei p 6509146 html
  • char码值对应列表大全

    char码值对应列表大全 Char 0 为0的字符 Char 1 Char 2 Char 3 Char 4 Char 5 Char 6 Char 7 响铃 Char 8 回格 Char 9 tab 水平制表符 Char 10 换行 Char
  • 【转载】探索推荐引擎内部的秘密

    原网址 https www ibm com developerworks cn web 1103 zhaoct recommstudy1 index html icomments 这是2011年ibm发布的文章 较为通俗易懂 适合想入门推荐
  • 如何判断Linux服务器是否被入侵?

    1 如何判断自己的服务器是否被入侵 背景 随着开源产品的越来越盛行 作为一个Linux运维工程师 能够清晰地鉴别异常机器是否已经被入侵了显得至关重要 个人结合自己的工作经历 整理了几种常见的机器被黑情况仅供参考 以下情况是在CentOS 6
  • 38个MySQL数据库的小技巧

    1 如何快速掌握MySQL 培养兴趣 兴趣是最好的老师 不论学习什么知识 兴趣都可以极大地提高学习效率 当然学习MySQL 5 6也不例外 夯实基础 计算机领域的技术非常强调基础 刚开始学习可能还认识不到这一点 随着技术应用的深 入 只有有

随机推荐

  • androidx.lifecycle.ViewModel

    相关链接 深入了解架构组件之ViewModel
  • 抓包工具Charles(二)-移动端APP抓包(设置手机代理、安装证书)

    安装好Charles之后 还只能捕获电脑的接口请求 想要抓取移动设备的APP还需要设置代理 安装证书 文章目录 一 抓包原理 二 手机设置网络代理 1 查看电脑的IP地址 local IP address 2 设置手机网络代理 1 iOS设
  • 数据结构与算法----详解二叉树的遍历(迭代、递归)

    文章目录 实现二叉树的类 前序遍历 中序遍历 后序遍历 层次遍历 总结 作者简介 大家好我是小鱼干儿 是一个热爱编程 热爱算法的大三学生 蓝桥杯国赛二等奖获得者 个人主页 https blog csdn net qq 52007481 个人
  • 老毛桃u盘装系统linux,老毛桃U盘装系统教程详细步骤

    电脑用久了 就会觉得用起来很慢 还很卡 有时还有蓝屏的现象 为了解决这一问题 通常我们都会选择重装系统 如果你还是用光盘来装系统 那么你就OUT了 今天小编讲讲U盘怎么用 老毛桃 来给电脑重装系统 老毛桃是一个多系统模式的PE操作系统 一般
  • 机器学习必学数学基础系列之概率与统计

    课程目标机器学习必学数学基础系列之大数据矩阵基础适应人群大数据 人工智能开发人员课程简介本课程囊括了机器学习理论中所需要概率部分包括概率公理及推论 条件概率 贝叶斯公式 随机变量及其概率函数 CDF pdf 常用概率分布及其均值 方差 统计
  • 虚拟机网络配置、ssh免密配置、jdk和hadoop安装、Hadoop集群配置、格式化文件系统、关闭和启动集群、UI查看集群状态

    一 虚拟机网络配置 二 SSH免密登录公能配置 二 安装jdk 三 安装Hadoop 四 Hadoop集群配置 五 格式化文件系统 六 关闭和启动Hadoop集群 七 通过UI界面查看Hadoop运行状态 1 虚拟机网络配置 mkdir p
  • Python中一些语句的简洁写法

    Python拾珍 Python 提供了不少并不是完全必需的功能 使用这些功能可以写出更简洁 更可读或者更高效的代码 甚至有时候三者兼得 当然 不使用这些功能 我们依然可以写出好代码 阅读一些开源项目 github上很常见 经常可以看到这种简
  • 博士的年薪一般是多少万?

    作者 Dr YaIRhttps www zhihu com question 546293852 answer 3035449200 中科院北京某所的土博士毕业 拿到了中科院优博 留在中科院做助理研究员 工作2年了 本人不在院士组 不在杰青
  • MD5学习总结

    1 MD5简介 MD5 即消息摘要算法第五版 是一种被广泛使用的密码散列函数 散列算法的基本原理是 进行数据 如一段文字 运算 将原始数据变为另一段固定长度的值 MD5 可以产生出一个 128位 16字节 的散列值 hash value 用
  • kubeadm方式部署k8s最新版本V1.26.2

    Kubernetes核心概念 Master主要负责资源调度 控制副本 和提供统一访问集群的入口 核心节点也是管理节点 Node是Kubernetes集群架构中运行Pod的服务节点 Node是Kubernetes集群操作的单元 用来承载被分配
  • C++将一组数随机分成几个小组

    在生活中难免会遇到需要对一群人进行拆分小组 对于大的课题组的研究生还会分组开组会汇报确定名单这个事情 针对这些问题写出了下面的代码 include
  • python学习笔记之多线程练习ThreadPoolExecutor,map,submit

    主要练习了ThreadPoolExecutor map和submit的区别 推荐使用submit更灵活 import os import random import threading import requests as rq impor
  • Elementui - 下拉框(el-dropdown-menu组件)的使用方法

    Elementui 下拉框 el dropdown menu组件 的使用方法 官方文档 简单样式 此为指令事件 具体效果请看文档
  • 2023浙江省赛“信息安全管理与评估“--Reverse部分全部解析(高职组)

    2022全国职业技能大赛 信息安全管理与评估 高职组 任务书 2022全国职业技能大赛 信息安全管理与评估 任务书 第一阶段竞赛项目试题 第二阶段竞赛项目试题 第三阶段竞赛项目试题 任务3 Reverse 80分 2022全国职业技能大赛
  • GLES3.0中文API-glGetProgramInterface

    名称 glGetProgramInterface 查询程序中接口的属性 C 规范 void glGetProgramInterfaceiv GLuint program GLenum programInterface GLenum pnam
  • Hibernate复合主键的注解

    最近做项目用到了Hibernate框架 采用了纯面向对象的思想 使用ORM映射实体 在开发中 实体中出现了复合主键 不再是单一的属性作主键 由于采用了注解的方式 就不再使用xml文件进行配置了 而是直接在实体中进行注释 Hibernate注
  • Unity动画知识之二:Animator动画状态机

    文 拉撒路 上次我们讲过 Unity游戏动画从入门到住院 今天我们来讲一下动画状态机 好了 现在我们已经成功的导入了动画 接下来要玩的东西就很装13啦 因为大部分动画师是用不到这家伙的 需要掌握这个技能的 至少也是动画组长级别了 嗯 一个组
  • 找不到工作?对不起,这份测试面试题来晚了!

    1 测试测试与 测试的区别 首先alpha测试和beta都属于验收测试 这两种测试都需要用户参加 且都不能由程序员和测试员执行 广义上来讲 测试是 内测 测试是 公测 alpha测试是用户在开发环境或者是公司内部模拟实际操作环境的测试 测试
  • C#学习笔记 线程操作

    完整代码在这里 https github com techstay csharp learning note 创建并使用线程 使用线程执行任务 要创建一个线程很简单 实例化一个System Threading Thread对象并向其构造函数
  • optimizeinplace

    上篇介绍了 X文件网格的渲染方法 如果需要创建自己的网格文件 并将它渲染出来 那么可以考虑创建一个空的网格 然后读取网格文件内容 将顶点 材质和纹理数据写入以上的网格相关缓冲区中 创建一个自定义顶点格式的空Mesh网格可由 D3DXCrea