mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-03-02 21:45:25 +00:00
Fix texture management
This commit is contained in:
@ -1,60 +0,0 @@
|
||||
#ifndef HLSLTRANSLATOR_CPP_
|
||||
#define HLSLTRANSLATOR_CPP_
|
||||
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "HLSLTranslator.hpp"
|
||||
|
||||
using namespace M4;
|
||||
|
||||
|
||||
std::string HLSLTranslator::parse(const std::string & shaderType, const char *fileName, const std::string &fullSource) {
|
||||
// alloc
|
||||
GLSLGenerator generator;
|
||||
Allocator allocator;
|
||||
|
||||
HLSLTree tree( &allocator );
|
||||
HLSLParser parser(&allocator, &tree);
|
||||
|
||||
// preprocess define macros
|
||||
std::string sourcePreprocessed;
|
||||
parser.ApplyPreprocessor(fileName, fullSource.c_str(), fullSource.size(), sourcePreprocessed);
|
||||
|
||||
// parse
|
||||
if( !parser.Parse(fileName, sourcePreprocessed.c_str(), sourcePreprocessed.size()) ) {
|
||||
std::cerr << "Failed to parse HLSL (" << shaderType << ") shader" << std::endl;
|
||||
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source: " << std::endl << sourcePreprocessed << std::endl;
|
||||
#else
|
||||
std::ofstream out("/tmp/shader_" + shaderType + ".txt");
|
||||
out << fullSource;
|
||||
out.close();
|
||||
|
||||
std::ofstream out2("/tmp/shader_preproc_" + shaderType + ".txt");
|
||||
out2 << sourcePreprocessed;
|
||||
out2.close();
|
||||
#endif
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// generate GLSL
|
||||
if (!generator.Generate(&tree, GLSLGenerator::Target_FragmentShader, GLSLGenerator::Version_140, "PS")) {
|
||||
std::cerr << "Failed to transpile HLSL (" << shaderType << ") shader to GLSL" << std::endl;
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source: " << std::endl << sourcePreprocessed << std::endl;
|
||||
#else
|
||||
std::ofstream out2("/tmp/shader_preproc_" + shaderType + ".txt");
|
||||
out2 << sourcePreprocessed;
|
||||
out2.close();
|
||||
#endif
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return std::string(generator.GetResult());
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* HLSLTranslator
|
||||
*
|
||||
* Translate HLSL (aka directX shader lang) to GLSL.
|
||||
* Needed because the presets all contain directX-style shaders, and we want GLSL so we can run on things that aren't windows computers.
|
||||
*
|
||||
* Also worth looking into generating SPIR-V for Vulkan support, someday.
|
||||
*
|
||||
* Created on: May 27, 2018
|
||||
* Author: mischa spiegelmock
|
||||
*
|
||||
* actual conversion is done by: https://github.com/Thekla/hlslparser
|
||||
*/
|
||||
|
||||
#ifndef HLSLTRANSLATOR_HPP_
|
||||
#define HLSLTRANSLATOR_HPP_
|
||||
|
||||
#include "Common.hpp"
|
||||
#include "projectM-opengl.h"
|
||||
#include "HLSLParser.h"
|
||||
#include "GLSLGenerator.h"
|
||||
#include <sys/types.h>
|
||||
#include "projectM-opengl.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
|
||||
class HLSLTranslator {
|
||||
public:
|
||||
std::string parse(const std::string & shaderType, const char *fileName, const std::string &fullSource);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -43,8 +43,7 @@ libRenderer_la_SOURCES = \
|
||||
hlslparser/src/CodeWriter.h hlslparser/src/GLSLGenerator.cpp \
|
||||
hlslparser/src/HLSLTokenizer.cpp hlslparser/src/HLSLTree.h \
|
||||
hlslparser/src/Engine.cpp hlslparser/src/GLSLGenerator.h hlslparser/src/HLSLParser.cpp \
|
||||
hlslparser/src/HLSLTokenizer.h \
|
||||
HLSLTranslator.cpp HLSLTranslator.hpp
|
||||
hlslparser/src/HLSLTokenizer.h
|
||||
|
||||
libRenderer_la_CPPFLAGS = ${my_CFLAGS} \
|
||||
-include $(top_builddir)/config.h \
|
||||
|
||||
@ -9,10 +9,13 @@
|
||||
#include "ShaderEngine.hpp"
|
||||
#include "BeatDetect.hpp"
|
||||
#include "Texture.hpp"
|
||||
#include "HLSLTranslator.hpp"
|
||||
#include "HLSLParser.h"
|
||||
#include "GLSLGenerator.h"
|
||||
#include <glm/mat4x4.hpp> // glm::mat4
|
||||
#include <glm/gtc/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <set>
|
||||
#include <regex>
|
||||
|
||||
#ifdef USE_GLES
|
||||
#define GLSL_VERSION "300 es"
|
||||
@ -255,12 +258,6 @@ std::string PresetShaderIncludes = ""
|
||||
"#define blur3_min _c13.z\n"
|
||||
"#define blur3_max _c13.w\n"
|
||||
|
||||
"// previous-frame-image samplers:\n"
|
||||
"uniform sampler2D sampler_main;\n"
|
||||
"uniform sampler2D sampler_fc_main;\n"
|
||||
"uniform sampler2D sampler_pc_main;\n"
|
||||
"uniform sampler2D sampler_fw_main;\n"
|
||||
"uniform sampler2D sampler_pw_main;\n"
|
||||
"#define sampler_FC_main sampler_fc_main\n"
|
||||
"#define sampler_PC_main sampler_pc_main\n"
|
||||
"#define sampler_FW_main sampler_fw_main\n"
|
||||
@ -275,27 +272,6 @@ std::string PresetShaderIncludes = ""
|
||||
"#define lum(x) (dot(x,float3(0.32,0.49,0.29)))\n"
|
||||
"#define tex2d tex2D\n"
|
||||
"#define tex3d tex3D\n"
|
||||
|
||||
|
||||
|
||||
"// built-in noise textures:\n"
|
||||
"uniform sampler2D sampler_noise_lq;\n"
|
||||
"uniform sampler2D sampler_noise_lq_lite;\n"
|
||||
"uniform sampler2D sampler_noise_mq;\n"
|
||||
"uniform sampler2D sampler_noise_hq;\n"
|
||||
"uniform sampler3D sampler_noisevol_lq;\n"
|
||||
"uniform sampler3D sampler_noisevol_hq;\n"
|
||||
"uniform float4 texsize_noise_lq;\n"
|
||||
"uniform float4 texsize_noise_lq_lite;\n"
|
||||
"uniform float4 texsize_noise_mq;\n"
|
||||
"uniform float4 texsize_noise_hq;\n"
|
||||
"uniform float4 texsize_noisevol_lq;\n"
|
||||
"uniform float4 texsize_noisevol_hq;\n"
|
||||
|
||||
"// procedural blur textures:\n"
|
||||
"uniform sampler2D sampler_blur1;\n"
|
||||
"uniform sampler2D sampler_blur2;\n"
|
||||
"uniform sampler2D sampler_blur3;\n"
|
||||
;
|
||||
|
||||
|
||||
@ -543,7 +519,6 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
|
||||
// replace shader_body with entry point function
|
||||
found = program.find("shader_body");
|
||||
size_t program_start = found;
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
//std::cout << "first 'shader_body' found at: " << int(found) << std::endl;
|
||||
@ -573,6 +548,23 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
|
||||
pmShader.textures.clear();
|
||||
|
||||
|
||||
// Add builtin textures
|
||||
pmShader.textures["main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR);
|
||||
pmShader.textures["fc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["pc_main"] = textureManager->getTexture("main", GL_CLAMP_TO_EDGE, GL_NEAREST);
|
||||
pmShader.textures["fw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR);
|
||||
pmShader.textures["pw_main"] = textureManager->getTexture("main", GL_REPEAT, GL_NEAREST);
|
||||
|
||||
pmShader.textures["noise_lq"] = textureManager->getTexture("noise_lq", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["noise_lq_lite"] = textureManager->getTexture("noise_lq_lite", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["noise_mq"] = textureManager->getTexture("noise_mq", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["noise_hq"] = textureManager->getTexture("noise_hq", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["noisevol_lq"] = textureManager->getTexture("noisevol_lq", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["noisevol_hq"] = textureManager->getTexture("noisevol_hq", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
|
||||
|
||||
|
||||
// set up texture samplers for all samplers references in the shader program
|
||||
found = 0;
|
||||
found = program.find("sampler_", found);
|
||||
@ -591,13 +583,9 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
|
||||
if (texDesc.first == NULL)
|
||||
{
|
||||
if (lowerCaseName.substr(0, 4) == "rand")
|
||||
if (lowerCaseName.substr(0, 4) == "rand" || lowerCaseName.substr(2, 5) == "_rand")
|
||||
{
|
||||
std::string random_name = textureManager->getRandomTextureName(lowerCaseName);
|
||||
if (random_name.size() > 0)
|
||||
{
|
||||
texDesc = textureManager->getTexture(random_name, GL_REPEAT, GL_LINEAR);
|
||||
}
|
||||
texDesc = textureManager->getRandomTextureName(sampler);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -611,31 +599,15 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
}
|
||||
else
|
||||
{
|
||||
// The shader declares a new sampler -> declaring it with a "uniform" outside the shader body
|
||||
if (texDesc.first->userTexture) {
|
||||
if (found < program_start) {
|
||||
int index = found;
|
||||
while(index >= 0 && program[index] != '\n') { index--; }
|
||||
program.insert(index+1, "uniform ");
|
||||
found += 8;
|
||||
program_start += 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Add built-in textures
|
||||
// Add user textures only if used
|
||||
if (!texDesc.first->userTexture || found > program_start)
|
||||
std::map<std::string, TextureSamplerDesc>::const_iterator iter = pmShader.textures.cbegin();
|
||||
for ( ; iter != pmShader.textures.cend(); ++iter)
|
||||
{
|
||||
std::map<std::string, TextureSamplerDesc>::const_iterator iter = pmShader.textures.cbegin();
|
||||
for ( ; iter != pmShader.textures.cend(); ++iter)
|
||||
{
|
||||
if (iter->first == sampler)
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter == pmShader.textures.cend())
|
||||
pmShader.textures[sampler] = texDesc;
|
||||
if (iter->first == sampler)
|
||||
break;
|
||||
}
|
||||
|
||||
if (iter == pmShader.textures.cend())
|
||||
pmShader.textures[sampler] = texDesc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,21 +616,13 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
|
||||
textureManager->clearRandomTextures();
|
||||
|
||||
// blur programs
|
||||
blur1_enabled = false;
|
||||
blur2_enabled = false;
|
||||
blur3_enabled = false;
|
||||
|
||||
if (program.find("GetMain") != std::string::npos || program.find("GetPixel") != std::string::npos)
|
||||
{
|
||||
pmShader.textures["main"] = textureManager->getTexture("main", GL_REPEAT, GL_LINEAR);
|
||||
}
|
||||
|
||||
found = program.find("GetBlur3");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
blur1_enabled = blur2_enabled = blur3_enabled = true;
|
||||
pmShader.textures["blur3"] = textureManager->getTexture("blur3", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["blur2"] = textureManager->getTexture("blur2", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -667,6 +631,7 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
{
|
||||
blur1_enabled = blur2_enabled = true;
|
||||
pmShader.textures["blur2"] = textureManager->getTexture("blur2", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
pmShader.textures["blur1"] = textureManager->getTexture("blur1", GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -709,11 +674,89 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
default: shaderTypeString = "Other";
|
||||
}
|
||||
|
||||
M4::GLSLGenerator generator;
|
||||
M4::Allocator allocator;
|
||||
|
||||
M4::HLSLTree tree( &allocator );
|
||||
M4::HLSLParser parser(&allocator, &tree);
|
||||
|
||||
// preprocess define macros
|
||||
std::string sourcePreprocessed;
|
||||
if (!parser.ApplyPreprocessor(shaderFilename.c_str(), fullSource.c_str(), fullSource.size(), sourcePreprocessed)) {
|
||||
std::cerr << "Failed to preprocess HLSL(step1) " << shaderTypeString << " shader" << std::endl;
|
||||
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source: " << std::endl << fullSource << std::endl;
|
||||
#else
|
||||
std::ofstream out("/tmp/shader_" + shaderTypeString + "_step1.txt");
|
||||
out << fullSource;
|
||||
out.close();
|
||||
#endif
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
// Remove previous shader declarations
|
||||
std::smatch matches;
|
||||
while(std::regex_search(sourcePreprocessed, matches, std::regex("sampler(2D|3D|)(\\s+|\\().*"))) {
|
||||
sourcePreprocessed.replace(matches.position(), matches.length(), "");
|
||||
}
|
||||
|
||||
// Remove previous texsize declarations
|
||||
while(std::regex_search(sourcePreprocessed, matches, std::regex("float4\\s+texsize_.*"))) {
|
||||
sourcePreprocessed.replace(matches.position(), matches.length(), "");
|
||||
}
|
||||
|
||||
// Declare samplers
|
||||
std::set<std::string> texsizes;
|
||||
std::map<std::string, TextureSamplerDesc>::const_iterator iter_samplers = pmShader.textures.cbegin();
|
||||
for ( ; iter_samplers != pmShader.textures.cend(); ++iter_samplers)
|
||||
{
|
||||
Texture * texture = iter_samplers->second.first;
|
||||
|
||||
if (texture->type == GL_TEXTURE_3D) {
|
||||
sourcePreprocessed.insert(0, "uniform sampler3D sampler_" + iter_samplers->first + ";\n");
|
||||
} else {
|
||||
sourcePreprocessed.insert(0, "uniform sampler2D sampler_" + iter_samplers->first + ";\n");
|
||||
}
|
||||
|
||||
texsizes.insert(iter_samplers->first);
|
||||
texsizes.insert(texture->name);
|
||||
}
|
||||
|
||||
// Declare texsizes
|
||||
std::set<std::string>::const_iterator iter_texsizes = texsizes.cbegin();
|
||||
for ( ; iter_texsizes != texsizes.cend(); ++iter_texsizes)
|
||||
{
|
||||
sourcePreprocessed.insert(0, "uniform float4 texsize_" + *iter_texsizes + ";\n");
|
||||
}
|
||||
|
||||
|
||||
// transpile from HLSL (aka preset shader aka directX shader) to GLSL (aka OpenGL shader lang)
|
||||
HLSLTranslator translator = HLSLTranslator();
|
||||
std::string glslSource = translator.parse(shaderTypeString, shaderFilename.c_str(), fullSource);
|
||||
if (glslSource.empty()) {
|
||||
std::cerr << "Failed to translate " << shaderTypeString << std::endl;
|
||||
|
||||
// parse
|
||||
if( !parser.Parse(shaderFilename.c_str(), sourcePreprocessed.c_str(), sourcePreprocessed.size()) ) {
|
||||
std::cerr << "Failed to parse HLSL(step2) " << shaderTypeString << " shader" << std::endl;
|
||||
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source: " << std::endl << sourcePreprocessed << std::endl;
|
||||
#else
|
||||
std::ofstream out2("/tmp/shader_" + shaderTypeString + "_step2.txt");
|
||||
out2 << sourcePreprocessed;
|
||||
out2.close();
|
||||
#endif
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
// generate GLSL
|
||||
if (!generator.Generate(&tree, M4::GLSLGenerator::Target_FragmentShader, M4::GLSLGenerator::Version_140, "PS")) {
|
||||
std::cerr << "Failed to transpile HLSL(step3) " << shaderTypeString << " shader to GLSL" << std::endl;
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source: " << std::endl << sourcePreprocessed << std::endl;
|
||||
#else
|
||||
std::ofstream out2("/tmp/shader_" + shaderTypeString + "_step2.txt");
|
||||
out2 << sourcePreprocessed;
|
||||
out2.close();
|
||||
#endif
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
@ -721,22 +764,22 @@ GLuint ShaderEngine::compilePresetShader(const PresentShaderType shaderType, Sha
|
||||
// copmile the preset shader fragment shader with the standard vertex shader and cross our fingers
|
||||
GLuint ret = 0;
|
||||
if (shaderType == PresentWarpShader) {
|
||||
ret = CompileShaderProgram(presetWarpVertexShader, glslSource, shaderTypeString); // returns new program
|
||||
ret = CompileShaderProgram(presetWarpVertexShader, generator.GetResult(), shaderTypeString); // returns new program
|
||||
} else {
|
||||
ret = CompileShaderProgram(presetCompVertexShader, glslSource, shaderTypeString); // returns new program
|
||||
ret = CompileShaderProgram(presetCompVertexShader, generator.GetResult(), shaderTypeString); // returns new program
|
||||
}
|
||||
|
||||
if (ret != GL_FALSE) {
|
||||
std::cerr << "Successfull compilation of " << shaderTypeString << std::endl;
|
||||
} else {
|
||||
std::cerr << "Compilation error of " << shaderTypeString << std::endl;
|
||||
std::cerr << "Compilation error (step3) of " << shaderTypeString << std::endl;
|
||||
|
||||
#ifndef DUMP_SHADERS_ON_ERROR
|
||||
std::cerr << "Source:" << std::endl << *glslSource.get() << std::endl;
|
||||
std::cerr << "Source:" << std::endl << generator.GetResult() << std::endl;
|
||||
#else
|
||||
std::ofstream out2("/tmp/shader_glsl_" + shaderTypeString + ".txt");
|
||||
out2 << glslSource;
|
||||
out2.close();
|
||||
std::ofstream out3("/tmp/shader_" + shaderTypeString + "_step3.txt");
|
||||
out3 << generator.GetResult();
|
||||
out3.close();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -862,12 +905,15 @@ void ShaderEngine::SetupTextures(GLuint program, const Shader &shader)
|
||||
{
|
||||
|
||||
uint texNum = 0;
|
||||
for (std::map<std::string, TextureSamplerDesc>::const_iterator iter = shader.textures.begin(); iter
|
||||
!= shader.textures.end(); ++iter)
|
||||
std::map<std::string, Texture*> texsizes;
|
||||
|
||||
// Set samplers
|
||||
for (std::map<std::string, TextureSamplerDesc>::const_iterator iter_samplers = shader.textures.begin(); iter_samplers
|
||||
!= shader.textures.end(); ++iter_samplers)
|
||||
{
|
||||
std::string texName = iter->first;
|
||||
Texture * texture = iter->second.first;
|
||||
Sampler * sampler = iter->second.second;
|
||||
std::string texName = iter_samplers->first;
|
||||
Texture * texture = iter_samplers->second.first;
|
||||
Sampler * sampler = iter_samplers->second.second;
|
||||
std::string samplerName = "sampler_" + texName;
|
||||
|
||||
// https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Binding_textures_to_samplers
|
||||
@ -877,24 +923,33 @@ void ShaderEngine::SetupTextures(GLuint program, const Shader &shader)
|
||||
continue;
|
||||
}
|
||||
|
||||
texsizes[texName] = texture;
|
||||
texsizes[texture->name] = texture;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + texNum);
|
||||
glBindTexture(texture->type, texture->texID);
|
||||
glBindSampler(texNum, sampler->samplerID);
|
||||
|
||||
glUniform1i(param, texNum);
|
||||
texNum++;
|
||||
}
|
||||
|
||||
std::string texsizeName = "texsize_" + texName;
|
||||
|
||||
// Set texsizes
|
||||
std::map<std::string, Texture*>::const_iterator iter_textures = texsizes.cbegin();
|
||||
for ( ; iter_textures != texsizes.cend(); ++iter_textures)
|
||||
{
|
||||
Texture * texture = iter_textures->second;
|
||||
|
||||
std::string texsizeName = "texsize_" + iter_textures->first;
|
||||
GLint textSizeParam = glGetUniformLocation(program, texsizeName.c_str());
|
||||
if (param >= 0) {
|
||||
if (textSizeParam >= 0) {
|
||||
glUniform4f(textSizeParam, texture->width, texture->height,
|
||||
1 / (float) texture->width, 1 / (float) texture->height);
|
||||
} else {
|
||||
std::cerr << "invalid texsize name " << texsizeName << std::endl;
|
||||
return;
|
||||
// unused uniform have been optimized out by glsl compiler
|
||||
continue;
|
||||
}
|
||||
|
||||
texNum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,8 +19,9 @@ Sampler::~Sampler()
|
||||
|
||||
|
||||
|
||||
Texture::Texture(const int _width, const int _height, const bool _userTexture) :
|
||||
Texture::Texture(const std::string &_name, const int _width, const int _height, const bool _userTexture) :
|
||||
type(GL_TEXTURE_2D),
|
||||
name(_name),
|
||||
width(_width),
|
||||
height(_height),
|
||||
userTexture(_userTexture)
|
||||
@ -31,9 +32,10 @@ Texture::Texture(const int _width, const int _height, const bool _userTexture) :
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
Texture::Texture(const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture) :
|
||||
Texture::Texture(const std::string &_name, const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture) :
|
||||
texID(_texID),
|
||||
type(_type),
|
||||
name(_name),
|
||||
width(_width),
|
||||
height(_height),
|
||||
userTexture(_userTexture)
|
||||
|
||||
@ -25,13 +25,14 @@ public:
|
||||
GLuint texID;
|
||||
GLenum type;
|
||||
|
||||
std::string name;
|
||||
int width;
|
||||
int height;
|
||||
bool userTexture;
|
||||
std::vector<Sampler*> samplers;
|
||||
|
||||
Texture(const int _width, const int _height, const bool _userTexture);
|
||||
Texture(const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture);
|
||||
Texture(const std::string & _name, const int _width, const int _height, const bool _userTexture);
|
||||
Texture(const std::string & _name, const GLuint _texID, const GLenum _type, const int _width, const int _height, const bool _userTexture);
|
||||
~Texture();
|
||||
|
||||
Sampler *getSampler(const GLint _wrap_mode, const GLint _filter_mode);
|
||||
|
||||
@ -40,10 +40,13 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
extensions.push_back(".dib");
|
||||
|
||||
Preload();
|
||||
loadTextureDir();
|
||||
|
||||
loadTextureDir(std::string(DATADIR_PATH) + "/presets");
|
||||
loadTextureDir(std::string(DATADIR_PATH) + "/textures");
|
||||
loadTextureDir(_presetsURL);
|
||||
|
||||
// Create main texture ans associated samplers
|
||||
mainTexture = new Texture(texsizeX, texsizeY, false);
|
||||
mainTexture = new Texture("main", texsizeX, texsizeY, false);
|
||||
mainTexture->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
mainTexture->getSampler(GL_REPEAT, GL_NEAREST);
|
||||
mainTexture->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
@ -70,9 +73,9 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
int w2 = ((w+3)/16)*16;
|
||||
int h2 = ((h+3)/4)*4;
|
||||
|
||||
Texture * textureBlur = new Texture(w2, h2, false);
|
||||
textureBlur->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
std::string texname = "blur" + std::to_string(i/2+1) + ((i%2) ? "" : "doNOTuseME");
|
||||
Texture * textureBlur = new Texture(texname, w2, h2, false);
|
||||
textureBlur->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
textures[texname] = textureBlur;
|
||||
blurTextures.push_back(textureBlur);
|
||||
}
|
||||
@ -83,7 +86,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures(1, &noise_texture_lq_lite);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq_lite);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGB, GL_FLOAT, noise.noise_lq_lite);
|
||||
Texture * textureNoise_lq_lite = new Texture(noise_texture_lq_lite, GL_TEXTURE_2D, 32, 32, false);
|
||||
Texture * textureNoise_lq_lite = new Texture("noise_lq_lite", noise_texture_lq_lite, GL_TEXTURE_2D, 32, 32, false);
|
||||
textureNoise_lq_lite->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_lq_lite"] = textureNoise_lq_lite;
|
||||
|
||||
@ -91,7 +94,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures(1, &noise_texture_lq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_lq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise.noise_lq);
|
||||
Texture * textureNoise_lq = new Texture(noise_texture_lq, GL_TEXTURE_2D, 256, 256, false);
|
||||
Texture * textureNoise_lq = new Texture("noise_lq", noise_texture_lq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_lq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_lq"] = textureNoise_lq;
|
||||
|
||||
@ -99,7 +102,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures(1, &noise_texture_mq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_mq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise.noise_mq);
|
||||
Texture * textureNoise_mq = new Texture(noise_texture_mq, GL_TEXTURE_2D, 256, 256, false);
|
||||
Texture * textureNoise_mq = new Texture("noise_mq", noise_texture_mq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_mq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_mq"] = textureNoise_mq;
|
||||
|
||||
@ -107,7 +110,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures(1, &noise_texture_hq);
|
||||
glBindTexture(GL_TEXTURE_2D, noise_texture_hq);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise.noise_hq);
|
||||
Texture * textureNoise_hq = new Texture(noise_texture_hq, GL_TEXTURE_2D, 256, 256, false);
|
||||
Texture * textureNoise_hq = new Texture("noise_hq", noise_texture_hq, GL_TEXTURE_2D, 256, 256, false);
|
||||
textureNoise_hq->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noise_hq"] = textureNoise_hq;
|
||||
|
||||
@ -115,7 +118,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures( 1, &noise_texture_lq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_lq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,GL_RGB ,GL_FLOAT ,noise.noise_lq_vol);
|
||||
Texture * textureNoise_lq_vol = new Texture(noise_texture_lq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
Texture * textureNoise_lq_vol = new Texture("noisevol_lq", noise_texture_lq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
textureNoise_lq_vol->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noisevol_lq"] = textureNoise_lq_vol;
|
||||
|
||||
@ -123,7 +126,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
|
||||
glGenTextures( 1, &noise_texture_hq_vol );
|
||||
glBindTexture( GL_TEXTURE_3D, noise_texture_hq_vol );
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, GL_RGB, GL_FLOAT, noise.noise_hq_vol);
|
||||
Texture * textureNoise_hq_vol = new Texture(noise_texture_hq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
Texture * textureNoise_hq_vol = new Texture("noisevol_hq", noise_texture_hq_vol, GL_TEXTURE_3D, 32, 32, false);
|
||||
textureNoise_hq_vol->getSampler(GL_REPEAT, GL_LINEAR);
|
||||
textures["noisevol_hq"] = textureNoise_hq_vol;
|
||||
}
|
||||
@ -147,9 +150,9 @@ void TextureManager::Preload()
|
||||
,&width,&height);
|
||||
|
||||
|
||||
Texture * newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
Texture * newTex = new Texture("M", tex, GL_TEXTURE_2D, width, height, true);
|
||||
newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
textures["M.tga"] = newTex;
|
||||
textures["M"] = newTex;
|
||||
|
||||
// tex = SOIL_load_OGL_texture_from_memory(
|
||||
// project_data,
|
||||
@ -160,9 +163,9 @@ void TextureManager::Preload()
|
||||
// | SOIL_FLAG_MULTIPLY_ALPHA
|
||||
// ,&width,&height);
|
||||
|
||||
// newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
// newTex = new Texture("project", tex, GL_TEXTURE_2D, width, height, true);
|
||||
// newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
// textures["project.tga"] = newTex;
|
||||
// textures["project"] = newTex;
|
||||
|
||||
tex = SOIL_load_OGL_texture_from_memory(
|
||||
headphones_data,
|
||||
@ -173,9 +176,9 @@ void TextureManager::Preload()
|
||||
| SOIL_FLAG_MULTIPLY_ALPHA
|
||||
,&width,&height);
|
||||
|
||||
newTex = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
newTex = new Texture("headphones", tex, GL_TEXTURE_2D, width, height, true);
|
||||
newTex->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
textures["headphones.tga"] = newTex;
|
||||
textures["headphones"] = newTex;
|
||||
}
|
||||
|
||||
void TextureManager::Clear()
|
||||
@ -189,24 +192,38 @@ void TextureManager::Clear()
|
||||
|
||||
TextureSamplerDesc TextureManager::getTexture(const std::string fullName, const GLenum defaultWrap, const GLenum defaultFilter)
|
||||
{
|
||||
std::string name;
|
||||
std::string fileName = fullName;
|
||||
std::string unqualifiedName;
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
|
||||
ExtractTextureSettings(fullName, wrap_mode, filter_mode, name);
|
||||
if (textures.find(name) == textures.end())
|
||||
// Remove extension
|
||||
std::string lowerCaseFileName(fullName);
|
||||
std::transform(lowerCaseFileName.begin(), lowerCaseFileName.end(), lowerCaseFileName.begin(), tolower);
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
{
|
||||
size_t found = lowerCaseFileName.find(extensions[x]);
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
fileName.replace(int(found), extensions[x].size(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ExtractTextureSettings(fileName, wrap_mode, filter_mode, unqualifiedName);
|
||||
if (textures.find(unqualifiedName) == textures.end())
|
||||
{
|
||||
return TextureSamplerDesc(NULL, NULL);
|
||||
}
|
||||
|
||||
if (fullName == name) {
|
||||
if (fileName == unqualifiedName) {
|
||||
// Warp and filter mode not specified in sampler name
|
||||
// applying default
|
||||
wrap_mode = defaultWrap;
|
||||
filter_mode = defaultFilter;
|
||||
}
|
||||
|
||||
Texture * texture = textures[name];
|
||||
Texture * texture = textures[unqualifiedName];
|
||||
Sampler * sampler = texture->getSampler(wrap_mode, filter_mode);
|
||||
|
||||
return TextureSamplerDesc(texture, sampler);
|
||||
@ -216,10 +233,15 @@ TextureSamplerDesc TextureManager::getTexture(const std::string fullName, const
|
||||
TextureSamplerDesc TextureManager::tryLoadingTexture(const std::string name)
|
||||
{
|
||||
TextureSamplerDesc texDesc;
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
std::string unqualifiedName;
|
||||
|
||||
ExtractTextureSettings(name, wrap_mode, filter_mode, unqualifiedName);
|
||||
|
||||
for (size_t x = 0; x < extensions.size(); x++)
|
||||
{
|
||||
std::string filename = name + extensions[x];
|
||||
std::string filename = unqualifiedName + extensions[x];
|
||||
std::string fullURL = presetsURL + PATH_SEPARATOR + filename;
|
||||
|
||||
texDesc = loadTexture(name, fullURL);
|
||||
@ -249,8 +271,13 @@ TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std
|
||||
return TextureSamplerDesc(NULL, NULL);
|
||||
}
|
||||
|
||||
Texture * newTexture = new Texture(tex, GL_TEXTURE_2D, width, height, true);
|
||||
Sampler * sampler = newTexture->getSampler(GL_CLAMP_TO_EDGE, GL_LINEAR);
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
std::string unqualifiedName;
|
||||
|
||||
ExtractTextureSettings(name, wrap_mode, filter_mode, unqualifiedName);
|
||||
Texture * newTexture = new Texture(unqualifiedName, tex, GL_TEXTURE_2D, width, height, true);
|
||||
Sampler * sampler = newTexture->getSampler(wrap_mode, filter_mode);
|
||||
|
||||
textures[name] = newTexture;
|
||||
|
||||
@ -258,10 +285,8 @@ TextureSamplerDesc TextureManager::loadTexture(const std::string name, const std
|
||||
}
|
||||
|
||||
|
||||
void TextureManager::loadTextureDir()
|
||||
void TextureManager::loadTextureDir(const std::string &dirname)
|
||||
{
|
||||
std::string dirname = std::string(DATADIR_PATH) + "/presets";
|
||||
|
||||
DIR * m_dir;
|
||||
|
||||
// Allocate a new a stream given the current directory name
|
||||
@ -309,15 +334,29 @@ void TextureManager::loadTextureDir()
|
||||
}
|
||||
}
|
||||
|
||||
std::string TextureManager::getRandomTextureName(std::string random_id)
|
||||
TextureSamplerDesc TextureManager::getRandomTextureName(std::string random_id)
|
||||
{
|
||||
GLint wrap_mode;
|
||||
GLint filter_mode;
|
||||
std::string unqualifiedName;
|
||||
|
||||
ExtractTextureSettings(random_id, wrap_mode, filter_mode, unqualifiedName);
|
||||
|
||||
std::vector<std::string> user_texture_names;
|
||||
size_t separator = unqualifiedName.find("_");
|
||||
std::string textureNameFilter;
|
||||
|
||||
if (separator != std::string::npos)
|
||||
{
|
||||
textureNameFilter = unqualifiedName.substr(separator+1);
|
||||
unqualifiedName = unqualifiedName.substr(0, separator);
|
||||
}
|
||||
|
||||
for(std::map<std::string, Texture*>::const_iterator iter = textures.begin(); iter != textures.end(); iter++)
|
||||
{
|
||||
if (iter->second->userTexture) {
|
||||
user_texture_names.push_back(iter->first);
|
||||
if (textureNameFilter.empty() || iter->first.find(textureNameFilter) == 0)
|
||||
user_texture_names.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,10 +364,16 @@ std::string TextureManager::getRandomTextureName(std::string random_id)
|
||||
{
|
||||
std::string random_name = user_texture_names[rand() % user_texture_names.size()];
|
||||
random_textures.push_back(random_id);
|
||||
textures[random_id] = textures[random_name];
|
||||
return random_name;
|
||||
|
||||
Texture * randomTexture = new Texture(*textures[random_name]);
|
||||
Sampler * sampler = randomTexture->getSampler(wrap_mode, filter_mode);
|
||||
randomTexture->name = unqualifiedName;
|
||||
textures[random_id] = randomTexture;
|
||||
|
||||
return TextureSamplerDesc(randomTexture, sampler);
|
||||
}
|
||||
else return "";
|
||||
|
||||
return TextureSamplerDesc(NULL, NULL);
|
||||
}
|
||||
|
||||
void TextureManager::clearRandomTextures()
|
||||
|
||||
@ -17,7 +17,7 @@ class TextureManager
|
||||
Texture * mainTexture;
|
||||
|
||||
std::vector<std::string> random_textures;
|
||||
void loadTextureDir();
|
||||
void loadTextureDir(const std::string & dirname);
|
||||
TextureSamplerDesc loadTexture(const std::string name, const std::string imageUrl);
|
||||
void ExtractTextureSettings(const std::string qualifiedName, GLint &_wrap_mode, GLint &_filter_mode, std::string & name);
|
||||
std::vector<std::string> extensions;
|
||||
@ -35,7 +35,7 @@ public:
|
||||
|
||||
void updateMainTexture();
|
||||
|
||||
std::string getRandomTextureName(std::string rand_name);
|
||||
TextureSamplerDesc getRandomTextureName(std::string rand_name);
|
||||
void clearRandomTextures();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user