天空盒

2020-03-22  本文已影响0人  一毛钱

天空盒Get知识点:

unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

因为立方体贴图包含有6个纹理,每个面一个,我们需要调用glTexImage2D函数6次,参数和之前教程中很类似。但这一次我们将纹理目标(target)参数设置为立方体贴图的一个特定的面,告诉OpenGL我们在对立方体贴图的哪一个面创建纹理。这就意味着我们需要对立方体贴图的每一个面都调用一次glTexImage2D。

 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 
        0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

设定它的环绕和过滤方式:

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
attribute vec3 aPos;

uniform mat4 projectionM;
uniform mat4 modelViewM;

varying lowp vec3 outTextCoord;

void main(){

    outTextCoord = aPos;
    vec4 pos = projectionM * modelViewM * vec4(aPos,1.0);
    //gl_Position = pos.xyww; //透视除法的应用
    //需要通过多边形偏移解决 边界闪烁的问题 (下面那个0.99是可以不乘的,而直接使用gl_Position = pos.xyww;),再查一下
    gl_Position =  vec4(pos.x,pos.y,pos.w*0.99,pos.w);
    
}

varying lowp vec3 outTextCoord;

uniform samplerCube boxTexture;

void main(){
    
    //gl_FragColor = vec4(0.2,0.2,0.3,1.0);
    gl_FragColor = textureCube(boxTexture,outTextCoord);
}
#pragma mark - cubeShafer
+(GLuint)loadCubeTextureWithImageNames:(NSArray*)fileNames
{
    //glActiveTexture(tex);
       GLuint textId ;
       glGenTextures(1, &textId);
       //绑定纹理
       glBindTexture(GL_TEXTURE_CUBE_MAP, textId);
    [self glCheckError];
    
    for (int i = 0; i < fileNames.count; ++i) {
        NSString* fileName = fileNames[I];
        size_t width,height;
        GLubyte *spriteData = [self getImageData:fileName width:&width height:&height];
        float fw = width,fh = height;
        if (spriteData) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X +i , 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
            //绑定纹理
            //glBindTexture(GL_TEXTURE_2D, 0);
            free(spriteData);
        } else {
            NSLog(@"立方体纹理加载错误---- ");
        }
    }
    [self glCheckError];
    
    //设置纹理的相关参数
    //参数不记得的同学,可以回顾一下OpenGL中的纹理课程
    //放大过滤器,缩小过滤器
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    [self glCheckError];
    return textId;
}
- (void)draw{
    glViewport(0, 0, _viewWidth,_viewHeight);
    glUseProgram(self.myProgram);

//先绘制盒子  填充深度缓冲区 
    glBindVertexArray(self.blackBoxVAO);
    glBindTexture(GL_TEXTURE_2D, self.textId);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    [ZKLodaShader glCheckError];
    
//再绘制天空盒  判断天空盒的深度缓冲区小于等于 当前深度缓冲区值,才比较通过。 
//结果就是天空盒只会在没有可见物体的地方渲染了(只有这样才能通过深度测试,其它所有的东西都在天空盒前面)
    glDepthFunc(GL_LEQUAL);
    glPolygonOffset(1.0, 1.0);
    glUseProgram(self.skyBoxProgram);
    glBindVertexArray(self.VAO);
    glBindTexture(GL_TEXTURE_CUBE_MAP, self.cubemapTexture);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    [ZKLodaShader glCheckError];
    glDepthFunc(GL_LESS);
    
    if (_myColorRenderBuffer) {
        glBindRenderbuffer(GL_RENDERBUFFER, _myColorRenderBuffer);
    }
    //绘制
    [self.myContext presentRenderbuffer:GL_RENDERBUFFER];
    
    glDeleteVertexArrays(1,&_VAO);
    glDeleteVertexArrays(1, &_blackBoxVAO);
}

反射

折射

这两个等哪天心情好了在写,又懒了,这样不好_

上一篇下一篇

猜你喜欢

热点阅读