热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenGL基础变化

顶点变换管线 image.png GLMatrixStack 矩阵堆栈 //类型 GLMatrixStack::GLMatrixStack(int iStackDepth
  • 顶点变换管线

    OpenGL 基础变化
    image.png
  • GLMatrixStack 矩阵堆栈

//类型
GLMatrixStack::GLMatrixStack(int iStackDepth = 64); 
//在堆栈顶部载⼊⼀个单元矩阵
void GLMatrixStack::LoadIdentity(void); 
//在堆栈顶部载⼊任何矩阵
//参数:4*4矩阵
void GLMatrixStack::LoadMatrix(const M3DMatrix44f m); 
//矩阵乘以矩阵堆栈顶部矩阵,相乘结果存储到堆栈的顶部
void GLMatrixStack::MultMatrix(const M3DMatrix44f); 
//获取矩阵堆栈顶部的值 GetMatrix 函数
//为了适应GLShaderMananger的使⽤,或者获取顶部矩阵的副本
const M3DMatrix44f & GLMatrixStack::GetMatrix(void); 
void GLMatrixStack::GetMatrix(M3DMatrix44f mMatrix);
//将当前矩阵压⼊堆栈
void GLMatrixStack::PushMatrix(void);
//将M3DMatrix44f 矩阵对象压⼊当前矩阵堆栈
void PushMatrix(const M3DMatrix44f mMatrix);
//将GLFame 对象压⼊矩阵对象
void PushMatrix(GLFame &frame); 
//出栈(出栈指的是移除顶部的矩阵对象)
void GLMatrixStack::PopMatrix(void);
// 仿射变换,旋转平移缩放
//Rotate 函数angle参数是传递的度数
void MatrixStack::Rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
void MatrixStack::Translate(GLfloat x,GLfloat y,GLfloat z);
void MatrixStack::Scale(GLfloat x,GLfloat y,GLfloat z);
GLFrame -参考帧
  • 其中存储了1个世界坐标点和2个世界坐标下的方向向量,也就是9个glFloat值,分别用来表示:当前位置点,向前方向向量,向上方向向量
  • GLFrame可以表示世界坐标系中任意物体的位置与方向。无论是相机还是模型,都可以使用GLFrame来表示。对任意一个使用GLFrame来表示的物体而言,涉及到的坐标系有两个:永远不变的世界坐标系,针对于自身的物体坐标系(即绘图坐标系)
  • 一般来说,针对于物体自身的物体坐标系有如下特点:X轴永远平行于视口的水平方向,+X的方向根据右手定则由+Y与+Z得出;Y轴永远平行于视口的竖直方向,竖直向上为+Y;Z轴永远平行于视口的垂直纸面向里方向,正前方为+Z。也就是说,在世界坐标系中,物体坐标系的Y轴看上去就是GLFrame的向上方向向量,Z轴看上去就是GLFrame的向前方向向量,而X轴由Y轴方向向量与Z轴方向向量根据右手定则可得出
class GLFrame  { 
 protected: 
 M3DVector3f vOrigin; // Where am I? 
 M3DVector3f vForward; // Where am I going? 
 M3DVector3f vUp; // Which way is up? 

public:
//默认构造函数(世界坐标系,位置在(0,0,0)点,up为(0,1,0)朝+Y,forward为(0,0,-1)朝向-Z)
  GLFrame(void)
//设置/获取世界坐标系下模型/相机的位置
inline void SetOrigin(const M3DVector3f vPoint)
inline void SetOrigin(float x, float y, float z)
inline void GetOrigin(M3DVector3f vPoint)
//获取世界坐标系下模型/相机位置的X/Y/Z分量
inline float GetOriginX(void)
inline float GetOriginY(void)
inline float GetOriginZ(void)
 
//设置/获取世界坐标系下模型/相机向前的方向向量
inline void SetForwardVector(const M3DVector3f vDirection)
inline void SetForwardVector(float x, float y, float z)
inline void GetForwardVector(M3DVector3f vVector)
 
//设置/获取世界坐标系下模型/相机向上的方向向量
inline void SetUpVector(const M3DVector3f vDirection)
inline void SetUpVector(float x, float y, float z)
inline void GetUpVector(M3DVector3f vVector)
 
//获取世界坐标系下模型/相机X/Y/Z轴方向向量
inline void GetZAxis(M3DVector3f vVector) {GetForwardVector(vVector); }
inline void GetYAxis(M3DVector3f vVector) { GetUpVector(vVector); }
inline void GetXAxis(M3DVector3f vVector) {m3dCrossProduct(vVector, vUp, vForward); }
 
// 以世界坐标系下(x,y,z)偏移量移动模型/相机
inline void TranslateWorld(float x, float y, float z)
// 以物体坐标系下(x,y,z)偏移量移动模型/相机
inline void TranslateLocal(float x, float y, float z)
// 沿物体坐标系下Z轴以指定偏移fDelta量移动模型/相机
inline void MoveForward(float fDelta)
// 沿物体坐标系下Y轴以指定偏移fDelta移动物体/相机
inline void MoveUp(float fDelta)
// 沿物体坐标系下X轴以指定偏移fDelta移动物体/相机
inline void MoveRight(float fDelta)
 
// 获取一个用于描述模型属性的4×4的矩阵
void GetMatrix(M3DMatrix44f matrix, bool bRotatiOnOnly= false)
// 获取一个用于描述相机属性的4×4的矩阵
inline void GetCameraOrientation(M3DMatrix44f m)
 
// 应用所有的相机变换。该函数仅用于相机
inline void ApplyCameraTransform(bool bRotOnly= false)
// 应用所有的物体变换。该函数仅用于除相机外的物体
void ApplyActorTransform(bool bRotatiOnOnly= false)
// 令物体/相机以自身位置为中心,绕X/Y/Z轴旋转。其角度以PI为单位
void RotateLocalX(float fAngle)
void RotateLocalY(float fAngle)
void RotateLocalZ(float fAngle)
 
// Reset axes to make sure they are orthonormal. This should be called on occasion
// if the matrix is long-lived and frequently transformed.
// 规范化
void Normalize(void)
// 模型/相机绕世界坐标系下的指定轴(x,y,z)旋转fAngle度
void RotateWorld(float fAngle, float x, float y, float z)
 // 模型/相机绕当前物体坐标系下的指定轴(x,y,z)旋转fAngle度
void RotateLocal(float fAngle, float x, float y, float z)
 
// 将点/向量vLocal从当前物体坐标系转换为世界坐标系
void LocalToWorld(const M3DVector3f vLocal, M3DVector3f vWorld)
 
// 将点/向量vLocal从世界坐标系转换为当前物体坐标系
void WorldToLocal(const M3DVector3f vWorld, M3DVector3f vLocal)
 
// 通过当前frame矩阵将vPointSrc点变换为vPointDst点
void TransformPoint(M3DVector3f vPointSrc, M3DVector3f vPointDst)
 //通过当前frame矩阵将vVectorSrc向量旋转为vVectorDst向量
void RotateVector(M3DVector3f vVectorSrc, M3DVector3f vVectorDst)
}
  • GLFrustum – 视景体
// 设置正投影
void SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)
// 设置透视投影
void SetPerspective(float fFov, float fAspect, float fNear, float fFar)
//  获取透视矩阵
const M3DMatrix44f& GetProjectionMatrix(void) { return projMatrix; }
  • GLBatch – 批次容器
    GLTools库中,包含了一个容器类GLBatch,可以作为7种图元批次容器使用,它知道使用GLShaderManager支持的任意存储着色器时,如何对图元进行渲染。
// 参数1:图元
// 参数2:顶点个数
// 参数3:一组或两组纹理图标
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
// 复制顶点
void CopyVertexData3f(M3DVector3f *vVerts);
// 复制表面法线
void GLBatch::CopyNormalDataf(GLfloat *vNorms);
// 复制颜色
void GLBatch::CopyColorData4f(GLfloat *vColors);
// 复制纹理坐标
void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords,GLuint u
iTextureLayer);
// 重置
void Reset(void);
// 设置顶点
void Vertex3f(GLfloat x, GLfloat y, GLfloat z);
 void Vertex3fv(M3DVector3f vVertex);
// 设置法线        
void Normal3f(GLfloat x, GLfloat y, GLfloat z);
void Normal3fv(M3DVector3f vNormal);
// 设置颜色    
void Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
void Color4fv(M3DVector4f vColor);
// 设置纹理        
void MultiTexCoord2f(GLuint texture, GLclampf s, GLclampf t);
void MultiTexCoord2fv(GLuint texture, M3DVector2f vTexCoord);
// 画
virtual void Draw(void);
// 绘制结束
void GLBatch::End(void);
  • GLTriangleBatch – 三角形批次类
// Use these three functions to add triangles
void BeginMesh(GLuint nMaxVerts);
void AddTriangle(M3DVector3f verts[3], M3DVector3f vNorms[3], M3DVector2f vTexCoords[3]);
void End(void);
virtual void Draw(void);
  • GLGeometryTransform – 几何变换管道
// 设置模型视图矩阵堆栈
inline void SetModelViewMatrixStack(GLMatrixStack& mModelView) { _mModelView = &mModelView; }
// 设置投影视图矩阵堆栈
inline void SetProjectionMatrixStack(GLMatrixStack& mProjection) { _mProjection = &mProjection; }
// 设置模型视图投影矩阵堆栈
inline void SetMatrixStacks(GLMatrixStack& mModelView, GLMatrixStack& mProjection)  {
    _mModelView = &mModelView;
    _mProjection = &mProjection;
}
// 获取模型视图投影矩阵
const M3DMatrix44f& GetModelViewProjectionMatrix(void)
// 获取模型视图矩阵
inline const M3DMatrix44f& GetModelViewMatrix(void) { return _mModelView->GetMatrix(); }
// 获取投影视图矩阵
inline const M3DMatrix44f& GetProjectionMatrix(void) { return _mProjection->GetMatrix(); }

绘制流程

  • main函数
int main(int argc, char* argv[])
{
    // 设置工作路径
    gltSetWorkingDirectory(argv[0]);
    // 这个函数用来初始化 GLUT 库
    glutInit(&argc, argv);
    //申请一个双缓存区,颜色缓存区、深度缓存区、模板缓存区
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    //设置window 的尺寸
    glutInitWindowSize(800, 600);
    //创建window的名称
    glutCreateWindow("GL_POINTS");
    //注册回调函数(改变尺寸)
    glutReshapeFunc(ChangeSize);
    //点击空格时,调用的函数
    glutKeyboardFunc(KeyPressFunc);
    //特殊键位函数(上下左右)
    glutSpecialFunc(SpecialKeys);
    //显示函数
    glutDisplayFunc(RenderScene);
    
    //判断一下是否能初始化glew库,确保项目能正常使用OpenGL 框架
    GLenum err = glewInit();
    
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %sn", glewGetErrorString(err));
        return 1;
    }
    
    // 此函数在呈现上下文中进行任何必要的初始化。.
    // 这是第一次做任何与opengl相关的任务。
    SetupRC();
    
    //runloop运行循环
    glutMainLoop();
    
    return 0;
}
  • 上下文初始化等工作
void SetupRC()
{
    // Black background
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
    
    //初始化固定着色管理器
    shaderManager.InitializeStockShaders();
    
    //开启深度测试
    glEnable(GL_DEPTH_TEST);
    
    //通过GLGeometryTransform管理矩阵堆栈
    //使用transformPipeline 管道管理模型视图矩阵堆栈 和 投影矩阵堆栈
    transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
    
    //将观察者坐标位置Z移动往屏幕里移动15个单位位置
    //表示离屏幕之间的距离 负数,是往屏幕后面移动;正数,往屏幕前面移动
    cameraFrame.MoveForward(-15.0f);
    
    //利用三角形批次类构造图形对象
    // 球
    /*
      gltMakeSphere(GLTriangleBatch& sphereBatch, GLfloat fRadius, GLint iSlices, GLint iStacks);
     参数1:sphereBatch,三角形批次类对象
     参数2:fRadius,球体半径
     参数3:iSlices,从球体底部堆叠到顶部的三角形带的数量;其实球体是一圈一圈三角形带组成
     参数4:iStacks,围绕球体一圈排列的三角形对数
     
     建议:一个对称性较好的球体的片段数量是堆叠数量的2倍,就是iStacks = 2 * iSlices;
     绘制球体都是围绕Z轴,这样+z就是球体的顶点,-z就是球体的底部。
     */
    gltMakeSphere(sphereBatch, 3.0, 10, 20);
    
    // 环面
    /*
     gltMakeTorus(GLTriangleBatch& torusBatch, GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor);
     参数1:torusBatch,三角形批次类对象
     参数2:majorRadius,甜甜圈中心到外边缘的半径
     参数3:minorRadius,甜甜圈中心到内边缘的半径
     参数4:numMajor,沿着主半径的三角形数量
     参数5:numMinor,沿着内部较小半径的三角形数量
     */
    gltMakeTorus(torusBatch, 3.0f, 0.75f, 15, 15);
    
    // 圆柱
    /*
     void gltMakeCylinder(GLTriangleBatch& cylinderBatch, GLfloat baseRadius, GLfloat topRadius, GLfloat fLength, GLint numSlices, GLint numStacks);
     参数1:cylinderBatch,三角形批次类对象
     参数2:baseRadius,底部半径
     参数3:topRadius,头部半径
     参数4:fLength,圆形长度
     参数5:numSlices,围绕Z轴的三角形对的数量
     参数6:numStacks,圆柱底部堆叠到顶部圆环的三角形数量
     */
    gltMakeCylinder(cylinderBatch, 2.0f, 2.0f, 3.0f, 15, 2);
    
    //锥
    /*
     void gltMakeCylinder(GLTriangleBatch& cylinderBatch, GLfloat baseRadius, GLfloat topRadius, GLfloat fLength, GLint numSlices, GLint numStacks);
     参数1:cylinderBatch,三角形批次类对象
     参数2:baseRadius,底部半径
     参数3:topRadius,头部半径
     参数4:fLength,圆形长度
     参数5:numSlices,围绕Z轴的三角形对的数量
     参数6:numStacks,圆柱底部堆叠到顶部圆环的三角形数量
     */
    //圆柱体,从0开始向Z轴正方向延伸。
    //圆锥体,是一端的半径为0,另一端半径可指定。
    gltMakeCylinder(coneBatch, 2.0f, 0.0f, 3.0f, 13, 2);
    
    // 磁盘
    /*
    void gltMakeDisk(GLTriangleBatch& diskBatch, GLfloat innerRadius, GLfloat outerRadius, GLint nSlices, GLint nStacks);
     参数1:diskBatch,三角形批次类对象
     参数2:innerRadius,内圆半径
     参数3:outerRadius,外圆半径
     参数4:nSlices,圆盘围绕Z轴的三角形对的数量
     参数5:nStacks,圆盘外网到内围的三角形数量
     */
    gltMakeDisk(diskBatch, 1.5f, 3.0f, 13, 3);
}

  • 屏幕大小发生改变
void ChangeSize(int w, int h)
{
    // 修改视口大小
    glViewport(0, 0, w, h);
    
    //设置透视投影
    viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
    
    //projectionMatrix 矩阵堆栈 加载透视投影矩阵
    projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
    
    //modelViewMatrix 矩阵堆栈 加载单元矩阵
    modelViewMatrix.LoadIdentity();
}
  • 绘制场景
//召唤场景
void RenderScene(void)
{
    //用当前清除颜色清除窗口背景
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    
    //模型视图矩阵栈堆,压栈
    modelViewMatrix.PushMatrix();
    //获取摄像头矩阵
    M3DMatrix44f mCamera;
    //从camereaFrame中获取矩阵到mCamera
    cameraFrame.GetCameraMatrix(mCamera);
    //模型视图堆栈的 矩阵与mCamera矩阵 相乘之后,存储到modelViewMatrix矩阵堆栈中
    modelViewMatrix.MultMatrix(mCamera);
    
    //创建矩阵mObjectFrame
    M3DMatrix44f mObjectFrame;
    //从ObjectFrame 获取矩阵到mOjectFrame中
    objectFrame.GetMatrix(mObjectFrame);
    //将modelViewMatrix 的堆栈中的矩阵 与 mOjbectFrame 矩阵相乘,存储到modelViewMatrix矩阵堆栈中
    modelViewMatrix.MultMatrix(mObjectFrame);
    
    //判断你目前是绘制第几个图形
    switch(nStep) {
        case 0:
            DrawWireFramedBatch(&sphereBatch);
            break;
        case 1:
            DrawWireFramedBatch(&torusBatch);
            break;
        case 2:
            DrawWireFramedBatch(&cylinderBatch);
            break;
        case 3:
            DrawWireFramedBatch(&coneBatch);
            break;
        case 4:
            DrawWireFramedBatch(&diskBatch);
            break;
    }
    
    modelViewMatrix.PopMatrix();
    
    // Flush drawing commands
    glutSwapBuffers();
}

void DrawWireFramedBatch(GLTriangleBatch* pBatch)
{
    //平面着色器,绘制三角形
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen);
   
    //传过来的参数,对应不同的图形Batch
    pBatch->Draw();
    
    // 画出黑色轮廓
    glPolygonOffset(-1.0f, -1.0f);
    
    //开启线段抗锯齿
    glEnable(GL_LINE_SMOOTH);
    
    //开启混合功能
    glEnable(GL_BLEND);
    
    //颜色混合,设置混合因子
    //表示源颜色乘以自身的alpha 值,目标颜色乘以1.0减去源颜色的alpha值,这样一来,源颜色的alpha值越大,则产生的新颜色中源颜色所占比例就越大,而目标颜色所占比例则减 小。这种情况下,我们可以简单的将源颜色的alpha值理解为“不透明度”。这也是混合时最常用的方式。
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    //通过程序点大小模式来设置点的大小
    glEnable(GL_POLYGON_OFFSET_LINE);
    
    //多边形模型(背面、线) 将多边形背面设为线框模式
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    
    //线条宽度
    glLineWidth(2.5f);
    
    //平面着色器绘制线条
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);

    pBatch->Draw();
    
    // 恢复多边形模式和深度测试
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
    glDisable(GL_BLEND);
    glDisable(GL_LINE_SMOOTH);
}
  • 按键控制
//上下左右,移动图形
void SpecialKeys(int key, int x, int y)
{
    if(key == GLUT_KEY_UP)
        //移动世界坐标系,而不是去移动物体。
        //将世界坐标系在X方向移动-5.0
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
    
    if(key == GLUT_KEY_DOWN)
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);
    
    if(key == GLUT_KEY_LEFT)
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);
    
    if(key == GLUT_KEY_RIGHT)
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);
    
    glutPostRedisplay();
}

//点击空格,切换渲染图形
void KeyPressFunc(unsigned char key, int x, int y)
{
    if(key == 32)
    {
        nStep++;
        
        if(nStep > 4)
            nStep = 0;
    }
    
    switch(nStep)
    {
        case 0:
            glutSetWindowTitle("Sphere");
            break;
        case 1:
            glutSetWindowTitle("Torus");
            break;
        case 2:
            glutSetWindowTitle("Cylinder");
            break;
        case 3:
            glutSetWindowTitle("Cone");
            break;
        case 4:
            glutSetWindowTitle("Disk");
            break;
    }
    
    glutPostRedisplay();
}


推荐阅读
  • C++程序员视角下的Rust语言
    自上世纪80年代初问世以来,C就是一门非常重要的系统级编程语言。到目前为止,仍然在很多注重性能、实时性、偏硬件等领域发挥着重要的作用。C和C一样&#x ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • C语言常量与变量的深入理解及其影响
    本文深入讲解了C语言中常量与变量的概念及其深入实质,强调了对常量和变量的理解对于学习指针等后续内容的重要性。详细介绍了常量的分类和特点,以及变量的定义和分类。同时指出了常量和变量在程序中的作用及其对内存空间的影响,类似于const关键字的只读属性。此外,还提及了常量和变量在实际应用中可能出现的问题,如段错误和野指针。 ... [详细]
  • 手把手教你使用GraphPad Prism和Excel绘制回归分析结果的森林图
    本文介绍了使用GraphPad Prism和Excel绘制回归分析结果的森林图的方法。通过展示森林图,可以更加直观地将回归分析结果可视化。GraphPad Prism是一款专门为医学专业人士设计的绘图软件,同时也兼顾统计分析的功能,操作便捷,可以帮助科研人员轻松绘制出高质量的专业图形。文章以一篇发表在JACC杂志上的研究为例,利用其中的多因素回归分析结果来绘制森林图。通过本文的指导,读者可以学会如何使用GraphPad Prism和Excel绘制回归分析结果的森林图。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • #define_CRT_SECURE_NO_WARNINGS#includelist.h#includevoidSListInit(PNode*pHead ... [详细]
  • 环境Time2022-04-11Rust1.60.0前言说明基于标准库来学习各种数据结构,并不是从头实现数据结构,未考虑实现性能。特点相比较二叉树,二叉搜索树的左节点都比父节点小, ... [详细]
  • 痞子衡嵌入式:对比MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异...
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异。近 ... [详细]
author-avatar
vghoon
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有