mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
improved environment mapping for specular IBL
This commit is contained in:
@@ -17,6 +17,7 @@ namespace vb01{
|
|||||||
inline Vector3 getUp(){return up;}
|
inline Vector3 getUp(){return up;}
|
||||||
inline void setNearPlane(float near){this->nearPlane = near;}
|
inline void setNearPlane(float near){this->nearPlane = near;}
|
||||||
inline void setFarPlane(float far){this->farPlane = far;}
|
inline void setFarPlane(float far){this->farPlane = far;}
|
||||||
|
inline void setFov(float fov){this->fov = fov;}
|
||||||
inline float getFov(){return fov;}
|
inline float getFov(){return fov;}
|
||||||
inline float getNearPlane(){return nearPlane;}
|
inline float getNearPlane(){return nearPlane;}
|
||||||
inline float getFarPlane(){return farPlane;}
|
inline float getFarPlane(){return farPlane;}
|
||||||
|
|||||||
@@ -64,11 +64,13 @@ namespace vb01{
|
|||||||
environmentShader = new Shader(libPath + "environmentPreFilter");
|
environmentShader = new Shader(libPath + "environmentPreFilter");
|
||||||
brdfIntegrationShader = new Shader(libPath + "brdfIntegration");
|
brdfIntegrationShader = new Shader(libPath + "brdfIntegration");
|
||||||
|
|
||||||
environmentMap = new Texture(reflectionSize, false, 5);
|
prefilterMap = new Texture(reflectionSize, false);
|
||||||
|
postfilterMap = new Texture(reflectionSize, false, 5);
|
||||||
brdfIntegrationMap = new Texture(reflectionSize, reflectionSize, false);
|
brdfIntegrationMap = new Texture(reflectionSize, reflectionSize, false);
|
||||||
int width = reflectionSize;
|
int width = reflectionSize;
|
||||||
|
|
||||||
initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, reflectionSize);
|
initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, reflectionSize);
|
||||||
|
initFramebuffer(postFilterFramebuffer, postFilterRenderbuffer, reflectionSize);
|
||||||
initFramebuffer(brdfFramebuffer, brdfRenderbuffer, reflectionSize);
|
initFramebuffer(brdfFramebuffer, brdfRenderbuffer, reflectionSize);
|
||||||
|
|
||||||
initMesh();
|
initMesh();
|
||||||
@@ -87,7 +89,7 @@ namespace vb01{
|
|||||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
cout << "Mesh framebuffer not complete\n";
|
cout << "Mesh framebuffer not complete\n";
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, *Root::getSingleton()->getFBO());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::initMesh(){
|
void Mesh::initMesh(){
|
||||||
@@ -241,7 +243,7 @@ namespace vb01{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::updatePrefilterMap(Vector3 pos){
|
void Mesh::updatePrefilterMap(Vector3 pos, mat4 &proj, vec3 dirs[6]){
|
||||||
/*
|
/*
|
||||||
Node *rootNode = root->getRootNode();
|
Node *rootNode = root->getRootNode();
|
||||||
vector<Node*> descendants;
|
vector<Node*> descendants;
|
||||||
@@ -274,23 +276,50 @@ namespace vb01{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, preFilterFramebuffer);
|
||||||
|
|
||||||
|
glViewport(0, 0, reflectionSize, reflectionSize);
|
||||||
|
|
||||||
Root *root = Root::getSingleton();
|
Root *root = Root::getSingleton();
|
||||||
Mesh *skybox = root->getSkybox();
|
Mesh *skybox = root->getSkybox();
|
||||||
Texture *skyboxTex = ((Material::TextureUniform*)skybox->getMaterial()->getUniform("skybox"))->value;
|
Material *mat = skybox->getMaterial();
|
||||||
|
mat->update();
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, preFilterFramebuffer);
|
Shader *shader = mat->getShader();
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, preFilterRenderbuffer);
|
shader->setMat4(proj, "proj");
|
||||||
|
|
||||||
|
for(int i = 0; i < 6; i++){
|
||||||
|
vec3 upVec = (fabs(dirs[i].y) == 1 ? vec3(0, 0, -1) : vec3(0, 1, 0));
|
||||||
|
shader->setMat4(lookAt(vec3(0.0), dirs[i], upVec), "view");
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, *prefilterMap->getTexture(), 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
if(skybox) {
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
glCullFace(GL_FRONT);
|
||||||
|
skybox->render();
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, *root->getFBO());
|
||||||
|
glViewport(0, 0, root->getWidth(), root->getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::updatePostfilterMap(mat4 &proj, vec3 dirs[6]){
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, postFilterFramebuffer);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, postFilterRenderbuffer);
|
||||||
|
|
||||||
skyboxTex->select();
|
|
||||||
|
|
||||||
environmentShader->use();
|
environmentShader->use();
|
||||||
environmentShader->setInt(0, "environmentMap");
|
|
||||||
mat4 proj = perspective(radians(90.f), 1.f, .1f, 100.f);
|
|
||||||
environmentShader->setMat4(proj, "proj");
|
environmentShader->setMat4(proj, "proj");
|
||||||
environmentShader->setMat4(mat4(1.f), "model");
|
environmentShader->setInt(0, "environmentMap");
|
||||||
|
|
||||||
int numMipmaps = environmentMap->getMipmapLevel();
|
prefilterMap->select(0);
|
||||||
vec3 dirs[]{vec3(1, 0, 0), vec3(-1, 0, 0), vec3(0, 1, 0), vec3(0, -1, 0), vec3(0, 0, 1), vec3(0, 0, -1)};
|
|
||||||
|
Root *root = Root::getSingleton();
|
||||||
|
int numMipmaps = postfilterMap->getMipmapLevel();
|
||||||
|
|
||||||
for(int i = 0; i < numMipmaps; ++i){
|
for(int i = 0; i < numMipmaps; ++i){
|
||||||
u32 width = reflectionSize * pow(0.5, i);
|
u32 width = reflectionSize * pow(0.5, i);
|
||||||
@@ -300,15 +329,17 @@ namespace vb01{
|
|||||||
environmentShader->setFloat((float)i / numMipmaps, "roughness");
|
environmentShader->setFloat((float)i / numMipmaps, "roughness");
|
||||||
|
|
||||||
for(int j = 0; j < 6; j++){
|
for(int j = 0; j < 6; j++){
|
||||||
vec3 v = vec3(pos.x, pos.y, pos.z);
|
|
||||||
vec3 upVec = (fabs(dirs[j].y) == 1 ? vec3(0, 0, -1) : vec3(0, 1, 0));
|
vec3 upVec = (fabs(dirs[j].y) == 1 ? vec3(0, 0, -1) : vec3(0, 1, 0));
|
||||||
environmentShader->setMat4(lookAt(v, v + dirs[j], upVec), "view");
|
environmentShader->setMat4(lookAt(vec3(0.0), dirs[j], upVec), "view");
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, *environmentMap->getTexture(), i);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, *postfilterMap->getTexture(), i);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
if(skybox)
|
glDepthMask(GL_FALSE);
|
||||||
skybox->render();
|
glCullFace(GL_FRONT);
|
||||||
|
root->getPostfilterBox()->render();
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +367,11 @@ namespace vb01{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::updateReflection(Vector3 pos){
|
void Mesh::updateReflection(Vector3 pos){
|
||||||
updatePrefilterMap(pos);
|
vec3 dirs[]{ vec3(1, 0, 0), vec3(-1, 0, 0), vec3(0, 1, 0), vec3(0, -1, 0), vec3(0, 0, 1), vec3(0, 0, -1) };
|
||||||
|
mat4 proj = perspective(radians(90.f), 1.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
updatePrefilterMap(pos, proj, dirs);
|
||||||
|
updatePostfilterMap(proj, dirs);
|
||||||
updateBrdfLut();
|
updateBrdfLut();
|
||||||
|
|
||||||
Shader *shader = material->getShader();
|
Shader *shader = material->getShader();
|
||||||
@@ -347,7 +382,7 @@ namespace vb01{
|
|||||||
shader->setInt(preFilterId, "preFilterMap");
|
shader->setInt(preFilterId, "preFilterMap");
|
||||||
shader->setInt(brdfId, "brdfIntegrationMap");
|
shader->setInt(brdfId, "brdfIntegrationMap");
|
||||||
|
|
||||||
environmentMap->select(preFilterId);
|
postfilterMap->select(preFilterId);
|
||||||
brdfIntegrationMap->select(brdfId);
|
brdfIntegrationMap->select(brdfId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,21 +57,23 @@ namespace vb01{
|
|||||||
inline u32* getIndices(){return indices;}
|
inline u32* getIndices(){return indices;}
|
||||||
inline ShapeKey& getShapeKey(int i){return shapeKeys[i];}
|
inline ShapeKey& getShapeKey(int i){return shapeKeys[i];}
|
||||||
inline int getNumShapeKeys(){return numShapeKeys;}
|
inline int getNumShapeKeys(){return numShapeKeys;}
|
||||||
inline Texture* getEnvironmentMap(){return environmentMap;}
|
inline Texture* getPrefilterMap(){return prefilterMap;}
|
||||||
|
inline Texture* getPostfilterMap(){return postfilterMap;}
|
||||||
inline Texture* getBrdfIntegrationMap(){return brdfIntegrationMap;}
|
inline Texture* getBrdfIntegrationMap(){return brdfIntegrationMap;}
|
||||||
private:
|
private:
|
||||||
void initMesh();
|
void initMesh();
|
||||||
void initFramebuffer(u32&, u32&, int);
|
void initFramebuffer(u32&, u32&, int);
|
||||||
void updateSkeleton(Shader*);
|
void updateSkeleton(Shader*);
|
||||||
void updatePrefilterMap(Vector3);
|
void updatePrefilterMap(Vector3, glm::mat4&, glm::vec3[6]);
|
||||||
|
void updatePostfilterMap(glm::mat4&, glm::vec3[6]);
|
||||||
void updateBrdfLut();
|
void updateBrdfLut();
|
||||||
void updateReflection(Vector3);
|
void updateReflection(Vector3);
|
||||||
void updateShapeKeys(Shader*);
|
void updateShapeKeys(Shader*);
|
||||||
|
|
||||||
int reflectionSize = 512;
|
int reflectionSize = 512;
|
||||||
Texture *environmentMap = nullptr, *brdfIntegrationMap = nullptr;
|
Texture *prefilterMap = nullptr, *postfilterMap = nullptr, *brdfIntegrationMap = nullptr;
|
||||||
Shader *environmentShader = nullptr, *brdfIntegrationShader = nullptr;
|
Shader *environmentShader = nullptr, *brdfIntegrationShader = nullptr;
|
||||||
u32 preFilterFramebuffer, preFilterRenderbuffer, brdfFramebuffer, brdfRenderbuffer;
|
u32 preFilterFramebuffer, preFilterRenderbuffer, postFilterFramebuffer, postFilterRenderbuffer, brdfFramebuffer, brdfRenderbuffer;
|
||||||
Material *material = nullptr;
|
Material *material = nullptr;
|
||||||
Node *node = nullptr;
|
Node *node = nullptr;
|
||||||
std::vector<Mesh*> meshes;
|
std::vector<Mesh*> meshes;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "glad.h"
|
#include "glad.h"
|
||||||
#include <glfw3.h>
|
#include <glfw3.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -46,6 +47,7 @@ namespace vb01{
|
|||||||
initWindow(name);
|
initWindow(name);
|
||||||
|
|
||||||
brdfLutPlane = new Quad(Vector3::VEC_IJK);
|
brdfLutPlane = new Quad(Vector3::VEC_IJK);
|
||||||
|
postfilterBox = new Box(Vector3::VEC_IJK);
|
||||||
|
|
||||||
Texture *fragTexture = new Texture(width, height, false);
|
Texture *fragTexture = new Texture(width, height, false);
|
||||||
Texture *brightTexture = new Texture(width, height, false);
|
Texture *brightTexture = new Texture(width, height, false);
|
||||||
@@ -57,19 +59,25 @@ namespace vb01{
|
|||||||
|
|
||||||
void Root::initWindow(string name){
|
void Root::initWindow(string name){
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
if (GL_TRUE != glfwInit())
|
if (GL_TRUE != glfwInit())
|
||||||
std::cerr << "Error initialising glfw" << std::endl;
|
std::cerr << "Error initialising glfw" << std::endl;
|
||||||
|
|
||||||
window = glfwCreateWindow(width, height, name.c_str(), NULL, NULL);
|
window = glfwCreateWindow(width, height, name.c_str(), NULL, NULL);
|
||||||
|
|
||||||
if(window == NULL){
|
if(window == NULL){
|
||||||
cout << "Failed to load window...\n";
|
cout << "Failed to load window...\n";
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSetFramebufferSizeCallback(window, foo);
|
glfwSetFramebufferSizeCallback(window, foo);
|
||||||
|
|
||||||
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
|
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
|
||||||
cout << "Failed to load GLAD.\n";
|
cout << "Failed to load GLAD.\n";
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
@@ -92,8 +100,8 @@ namespace vb01{
|
|||||||
|
|
||||||
glGenRenderbuffers(1, &RBO);
|
glGenRenderbuffers(1, &RBO);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, RBO);
|
glBindRenderbuffer(GL_RENDERBUFFER, RBO);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RBO);
|
||||||
|
|
||||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
cout << "Not complete\n";
|
cout << "Not complete\n";
|
||||||
@@ -199,7 +207,7 @@ namespace vb01{
|
|||||||
skybox = new Box(Vector3(1, 1, 1) * 10);
|
skybox = new Box(Vector3(1, 1, 1) * 10);
|
||||||
Material *skyboxMat = new Material(libPath + "skybox");
|
Material *skyboxMat = new Material(libPath + "skybox");
|
||||||
Texture *texture = new Texture(paths, 6, true);
|
Texture *texture = new Texture(paths, 6, true);
|
||||||
skyboxMat->addTexUniform("skybox", texture, true);
|
skyboxMat->addTexUniform("tex", texture, true);
|
||||||
skybox->setMaterial(skyboxMat);
|
skybox->setMaterial(skyboxMat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ namespace vb01{
|
|||||||
inline Node* getGuiNode(){return guiNode;}
|
inline Node* getGuiNode(){return guiNode;}
|
||||||
inline int getWidth(){return width;}
|
inline int getWidth(){return width;}
|
||||||
inline int getHeight(){return height;}
|
inline int getHeight(){return height;}
|
||||||
inline unsigned int* getFBO(){return &FBO;}
|
inline u32* getFBO(){return &FBO;}
|
||||||
|
inline u32* getRBO(){return &RBO;}
|
||||||
inline GLFWwindow* getWindow(){return window;}
|
inline GLFWwindow* getWindow(){return window;}
|
||||||
inline void setHDREnabled(bool hdr){this->hdr = hdr;}
|
inline void setHDREnabled(bool hdr){this->hdr = hdr;}
|
||||||
inline void setExposure(float exposure){this->exposure = exposure;}
|
inline void setExposure(float exposure){this->exposure = exposure;}
|
||||||
@@ -36,6 +37,7 @@ namespace vb01{
|
|||||||
inline void setBloom(bool bloom){this->bloom = bloom;}
|
inline void setBloom(bool bloom){this->bloom = bloom;}
|
||||||
inline void setBlurLevel(bool level){this->blurLevel = level;}
|
inline void setBlurLevel(bool level){this->blurLevel = level;}
|
||||||
inline Box* getSkybox(){return skybox;}
|
inline Box* getSkybox(){return skybox;}
|
||||||
|
inline Box* getPostfilterBox(){return postfilterBox;}
|
||||||
inline Quad* getBrdfLutPlane(){return brdfLutPlane;}
|
inline Quad* getBrdfLutPlane(){return brdfLutPlane;}
|
||||||
void createSkybox(std::string[6]);
|
void createSkybox(std::string[6]);
|
||||||
void removeSkybox();
|
void removeSkybox();
|
||||||
@@ -47,7 +49,7 @@ namespace vb01{
|
|||||||
int numLights = 0;
|
int numLights = 0;
|
||||||
bool bloom = false, hdr = false;
|
bool bloom = false, hdr = false;
|
||||||
float exposure = 1, gamma = 1;
|
float exposure = 1, gamma = 1;
|
||||||
Box *skybox = nullptr;
|
Box *skybox = nullptr, *postfilterBox = nullptr;
|
||||||
Quad *guiPlane = nullptr, *brdfLutPlane = nullptr;
|
Quad *guiPlane = nullptr, *brdfLutPlane = nullptr;
|
||||||
int width, height, blurLevel = 10;
|
int width, height, blurLevel = 10;
|
||||||
u32 FBO, RBO, pingpongBuffers[2];
|
u32 FBO, RBO, pingpongBuffers[2];
|
||||||
|
|||||||
+3
-3
@@ -41,7 +41,6 @@ namespace vb01{
|
|||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(string paths[], int numPaths, bool cubemap, int mipmapLevel, bool flip){
|
Texture::Texture(string paths[], int numPaths, bool cubemap, int mipmapLevel, bool flip){
|
||||||
this->numFrames = numPaths;
|
|
||||||
this->cubemap = cubemap;
|
this->cubemap = cubemap;
|
||||||
this->paths = new string[numPaths];
|
this->paths = new string[numPaths];
|
||||||
|
|
||||||
@@ -53,6 +52,7 @@ namespace vb01{
|
|||||||
createCubemap(false, flip, true);
|
createCubemap(false, flip, true);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
this->numFrames = numPaths;
|
||||||
texture = new u32[numPaths];
|
texture = new u32[numPaths];
|
||||||
create2DTexture(flip);
|
create2DTexture(flip);
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ namespace vb01{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, width, 0, GL_RGB, GL_FLOAT, NULL);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_INT, NULL);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, width, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, width, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||||
@@ -126,7 +126,7 @@ namespace vb01{
|
|||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
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_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
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_MAG_FILTER, GL_LINEAR);
|
||||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user