[OpenGL ES 04]3D变换实践篇:平移,旋转,缩放

[OpenGL ES 04]3D变换实践篇:平移,旋转,缩放

罗朝辉 (http://blog.csdn.net/kesalin)

本文遵循“署名-非商业用途-保持一致”创作公用协议

前言

前文《[OpenGL ES 03]3D变换:模型,视图,投影与Viewport》中已经详细介绍了3D变换相关的数学知识,也讲了基本的模型变换:平移,旋转与缩放,如果你还没有阅读前文或对这些知识还不够明白,务必先弄懂前文再继续。假如你已经准备好继续了,那么在接下来的内容中,我将介绍如何在 OpenGL ES 中运用这些知识,来渲染一个四棱锥,并对它进行平移,旋转与缩放操作,此外本文也演示了如何将 OpenGL View 与 UIView 结合在一起(注意:在实际运用中,不推荐这么做,混合使用 OpenGL View 和 UIView 对效率影响较大)。

本文代码可以从这里获得:点此下载(Tutorial03),最终效果图如下:


 

一,创建工程

1,新建工程

从今天起,我们不再从头开始创建 window 和 view 了,新建一个名为 Tutorial03 的 Single view application 工程:


2,从前面的效果图中可以看到,在这个教程中,我们需要两个 view:OpenGL view 和 UIView。因此打开 MainStoryboard.storyboard,向其中加入两个 view,其中上面那一个用于 OpenGL view,下面那一个用于 control view。调整两个view 的大小与位置,将下面的 view 的背景设置为浅蓝色,以方便区分。


3,拷贝 Tutorial02 教程中的 GLESUtils.h, GLESUtils.m OpenGLView.h, OpenGLView.m 以及 FragmentShader.glsl, VertexShader.glsl 到 Tutorial03 中,并加入到工程中进来,再添加 OpenGLES 以及 QuartzCore framework。


4,在 ViewController.h 中,为这两个view 添加 IBOutlet:

#import "OpenGLView.h"

@interface ViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIView * controlView;
@property (nonatomic, strong) IBOutlet OpenGLView * openGLView;

在 ViewController.m 中 @implementation ViewController 下面的添加

@synthesize controlView, openGLView;

并在 viewDidUnload 中进行清理:

- (void)viewDidUnload
{
    [super viewDidUnload];
    
    [self.openGLView cleanup];
    self.openGLView = nil;
    
    self.controlView = nil;
}

5,回到 MainStoryboard.storyboard,将上面那个 view 的类型设置为 OpenGLView,并关联相关的 IBOutlet:


 

二,描绘四棱锥

1,在 Tutorial02 中只描绘了一个三角形,这回我们来描绘一个真正的 3D 物体:四棱锥。在 OpenGLView.m 中 render() 上面添加如下函数:

- (void)drawTriCone
{
    GLfloat vertices[] = {
        0.5f, 0.5f, 0.0f, 
        0.5f, -0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        -0.5f, 0.5f, 0.0f, 
        0.0f, 0.0f, -0.707f,
    };
    
    GLubyte indices[] = {
        0, 1, 1, 2, 2, 3, 3, 0,
        4, 0, 4, 1, 4, 2, 4, 3
    };
    
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices );
    glEnableVertexAttribArray(_positionSlot);
    
    // Draw lines
    //
    glDrawElements(GL_LINES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices);
}

这次我们使用顶点索引数组结合 glDrawElements 来渲染,而在 Tutorial02 中,使用的是 glDrawArrays。使用顶点索引数组有什么好处呢?很明显,我们可以减少存储重复顶点的内存消耗。比如在本例的索引表中,我们重复利用了顶点 0,1,2,3,4,它们对应 vertices 数组中5个顶点(三个浮点数组成一个顶点)。

glDrawElements 函数的原型为:

void glDrawElements(    GLenum      mode,
     GLsizei      count,
     GLenum      type,
     const GLvoid *      indices);

第一个参数 mode 为描绘图元的模式,其有效值为:GL_POINTS, GL_LINES, GL_LINE_STRIP,  GL_LINE_LOOP,  GL_TRIANGLES,  GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN。这些模式具体含义下面有介绍。

第二个参数 count 为顶点索引的个数也就是,type 是指顶点索引的数据类型,因为索引始终是正值,索引这里必须是无符号型的非浮点类型,因此只能是 GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT 之一,为了减少内存的消耗,尽量使用最小规格的类型如 GL_UNSIGNED_BYTE。

第三个参数 indices 是存放顶点索引的数组。(indices 是 index 的复数形式,3D 里面很多单词的复数都挺特别的。)

2,使用

修改 render() 函数如下:

- (void)render
{
    glClearColor(0, 1.0, 0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Setup viewport
    //
    glViewport(0, 0, self.frame.size.width, self.frame.size.height);    
    
    [self drawTriCone];

    [_context presentRenderbuffer:GL_RENDERBUFFER];
}

编译运行程序,你就应该就能看到一个四棱锥了。


也许你会说,怎么看起来不像呢?那是因为你是从四棱锥的正上方朝下俯视它,索引四棱锥的尖顶(就是图中间交叉的那个点)看起来就是平的了。如果我们给程序加入旋转功能,那就会看得非常明显了,在介绍完图元模式之后,我们将加入旋转功能。


三,图元模式介绍:

对于画 line 来说有三种模式:


此外还可以通过函数 glLineWidth(GLfloat width) 来设定线的宽度,要获得当前设置的线宽度可以使用如下代码:

GLfloat lineWidthRange[2];
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);

在 Tutorial02 教程中,我们使用模式 GL_TRIANGLES 描绘了一个三角形。对于三角形来说也有三种模式:


OpenGL ES 还支持描绘点(精灵, sprite)的模式:GL_POINTS,此外还可以通过内建变量 gl_PointSize 来设置点精灵的大小,要获取当前设置的点精灵的大小可以使用如下代码:

GLfloat pointSizeRange[2]; 
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);

 

四,平移

1,添加控件

为了加入平移控制,我们需要在下面的 view 上面添加滑块对平移的距离进行调节。为此,打开 MainStoryboard.storyboard,在下面浅蓝色背景的 UIView 上添加一个 UILabel 和 UISlider。


并设置滑块的最大值 3,最小值 -3 和当前值 0 :


2,加入控件关联代码

在 ViewController.h 中加入滑块的 IBOutlet 和 IBAction,并将它与 UISlider 关联起来。

@property (nonatomic, strong) IBOutlet UISlider * posXSlider;

- (IBAction)xSliderValueChanged:(id)sender;

在 ViewController.m 中加入:

@synthesize posXSlider;

- (IBAction)xSliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];

    NSLog(@" >> current x is %f", currentValue);
}

这时,如果你拖动滑块,就能输出滑块当前的值。不要忘记在 viewDidUnload 清理该滑块:

self.posXSlider = nil;

 

3,加入平移代码

为了让我们的三棱锥可以在 x 轴上移动,打开 OpenGLView.h,在 @interface 中加入:

float _posX;

然后再加入属性:

@property (nonatomic, assign) float posX;

打开 OpenGLView.m,加入:

@synthesize posX = _posX;

 

4,修改顶点着色器代码

打开 VertexShader.glsl,修改其内容如下:

uniform mat4 projection;
uniform mat4 modelView;
attribute vec4 vPosition; 
 
void main(void)
{
    gl_Position = projection * modelView * vPosition;
}

在上面的代码中,我们对输入顶点进行了自定义的投影和模型视图变换,还记得在前文中介绍的内容么?尤其是左乘,在这里,顶点先进行模型视图变换,然后再进行投影变换。

5,增加实现 Transform 代码

回到 OpenGLView.h 中,加入对应的投影矩阵与模型视图矩阵:

    KSMatrix4 _modelViewMatrix;
    KSMatrix4 _projectionMatrix;

KSMatrix4 是定义在数学辅助库 GLESMath 中用 4 * 4 的二维数组表示的矩阵,你可以在这里获取 GLESMath.h 和 GLESMath.c,并将它们加入工程中。这个数学辅助库中包含了常见的一些 3D 计算,后面还会提到它。

在 OpenGLView.m 中,在 setupProgram 的最后加入获取模型视图矩阵以及投影矩阵变量的槽位:

    // Get the attribute position slot from program
    //
    _positionSlot = glGetAttribLocation(_programHandle, "vPosition");
    
    // Get the uniform model-view matrix slot from program
    //
    _modelViewSlot = glGetUniformLocation(_programHandle, "modelView");
    
    // Get the uniform projection matrix slot from program
    //
    _projectionSlot = glGetUniformLocation(_programHandle, "projection");

 在OpenGLView 的匿名 category 中加入以下两个函数声明:

- (void)setupProjection;

- (void)updateTransform;

然后在 @implemetion 中实现它们:

-(void)setupProjection
{
    // Generate a perspective matrix with a 60 degree FOV
    //
    float aspect = self.frame.size.width / self.frame.size.height;
    ksMatrixLoadIdentity(&_projectionMatrix);
    ksPerspective(&_projectionMatrix, 60.0, aspect, 1.0f, 20.0f);
    
    // Load projection matrix
    glUniformMatrix4fv(_projectionSlot, 1, GL_FALSE, (GLfloat*)&_projectionMatrix.m[0][0]);
}

上面的代码中,ksMatrixLoadIdentity 是 GLESMath 中的一个数学函数,用来将指定矩阵重置为单位矩阵,而 ksPerspective 与前文中讲到的 gluPersoective 作用一样。在这里,我们设置视锥体的近裁剪面到观察者的距离为 1, 远裁剪面到观察者的距离为 20,视角为 60度,然后装载投影矩阵。默认的观察者位置在原点,视线朝向 -Z 方向,因此近裁剪面其实就在 z = -1 这地方,远裁剪面在 z = -20 这地方,z 值不在(-1, -20) 之间的物体是看不到的。不要忘记在初始化代码中调用该函数:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setupLayer];        
        [self setupContext];
        [self setupProgram];
        [self setupProjection];
    }

    return self;
}

下面的代码是更新模型视图矩阵,以响应用户的控制。

- (void)updateTransform
{
    // Generate a model view matrix to rotate/translate/scale
    //
    ksMatrixLoadIdentity(&_modelViewMatrix);
    
    // Translate away from the viewer
    //
    ksTranslate(&_modelViewMatrix, self.posX, 0.0, -5.5);
    
    // Rotate the triangle
    //
    ksRotate(&_modelViewMatrix, 0.0, 1.0, 0.0, 0.0);
    
    // Scale the triangle
    ksScale(&_modelViewMatrix, 1.0, 1.0, 1.0);
    
    // Load the model-view matrix
    glUniformMatrix4fv(_modelViewSlot, 1, GL_FALSE, (GLfloat*)&_modelViewMatrix.m[0][0]);
}

上面的代码中,ksTranslate,ksRotate,ksScale 也是 GLESMath 中的数学函数,作用与 glTranslate,glRotate,glScale 相同,分别用于平移,绕轴旋绕以及缩放。在这里,设置在 x 方向上平移,平移量将由 self.posX 控制,而这个属性最终是由滑块控制的,从而达到用户移动物体的目的;将 z 设置为 -5.5 (介于 (-1, -20) 之间,前面有讲);此外还设置绕 x 轴旋绕 0 度,在 x,y,z三个方向上缩放 1 倍,这两个函数的调用是为下一步的旋转和缩放控制准备的。最后,装载模型视图矩阵。

由于需要在 posX 的值变化时,及时更新模型视图矩阵,并重新描绘,以便能及时看到效果,我们得自己实现属性 posX 的 setter 和 getter 方法:

- (void)setPosX:(float)x
{
    _posX = x;
    
    [self updateTransform];
    [self render];
}

- (float)posX
{
    return _posX;
}

6,至此,下层的控制代码就绪了,我们来实现上层 UI 的响应代码,修改 ViewController.m 中的 xSliderValueChanged 方法如下:

- (IBAction)xSliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];
    
    openGLView.posX = currentValue;

    NSLog(@" >> current x is %f", currentValue);
}

7,编译运行,滑动滑块你就能够控制四棱锥在 x 方向上来回移动了(还记得前面限制了 x 的位置只能在 (-3, 3) 之间么,这是为了不让四棱锥跑到屏幕外边去)。聪明的你,应该很容易实现如何控制在 y 和 z 方向的移动了。在实现的过程中要注意,y 滑块的取值范围也为(-3, 3),默认值为0,而 z 滑块的取值范围为(-10, -1),默认值居中为-5.5。这样的设置可以确保物体不会完全跑出视锥体所圈定的范围,因为视锥体之外的物体是不可见的。比如下图中四棱锥的尖顶部分就跑到视锥体的近裁剪面外面去了,所以尖顶就被裁剪了。



五,旋绕,缩放

1,实现下层控制代码

有了控制平移的基础,我们也很容易就能控制旋转与缩放。我们还是从下层开始,修改 OpenGLView.h 中的代码(我将在 y 和 z 方向平移的代码放在这里了,希望你是自己实现它的):

    float _posX;
    float _posY;
    float _posZ;
    
    float _rotateX;
    float _scaleZ;
}

@property (nonatomic, assign) float posX;
@property (nonatomic, assign) float posY;
@property (nonatomic, assign) float posZ;

@property (nonatomic, assign) float scaleZ;
@property (nonatomic, assign) float rotateX;

修改 OpenGLView.m 中的代码:

@synthesize posX = _posX;
@synthesize posY = _posY;
@synthesize posZ = _posZ;
@synthesize scaleZ = _scaleZ;
@synthesize rotateX = _rotateX;

前面说过,我们需要自己实现这些属性的 setter 和 getter 方法,在这里就不一一列出了, 它们与 setPosX 和 posX 的实现是类似的。我们需要让这些属性来控制模型视图矩阵,因此还要更新 updateTransform 方法如下:

- (void)updateTransform
{
    // Generate a model view matrix to rotate/translate/scale
    //
    ksMatrixLoadIdentity(&_modelViewMatrix);
    
    // Translate away from the viewer
    //
    ksTranslate(&_modelViewMatrix, self.posX, self.posY, self.posZ);
    
    // Rotate the triangle
    //
    ksRotate(&_modelViewMatrix, self.rotateX, 1.0, 0.0, 0.0);
    
    // Scale the triangle
    ksScale(&_modelViewMatrix, 1.0, 1.0, self.scaleZ);
    
    // Load the model-view matrix
    glUniformMatrix4fv(_modelViewSlot, 1, GL_FALSE, (GLfloat*)&_modelViewMatrix.m[0][0]);
}

这样四棱锥就能绕 x 轴旋转 rotateX 角度,并在 z 方向上缩放 scaleZ 倍。注意:属性 scaleZ 默认值为 0,所以我们需要对它进行初始化,此外为了能方便重置模型视图矩阵,我实现了 resetTransform,该方法在 initWithCoder 方法的最后被调用。

- (void)resetTransform
{
    _posX = 0.0;
    _posY = 0.0;
    _posZ = -5.5;
    
    _scaleZ = 1.0;
    _rotateX = 0.0;
    
    [self updateTransform];
}

2,添加上层控制代码

 打开 MainStoryboard.storyboard,在下方的 control view 中添加滑块与按钮,如图所示:


 然后修改 ViewController.h 为:

@interface ViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIView * controlView;
@property (nonatomic, strong) IBOutlet OpenGLView * openGLView;

@property (nonatomic, strong) IBOutlet UISlider * posXSlider;
@property (nonatomic, strong) IBOutlet UISlider * posYSlider;
@property (nonatomic, strong) IBOutlet UISlider * posZSlider;
@property (nonatomic, strong) IBOutlet UISlider * scaleZSlider;
@property (nonatomic, strong) IBOutlet UISlider * rotateXSlider;

- (IBAction)xSliderValueChanged:(id)sender; 
- (IBAction)ySliderValueChanged:(id)sender; 
- (IBAction)ySliderValueChanged:(id)sender;

- (IBAction)scaleZSliderValueChanged:(id)sender; 
- (IBAction)rotateXSliderValueChanged:(id)sender;

- (IBAction)autoButtonClick:(id)sender;
- (IBAction)resetButtonClick:(id)sender;

@end

在 ViewController.m 中添加属性相关代码:

@synthesize posXSlider, posYSlider, posZSlider;
@synthesize scaleZSlider, rotateXSlider;

- (void)viewDidUnload
{
    [super viewDidUnload];
    
    [self.openGLView cleanup];
    self.openGLView = nil;
    
    self.posXSlider = nil;
    self.posYSlider = nil;
    self.posZSlider = nil;
    self.scaleZSlider = nil;
    self.rotateXSlider = nil;
    self.controlView = nil;
}

以及响应事件的方法:

- (IBAction)ySliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];
    
    openGLView.posY = currentValue;
    
    NSLog(@" >> current y is %f", currentValue);
}

- (IBAction)zSliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];
    
    openGLView.posZ = currentValue;
    
    NSLog(@" >> current z is %f", currentValue);
}

- (IBAction)scaleZSliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];
    
    openGLView.scaleZ = currentValue;
    
    NSLog(@" >> current z scale is %f", currentValue);
}

- (IBAction)rotateXSliderValueChanged:(id)sender
{
    UISlider * slider = (UISlider *)sender;
    float currentValue = [slider value];
    
    openGLView.rotateX = currentValue;
    
    NSLog(@" >> current x rotation is %f", currentValue);   
}

- (IBAction)autoButtonClick:(id)sender
{
}

- (IBAction)resetButtonClick:(id)sender
{
}

上面的代码很简单,基本与平移 x 的代码类似,所以在这里也就不一一讲述了。然后回到 MainStoryboard.storyboard 中,使用拖拽技巧将相关属性和事件与控件关联起来。 

3,编译运行,滑动不同的滑块,体验下 3D 变换的效果。

 

六,自动旋转与重置

1,重置恢复默认状态

还记得在前面我提到有一个重置模型视图矩阵的方法么,如果想让物体恢复默认状态,只要调用此方法,再重新描绘即可。因此,resetButtonClick 实现如下:

- (void)resetControls
{
    [posXSlider setValue:self.openGLView.posX];
    [posYSlider setValue:self.openGLView.posY];
    [posZSlider setValue:self.openGLView.posZ];
    
    [scaleZSlider setValue:self.openGLView.scaleZ];
    [rotateXSlider setValue:self.openGLView.rotateX];
}

- (IBAction)resetButtonClick:(id)sender
{
    [openGLView resetTransform];
    [openGLView render];
    
    [self resetControls];
}

在 Tutorial02 教程中 render 方法是私有方法,在这里,需要把它修改为公开方法。resetControls 是用来设置控件的默认值,以保持模型矩阵与控件的相关值同步,记得在 viewDidLoad 中调用此函数。编译运行,无论你做了多么复杂的变换,只要按下 Reset 按钮,一切都恢复原样了。

2,自动旋转

下面来添加点好玩的,让物体自动绕 X 轴旋转。这通常是通过 timer 来实现的,但苹果为我们提供了更好的办法:CADisplayLink(其实它内部也是使用的 timer),它可以让我们的应用程序与屏幕的刷新率保持同步,每当屏幕刷新时,就会调用我们提供的回调函数。下面我们来使用它,在 OpenGLView.m 中的匿名 category 中添加成员变量:

@interface OpenGLView()
{
    CADisplayLink * _displayLink;
}

并添加回调函数声明:

- (void)displayLinkCallback:(CADisplayLink*)displayLink;

然后在下面的 @implemetion 中实现此回调,屏幕没刷新一次就让四棱锥绕 x 轴旋转一定的角度:

- (void)displayLinkCallback:(CADisplayLink*)displayLink
{
    self.rotateX += displayLink.duration * 90;
}

在 OpenGLView.h 中添加公开方法:

- (void)toggleDisplayLink;

然后在 OpenGLView.m 中实现之:

- (void)toggleDisplayLink
{
    if (_displayLink == nil) {
        _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback:)];
        [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
    else {
        [_displayLink invalidate];
        [_displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        _displayLink = nil;
    }
}

在上面的代码中,我们实现了一个 toggle 开关方法,如果没有自动旋转,那么就启动自动旋转;如果已经在自动旋转了,那么就停止它。CADisplayLink 的使用很简单,创建一个对象,设置它的 target 和回调函数,然后将它加入 NSRunLoop 中开始运行;如果要停止它,首先调用 invalidate 方法,然后将它从 NSRunLoop 中移除。

最后,我们在按钮的响应方法中添加对 toggleDisplayLink 的调用:

- (IBAction)autoButtonClick:(id)sender
{
    [openGLView toggleDisplayLink];
    
    UIButton * button = (UIButton *)sender;
    NSString * text = button.titleLabel.text;
    if ([text isEqualToString:@"Auto"]) {
        [button setTitle: @"Stop" forState: UIControlStateNormal];
    }
    else {
        [button setTitle: @"Auto" forState: UIControlStateNormal];
    }
}

编译运行代码,点击 Auto 就能让四棱锥自动旋转了,再次点击就能让它停止自动旋转,很妙吧?

 

七,总结

在这一篇文章中,介绍了如何通过 3D 变换来实现平移,旋转和缩放,以更好地理解前文中介绍的理论知识;同时也实现了如何通过 UIControl 来控制 OpenGL View 中的物体;此外还详细介绍了描绘图元的模式以及顶点索引模式。在文章的最后,介绍了如何使用 CADisplayLink 来实现动画效果。

最后,四棱锥看起来有点丑陋,来个水立方怎么样?(长方体),这个任务就交给看官你了,相信你一定可以实现的。

 

相关推荐
<p> <strong><span style="background-color:#FFFFFF;color:#E53333;font-size:24px;">本页面购买不发书!!!仅为视频课购买!!!</span></strong> </p> <p> <strong><span style="color:#E53333;font-size:18px;">请务必到</span></strong><a href="https://edu.csdn.net/bundled/detail/49?utm_source=banner"><strong><span style="color:#E53333;font-size:18px;">https://edu.csdn.net/bundled/detail/49</span></strong></a><strong><span style="color:#E53333;font-size:18px;">下单购买课+书。</span></strong> </p> <p> <span style="font-size:14px;">本页面仅为观看视频页面如需一并购买图书请</span><span style="font-size:14px;">务必到</span><a href="https://edu.csdn.net/bundled/detail/49?utm_source=banner"><span style="font-size:14px;">https://edu.csdn.net/bundled/detail/49</span></a><span style="font-size:14px;">下单购买课程+图书!!!</span> </p> <p> <br /> </p> <p> <span style="font-size:14px;">疯狂Python精讲课程覆盖《疯狂Python讲义》全书的主体内容。</span> </p> <span style="font-size:14px;">内容包括Python基本数据类型、Python列表、元组和字典、流程控制、函数式编程、面向对象编程、文件读写、异常控制、数据库编程、并发编程与网络编程、数据可视化分析、Python爬虫等。</span><br /> <span style="font-size:14px;"> 全套课程从Python基础开始介绍逐步步入当前就业热点。将会带着大家从Python基础语法开始学习为每个知识点都提供对应的代码实操、代码练习逐步过渡到文件IO、数据库编程、并发编程、网络编程、数据分 析和网络爬虫等内容本课程会从小案例起至爬虫、数据分析案例终、以Python知识体系作为内在逻辑以Python案例作为学习方式最终达到“知行合一”。</span><br />
DirectX修复工具(DirectX Repair)是一款系统级工具软件简便易用。本程序为绿色版无需安装可直接运行。 本程序的主要功能是检测当前系统的DirectX状态如果发现异常则进行修复。程序主要针对0xc000007b问题设计可以完美修复该问题。本程序中包含了最新版的DirectX redist(Jun2010)并且全部DX文件都有Microsoft的数字签名安全放心。 本程序为了应对一般电脑用户的使用采用了易用的一键式设计只要点击主界面上的“检测并修复”按钮程序就会自动完成校验、检测、下载、修复以及注册的全部功能无需用户的介入大大降低了使用难度。在常规修复过程中程序还会自动检测DirectX加速状态在异常时给予用户相应提示。 本程序适用于多个操作系统如Windows XP(需先安装.NET 2.0详情请参阅“致Windows XP用户.txt”文件)、Windows Vista、Windows 7、Windows 8、Windows 8.1、Windows 8.1 Update、Windows 10同时兼容32位操作系统和64位操作系统。本程序会根据系统的不同自动调整任务模式无需用户进行设置。 本程序的V4.0版分为标准版、增强版以及在线修复版。所有版本都支持修复DirectX的功能而增强版则额外支持修复c++的功能。在线修复版功能与标准版相同但其所需的数据包需要在修复时自动下载。各个版本之间主程序完全相同只是其配套使用的数据包不同。因此标准版和在线修复版可以通过补全扩展包的形式成为增强版。本程序自V3.5版起自带扩展功能。只要在主界面的“工具”菜单下打开“选项”对话框找到“扩展”标签点击其中的“开始扩展”按钮即可。扩展过程需要Internet连接扩展成功后新的数据包可自动生效。扩展用时根据网络速度不同而不同最快仅需数秒最慢需要数分钟烦请耐心等待。如扩展失败可点击“扩展”界面左上角小锁图标切换为加密连接即可很大程度上避免因防火墙或其他原因导致的连接失败。 本程序自V2.0版起采用全新的底层程序架构使用了异步多线程编程技术使得检测、下载、修复单独进行互不干扰快速如飞。新程序更改了自我校验方式因此使用新版本的程序时不会再出现自我校验失败的错误;但并非取消自我校验因此程序安全性与之前版本相同并未降低。 程序有更新系统c++功能。由于绝大多数软件运行时需要c++的支持并且c++的异常也会导致0xc000007b错误因此程序在检测修复的同时也会根据需要更新系统中的c++组件。自V3.2版本开始使用了全新的c++扩展包可以大幅提高工业软件修复成功的概率。修复c++的功能仅限于增强版标准版及在线修复版在系统c++异常时(非丢失时)会提示用户使用增强版进行修复。除常规修复外新版程序还支持C++强力修复功能。当常规修复无效时可以到本程序的选项界面内开启强力修复功能可大幅提高修复成功率。请注意请仅在常规修复无效时再使用此功能。 程序有两种窗口样式。正常模式即默认样式适合绝大多数用户使用。另有一种简约模式此时窗口将只显示最基本的内容修复会自动进行修复完成10秒钟后会自动退出。该窗口样式可以使修复工作变得更加简单快速同时方便其他软件、游戏将本程序内嵌即可进行无需人工参与的快速修复。开启简约模式的方法是打开程序所在目录下的“Settings.ini”文件(如果没有可以自己创建)将其中的“FormStyle”一项的值改为“Simple”并保存即可。 新版程序支持命令行运行模式。在命令行中调用本程序可以在路径后直接添加命令进行相应的设置。常见的命令有7类分别是设置语言的命令、设置窗口模式的命令设置安全级别的命令、开启强力修复的命令、设置c++修复模式的命令、控制Direct加速的命令、显示版权信息的命令。具体命令名称可以通过“/help”或“/?”进行查询。 程序有高级筛选功能开启该功能后用户可以自主选择要修复的文件避免了其他不必要的修复工作。同时也支持通过文件进行辅助筛选只要在程序目录下建立“Filter.dat”文件其中的每一行写一个需要修复文件的序号即可。该功能仅针对高级用户使用并且必须在正常窗口模式下才有效(简约模式时无效)。 本程序有自动记录日志功能可以记录每一次检测修复结果方便在出现问题时及时分析和查找原因以便找到解决办法。 程序的“选项”对话框中包含了7项高级功能。点击"常规”选项卡可以调整程序的基本运行情况包括日志记录、安全级别控制、调试模式开启等。只有开启调试模式后才能在C
<p> <b><span style="background-color:#FFE500;">【超实用课程内容】</span></b> </p> <p> <br /> </p> <p> <br /> </p> <p> 本课程内容包含讲解<span>解读Nginx的基础知识</span><span>解读Nginx的核心知识、带领学员进行</span>高并发环境下的Nginx性能优化实战让学生能够快速将所学融合到企业应用中。 </p> <p> <br /> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><br /> </b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b><span style="background-color:#FFE500;">【课程如何观看?】</span></b> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> PC端<a href="https://edu.csdn.net/course/detail/26277"><span id="__kindeditor_bookmark_start_21__"></span></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a> </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 移动端CSDN 学院APP(注意不是CSDN APP哦) </p> <p style="font-family:Helvetica;color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 本课程为录播课课程永久有效观看时长大家可以抓紧时间学习后一起讨论哦~ </p> <p style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <br /> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <strong><span style="background-color:#FFE500;">【学员专享增值服务】</span></strong> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> <b>源码开放</b> </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 课件、课程案例代码完全开放给你你可以根据所学知识自行修改、优化 </p> <p class="ql-long-24357476" style="font-family:"color:#3A4151;font-size:14px;background-color:#FFFFFF;"> 下载方式电脑登录<a href="https://edu.csdn.net/course/detail/26277"></a><a href="https://edu.csdn.net/course/detail/27216">https://edu.csdn.net/course/detail/27216</a>播放页面右侧点击课件进行资料打包下载 </p> <p> <br /> </p> <p> <br /> </p> <p> <br /> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页