立方体贴图

  立方体贴图,也称CubeMap。其实就是一张包含六个面的纹理贴图,一般情况下是加载六张贴图构成cubemap。

  加载代码如下:

void WKS::CubeMap::LoadCubeMap(std::vector<std::string> faces) {
    glGenTextures(1, &this->textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, this->textureID);

    int width, height, nrChannels;
    for (unsigned int i = 0; i < faces.size(); i++) {
        unsigned char* image = SOIL_load_image(faces[i].c_str(), &width, &height, &nrChannels, SOIL_LOAD_RGB);
        if (image) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
        }
        else {
            std::cout << "Cubemap texture failed to load at path: " << faces[i] << std::endl;
        }
        SOIL_free_image_data(image);
    }
    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);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}

  使用cubemap实现天空盒

#pragma once
#include "Model/Texture.h"
#include "Shader.h"
#include "Camera.h"

class SkyBox
{
public:
    SkyBox();
    ~SkyBox();
    void setTexture(std::vector<std::string>);
    void Draw();

private:
    GLuint VAO, VBO;
    GLuint textureID;
    Shader* shader;
    Camera* phc = Camera::getInstance();

private:
    void setup();
};

SkyBox::SkyBox()
{
    setup();
}

SkyBox::~SkyBox()
{
}

void SkyBox::setup() {
    float skyboxVertices[] = {
        // positions
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f,  1.0f
    };
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glBindVertexArray(0);

    shader = new Shader("./Shader/skybox.vert", "./Shader/skybox.frag");
}

void SkyBox::setTexture(std::vector<std::string> faces) {
    WKS::CubeMap cubeMap;
    cubeMap.LoadCubeMap(faces);
    this->textureID = cubeMap.GetTextureID();
}

void SkyBox::Draw() {
    glDepthFunc(GL_LEQUAL);

    this->shader->use();
    glm::mat4 model = glm::scale(glm::mat4(1), glm::vec3(10, 10, 10));
    glm::mat4 view = glm::mat4(glm::mat3(phc->getViewMatrix()));
    this->shader->setMat4("model", model);
    this->shader->setMat4("view", view);
    this->shader->setMat4("projection", phc->getProjectionMatrix());

    glBindTexture(GL_TEXTURE_CUBE_MAP, this->textureID);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
}

  片段着色器中采样纹理

uniform samplerCube skybox;

  效果展示:

  1、反射 - 盒子

  

  2、反射 - nanosuit

  

  3、折射 - nanosuit

  

原文地址:https://www.cnblogs.com/chen9510/p/11431564.html

时间: 2024-08-22 01:16:30

立方体贴图的相关文章

OpenGL+OpenCV实现立方体贴图

我屮艸芔茻,转眼就7月份了. 今天试了一下立方体贴图,比较简单,大概说下和平面贴图的区别. 1. 平面贴图需要的是纹理坐标vec2:立方体贴图需要的是一个方向向量vec3,长度没有关系,重要的是方向,OpenGL会根据方向向量与立方体的各个面的交点来采样纹理. 2.在立方体的六个面贴六张不同的图片,我用的方法是将六张图片读入到OpenCV的Mat数组中,需要从BGR转到RGB,然后一个一个去绑定纹理.此时区别2D纹理的地方在于要是用GL_TEXTURE_CUBE_MAP,而不再是GL_TEXTU

立方体贴图(Cubemap)

http://blog.csdn.net/asdjy123/article/details/51190643 点击打开链接 好东西保存方便查看 立方体贴图(Cubemap) 原文 Cubemaps 作者 JoeyDeVries 翻译 Django 校对 Geequlim 我们之前一直使用的是2D纹理,还有更多的纹理类型我们没有探索过,本教程中我们讨论的纹理类型是将多个纹理组合起来映射到一个单一纹理,它就是cubemap. 基本上说cubemap它包含6个2D纹理,这每个2D纹理是一个立方体(cu

Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用

开始学习第4章 - 着色器的反射 看完了1.2节,来记录一下.反射主要是利用了 Cubemap 立方体贴图. 认识Cubemap 立方体贴图,就如同名字所说,在一个立方体上有6张图,就这样认为吧. 假想一下 ,在一个艳丽的房间里,有一个表面是镜子的圆球,那这个圆球表面就反射了房间里面的所有东西,就是一个大号的凸镜. 这是到网上找得一张图,很直观的表达了我的意思-- 注意标题中说的,静态立方体贴图,为什么叫静态,因为这一次使用的立方体贴图是提前生成好的图片,而不是动态生成的. 这又是什么意思呢?

threejs立方体贴图产生边缘锯齿问题

threejs立方体贴图产生边缘锯齿问题 立方体贴图边缘锯齿 解决后 经过试验测试发现, textureGrass.wrapS和 textureGrass.wrapT属性导致的. 解决方法1: 删掉textureGrass.wrapS和 textureGrass.wrap var textureGrass = new THREE.ImageUtils.loadTexture(src); // 此属性会产生抗锯齿 // 写法1:删除即可 /*textureGrass.wrapS = THREE.R

opengl 一个可以运行的立方体贴图

对于开始学习opengl的人来说 下载一个可以运行的代码,对自己的鼓舞极大,但是网上下载的程序大多数由于这样那样的原因不能运行.有时会抱怨:照抄的啊 咋不行呢?其实原因很简单 主要是环境变了 库配置不对 版本不对 有的库是debug 而有的是release 所以导致不能运行. 下面这个例子是纹理贴图: 图片必须是能被2整除的 比如 128X128  512X512 文件名:MF.bmp 保证你运行而且可以手动控制旋转 ,由于开始贴在正面,所以你看到的是平面.按D键 立即旋转. / fangkua

NGUI字体贴图压缩以及相关Shader解读

一般游戏中,字体贴图是游戏贴图压缩的一个重点,特别是对于中文的游戏.考虑的字体贴图的特殊性,一般我们输出的字体贴图是不含颜色信息的,所以正常情况下,我们输出的字体贴图RGBA每一个通道都是一样的.这样一来,就存在非常大的浪费.所以我们能够在RGBA四个通道中能够保存不同的字体,这样,我们的贴图的大小能够降低4倍.假设我们想使用ETC压缩的话,我们可还以直接不使用Alpha通道,仅仅在RGB三个通道中存储不同的文字(这样,假设我们要进行ETC压缩的话,不须要对Alpha通道做分离处理了,可是得到的

UnityEditor扩展编辑器实现从场景中渲染得到Cubemap

(学习笔记,希望能帮助到有需要的人.) 在自定义的EditorWindow中定义2个变量,分别代表需要渲染的Cubemap 和 视点对象(通常是Camera对象) private Cubemap cubemap; private GameObject obj; 在OnGUI 函数中 <span style="white-space:pre"> </span>this.cubemap = (Cubemap) EditorGUILayout.ObjectField

Bubble更新

本次Bubble引擎的重要更新: 项目重构,创建独立的渲染系统Renderer处理渲染逻辑,Renderer与Graphics交互,Graphics是底层图形API的封装 完善材质系统,区分材质参数和自动参数,自动参数为引擎内置,无需用户指定,引擎自动为其传递参数 完善场景树,完善树节点的插入,删除操作 实现天空盒功能 渲染效果图: 图中分别用不同的方法渲染人头,其中最右边直接使用纹理,其余使用各种材质,依次为:塑料,铜,铬,金. 背景使用了天空盒技术. 天空盒添加方法如下: SkyboxPtr

Unity3D脚本学习——运行时类

AssetBundle 类,继承自Object.AssetBundles让你通过WWW类流式加载额外的资源并在运行时实例化它们.AssetBundles通过BuildPipeline.BuildAssetBundle创建. 参见:WWW.assetBundle ,Loading Resources at Runtime ,BuildPipeline.BuildPlayer function Start () { var www = new WWW ("http://myserver/myBund