added serialisation of texture to png with lodepng

This commit is contained in:
Anselme 2016-06-15 16:09:11 +02:00
parent 7c139a576a
commit 5eef43156b
14 changed files with 8150 additions and 170 deletions

View File

@ -11,10 +11,10 @@ flat in int instanceId;
uniform sampler2D alphaMask;
#endif
#ifdef AMBIENT_TEXTURE
uniform sampler2D ambientTexture;
#ifdef EMISSION_TEXTURE
uniform sampler2D emissionTexture;
#else
uniform vec3 materialKa;
uniform vec3 materialEmission;
#endif
#ifdef DIFFUSE_TEXTURE
@ -93,10 +93,10 @@ void main(void) {
vec3 normal = normalize(varNormal);
#endif
#ifdef AMBIENT_TEXTURE
vec3 ambient = texture(ambientTexture, varTexCoord).rgb;
#ifdef EMISSION_TEXTURE
vec3 emission = texture(emissionTexture, varTexCoord).rgb;
#else
vec3 ambient = materialKa;
vec3 emission = materialEmission;
#endif
#ifdef DIFFUSE_TEXTURE

View File

@ -1,61 +0,0 @@
layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec4 outColor;
layout (location = 2) out vec4 outSpecular;
uniform float materialNs;
uniform int objectId;
#ifdef ALPHA_MASK
uniform sampler2D alphaMask;
#endif
#ifdef DIFFUSE_TEXTURE
uniform sampler2D diffuseTexture;
#else
uniform vec3 materialKd;
#endif
#ifdef SPECULAR_TEXTURE
uniform sampler2D specularTexture;
#else
uniform vec3 materialKs;
#endif
#ifdef NORMAL_MAP
uniform sampler2D normalMap;
in mat3 tangentSpace;
#else
in vec3 varNormal;
#endif
in vec2 varTexCoord;
void main()
{
#ifdef ALPHA_MASK
if(texture(alphaMask, varTexCoord).r < 0.5)
discard;
#endif
#ifdef NORMAL_MAP
vec3 varNormal = texture(normalMap, varTexCoord).xyz * tangentSpace;
#endif
outNormal = normalize(varNormal);
#ifdef DIFFUSE_TEXTURE
outColor.rgb = texture(diffuseTexture, varTexCoord).rgb;
#else
outColor.rgb = materialKd;
#endif
outColor.a = materialNs;
#ifdef SPECULAR_TEXTURE
outSpecular.rgb = texture(specularTexture, varTexCoord).rgb;
#else
outSpecular.rgb = materialKs;
#endif
outSpecular.a = objectId;
}

View File

@ -1,36 +0,0 @@
#ifdef NORMAL_MAP
out mat3 tangentSpace;
#else
out vec3 varNormal;
#endif
out vec2 varTexCoord;
// Matrices
uniform mat4 modelViewMatrix;
uniform mat4 MVP;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;
layout(location = 0)in vec3 inPosition;
layout(location = 1)in vec2 inTexCoord;
layout(location = 2)in vec3 inNormal;
#ifdef NORMAL_MAP
layout(location = 3)in vec3 inTangent;
layout(location = 4)in vec3 inBinormal;
#endif
void main(void)
{
#ifdef NORMAL_MAP
tangentSpace = mat3(normalize(normalMatrix*inNormal),
normalize(normalMatrix*inTangent),
normalize(normalMatrix*inBinormal));
#else
varNormal = normalize(normalMatrix*inNormal);
#endif
varTexCoord = inTexCoord.xy;
gl_Position = MVP * vec4(inPosition, 1.0);
}

69
src/image.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "image.h"
#include <glm/gtc/noise.hpp>
#include "lodepng.h"
Image::Image(int myDepth, int myWidth, int myHeight, float frequency, float amplitude) :
width(myWidth),
height(myHeight),
depth(myDepth)
{
allocate(width * height * (depth/8));
unsigned char* data = pixels.data();
float xFactor = 1.0f / (width - 1);
float yFactor = 1.0f / (height - 1);
for( int row = 0; row < height; row++ ) {
for( int col = 0 ; col < width; col++ ) {
float x = xFactor * col;
float y = yFactor * row;
float sum = 0.0f;
float freq = frequency;
float scale = amplitude;
// Compute the sum for each octave
for( int oct = 0; oct < 4 ; oct++ ) {
glm::vec2 p(x * freq, y * freq);
float val = glm::perlin(p, glm::vec2(freq)) / scale;
sum += val;
float result = (sum + 1.0f)/ 2.0f;
// Store in texture buffer
data[((row * width + col) * (depth/8)) + oct] =
(unsigned char) ( result * 255.0f );
freq *= 2.0f; // Double the frequency
scale *= amplitude; // Next power of b
}
}
}
}
Image::Image(const std::string &pngFile)
{
unsigned int w, h;
unsigned error = lodepng::decode(pixels, w, h, pngFile);
if(error)
fprintf(stderr, lodepng_error_text(error));
else
{
width = w;
height = h;
depth = pixels.size()*8/(width*height);
}
}
bool Image::save(const std::string &filename)
{
LodePNGColorType colorType;
switch(depth)
{
case 32: colorType = LCT_RGBA; break;
case 24: colorType = LCT_RGB; break;
case 8: colorType = LCT_GREY; break;
default: return false; break;
}
unsigned error = lodepng::encode(filename, pixels.data(), width, height, colorType, 8);
if(error)
fprintf(stderr, lodepng_error_text(error));
return error != 0;
}

View File

@ -1,64 +1,26 @@
#ifndef IMAGE
#define IMAGE
#include <cstddef>
#include <glm/gtc/noise.hpp>
#include <string>
#include <vector>
struct Image
{
int width;
int height;
int depth;
void* pixels;
std::vector<unsigned char> pixels;
Image() : pixels(NULL) {}
Image() : width(0), height(0), depth(8) {}
Image(int myDepth, int myWidth, int myHeight, float frequency, float amplitude) :
width(myWidth),
height(myHeight),
depth(myDepth)
{
allocate(width * height * (depth/8));
unsigned char* data = (unsigned char*)pixels;
Image(int myDepth, int myWidth, int myHeight, float frequency, float amplitude);
float xFactor = 1.0f / (width - 1);
float yFactor = 1.0f / (height - 1);
for( int row = 0; row < height; row++ ) {
for( int col = 0 ; col < width; col++ ) {
float x = xFactor * col;
float y = yFactor * row;
float sum = 0.0f;
float freq = frequency;
float scale = amplitude;
// Compute the sum for each octave
for( int oct = 0; oct < 4 ; oct++ ) {
glm::vec2 p(x * freq, y * freq);
float val = glm::perlin(p, glm::vec2(freq)) / scale;
sum += val;
float result = (sum + 1.0f)/ 2.0f;
// Store in texture buffer
data[((row * width + col) * (depth/8)) + oct] =
(unsigned char) ( result * 255.0f );
freq *= 2.0f; // Double the frequency
scale *= amplitude; // Next power of b
}
}
}
}
~Image()
{
if(pixels != NULL)
delete[] (char*)pixels;
}
Image(const std::string &pngFile);
void allocate(int size)
{
pixels = new char[size];
}
{ pixels.resize(size); }
bool save(const std::string &filename);
};
#endif // IMAGE

6224
src/lodepng.cpp Normal file

File diff suppressed because it is too large Load Diff

1759
src/lodepng.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
"PHONG",
"DIFFUSE_TEXTURE",
"AMBIENT_TEXTURE",
"EMISSION_TEXTURE",
"SPECULAR_TEXTURE",
"NORMAL_MAP",

View File

@ -42,7 +42,7 @@ public:
// 3D phong material
MATERIAL_PHONG,
MATERIAL_PHONG_DIFFUSE_TEXTURE,
MATERIAL_PHONG_AMBIENT_TEXTURE,
MATERIAL_PHONG_EMISSION_TEXTURE,
MATERIAL_PHONG_SPECULAR_TEXTURE,
MATERIAL_PHONG_NORMAL_MAP,

View File

@ -17,13 +17,13 @@ void PhongMaterial::bindAttributes(Shader* myShader)
myShader->bindInteger(myShader->getLocation("normalMap"), NORMALS_SLOT);
}
if(ambient_texture != NULL)
if(emission_texture != NULL)
{
ambient_texture->bind(AMBIENT_SLOT);
myShader->bindInteger(myShader->getLocation("ambientTexture"), AMBIENT_SLOT);
emission_texture->bind(EMISSION_SLOT);
myShader->bindInteger(myShader->getLocation("emissionTexture"), EMISSION_SLOT);
}
else
myShader->bindVec3(myShader->getLocation("materialKa"), ambient);
myShader->bindVec3(myShader->getLocation("materialEmission"), emission);
if(diffuse_texture != NULL)
{
@ -53,8 +53,8 @@ unsigned int PhongMaterial::getFlags()
unsigned int flags = 1 << Mesh::MATERIAL_PHONG;
if(normal_map != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_NORMAL_MAP;
if(ambient_texture != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_AMBIENT_TEXTURE;
if(emission_texture != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_EMISSION_TEXTURE;
if(diffuse_texture != NULL)
flags |= 1 << Mesh::MATERIAL_PHONG_DIFFUSE_TEXTURE;
if(specular_texture != NULL)

View File

@ -8,12 +8,11 @@ class Texture;
struct PhongMaterial : public Material
{
glm::vec3 ambient;
glm::vec3 emission;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
bool castShadow;
Texture* ambient_texture;
Texture* emission_texture;
Texture* diffuse_texture;
Texture* specular_texture;
Texture* normal_map;
@ -22,7 +21,7 @@ struct PhongMaterial : public Material
enum TextureSlots
{
DIFFUSE_SLOT,
AMBIENT_SLOT,
EMISSION_SLOT,
NORMALS_SLOT,
SPECULAR_SLOT,
ALPHA_SLOT,
@ -30,12 +29,11 @@ struct PhongMaterial : public Material
};
PhongMaterial() :
ambient(0),
emission(0),
diffuse(0.5f),
specular(0.5f),
shininess(10),
castShadow(true),
ambient_texture(NULL),
emission_texture(NULL),
diffuse_texture(NULL),
specular_texture(NULL),
normal_map(NULL),

View File

@ -5,6 +5,7 @@
#include "mesh.h"
#include "light.h"
#include "texture.h"
#include "phongmaterial.h"
namespace serializers
{
@ -20,12 +21,15 @@ struct MeshHeader
int nbIndices;
};
struct LightHeader
struct MaterialHeader
{
glm::vec3 emission;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
};
struct TextureHeader
struct LightHeader
{
};
@ -36,6 +40,10 @@ bool serializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file);
bool deserializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file);
bool serializeMaterial(Material* material, FILE *file);
Material* deserializeMaterial(FILE *file);
template<typename T>
bool writeBuffer(const std::vector<T> &vec, std::FILE *file);
@ -137,6 +145,25 @@ bool serializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
return true;
}
bool serializeMaterial(Material* material, FILE *file)
{
unsigned int flags = material->getFlags();
if(!fwrite(&flags, sizeof(unsigned int), 1, file))
return false;
if(flags & (1 << Mesh::MATERIAL_PHONG))
{
MaterialHeader header;
PhongMaterial *mat = (PhongMaterial*)material;
header.emission = mat->emission;
header.diffuse = mat->diffuse;
header.specular = mat->specular;
header.shininess = mat->shininess;
}
return true;
}
bool saveLight(const std::string &filename, Light *light)
{
std::FILE *file = std::fopen(filename.c_str(), "w");
@ -230,6 +257,12 @@ bool deserializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
return true;
}
Material* deserializeMaterial(FILE *file)
{
}
Light* loadLight(const std::string &filename)
{

View File

@ -119,7 +119,7 @@ void Texture::initPixels(Image* myImage, GLenum target)
m_internal_format = GL_R8;
break;
}
glTexImage2D(target, 0, m_internal_format, m_width, m_height, 0, m_format, m_dataType, myImage->pixels);
glTexImage2D(target, 0, m_internal_format, m_width, m_height, 0, m_format, m_dataType, myImage->pixels.data());
}
void Texture::setWrap(GLint wrap)
@ -161,3 +161,33 @@ void Texture::unbind()
glActiveTexture(GL_TEXTURE0+m_texUnit);
glBindTexture(m_target, 0);
}
Image* Texture::getData()
{
bind();
int nbVal;
int nbImages;
switch(m_format)
{
case GL_RGBA: nbVal = 4; break;
case GL_RGB: nbVal = 3; break;
case GL_RED: nbVal = 1; break;
default: return NULL;
}
switch(m_target)
{
case GL_TEXTURE_CUBE_MAP: nbImages = 6; break;
case GL_TEXTURE_2D_ARRAY: nbImages = 3; break; // TODO : add a member specifying how many layers has the texture
default: nbImages = 1; break;
}
int size = nbVal*m_width*m_height*nbImages;
Image *img = new Image();
img->depth = nbVal*8;
img->height = m_height;
img->width = m_width;
img->allocate(size);
glGetTexImage(m_target, 0, m_format, GL_UNSIGNED_BYTE, img->pixels.data());
return img;
}

View File

@ -52,6 +52,8 @@ public:
int getWidth() {return m_width;}
int getHeight() {return m_height;}
Image* getData();
};
#endif // TEXTURE_H