154 lines
3.3 KiB
C++
154 lines
3.3 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license BSD v3 (see license file)
|
|
*/
|
|
|
|
#include <etk/Types.h>
|
|
#include <etk/os/FSNode.h>
|
|
#include <ewol/Debug.h>
|
|
#include <ewol/openGL/Shader.h>
|
|
|
|
|
|
|
|
ewol::Shader::Shader(etk::UString& filename):
|
|
ewol::Resource(filename),
|
|
m_exist(false),
|
|
m_fileData(NULL),
|
|
m_shader(0),
|
|
m_type(0)
|
|
{
|
|
m_resourceLevel = 0;
|
|
EWOL_DEBUG("OGL : load SHADER \"" << filename << "\"");
|
|
// load data from file "all the time ..."
|
|
|
|
if (true == m_name.EndWith(".frag") ) {
|
|
m_type = GL_FRAGMENT_SHADER;
|
|
} else if (true == m_name.EndWith(".vert") ) {
|
|
m_type = GL_VERTEX_SHADER;
|
|
} else {
|
|
EWOL_ERROR("File does not have extention \".vert\" for Vertex Shader or \".frag\" for Fragment Shader. but : \"" << m_name << "\"");
|
|
return;
|
|
}
|
|
Reload();
|
|
}
|
|
|
|
|
|
ewol::Shader::~Shader(void)
|
|
{
|
|
if (NULL != m_fileData) {
|
|
delete [] m_fileData;
|
|
m_fileData = NULL;
|
|
}
|
|
if (0!=m_shader) {
|
|
glDeleteShader(m_shader);
|
|
m_shader = 0;
|
|
}
|
|
m_exist = false;
|
|
}
|
|
|
|
|
|
static void checkGlError(const char* op)
|
|
{
|
|
for (GLint error = glGetError(); error; error = glGetError()) {
|
|
EWOL_INFO("after " << op << "() glError (" << error << ")");
|
|
}
|
|
}
|
|
#define LOG_OGL_INTERNAL_BUFFER_LEN (8192)
|
|
static char l_bufferDisplayError[LOG_OGL_INTERNAL_BUFFER_LEN] = "";
|
|
|
|
void ewol::Shader::UpdateContext(void)
|
|
{
|
|
if (true==m_exist) {
|
|
// Do nothing ==> too dangerous ...
|
|
} else {
|
|
// create the Shader
|
|
if (NULL == m_fileData) {
|
|
m_shader = 0;
|
|
return;
|
|
}
|
|
m_shader = glCreateShader(m_type);
|
|
if (!m_shader) {
|
|
EWOL_ERROR("glCreateShader return error ...");
|
|
checkGlError("glCreateShader");
|
|
return;
|
|
} else {
|
|
glShaderSource(m_shader, 1, (const char**)&m_fileData, NULL);
|
|
glCompileShader(m_shader);
|
|
GLint compiled = 0;
|
|
glGetShaderiv(m_shader, GL_COMPILE_STATUS, &compiled);
|
|
if (!compiled) {
|
|
GLint infoLen = 0;
|
|
l_bufferDisplayError[0] = '\0';
|
|
glGetShaderInfoLog(m_shader, LOG_OGL_INTERNAL_BUFFER_LEN, &infoLen, l_bufferDisplayError);
|
|
const char * tmpShaderType = "GL_FRAGMENT_SHADER";
|
|
if (m_type == GL_VERTEX_SHADER){
|
|
tmpShaderType = "GL_VERTEX_SHADER";
|
|
}
|
|
EWOL_ERROR("Could not compile \"" << tmpShaderType << "\": " << l_bufferDisplayError);
|
|
return;
|
|
}
|
|
}
|
|
m_exist = true;
|
|
}
|
|
}
|
|
|
|
void ewol::Shader::RemoveContext(void)
|
|
{
|
|
if (true==m_exist) {
|
|
glDeleteShader(m_shader);
|
|
m_exist = false;
|
|
m_shader = 0;
|
|
}
|
|
}
|
|
|
|
void ewol::Shader::RemoveContextToLate(void)
|
|
{
|
|
m_exist = false;
|
|
m_shader = 0;
|
|
}
|
|
|
|
void ewol::Shader::Reload(void)
|
|
{
|
|
etk::FSNode file(m_name);
|
|
if (false == file.Exist()) {
|
|
EWOL_ERROR("File does not Exist : \"" << file << "\"");
|
|
return;
|
|
}
|
|
|
|
int64_t fileSize = file.FileSize();
|
|
if (0==fileSize) {
|
|
EWOL_ERROR("This file is empty : " << file);
|
|
return;
|
|
}
|
|
if (false == file.FileOpenRead()) {
|
|
EWOL_ERROR("Can not open the file : " << file);
|
|
return;
|
|
}
|
|
// Remove previous data ...
|
|
if (NULL != m_fileData) {
|
|
delete[] m_fileData;
|
|
m_fileData = 0;
|
|
}
|
|
// allocate data
|
|
m_fileData = new char[fileSize+5];
|
|
if (NULL == m_fileData) {
|
|
EWOL_ERROR("Error Memory allocation size=" << fileSize);
|
|
return;
|
|
}
|
|
memset(m_fileData, 0, (fileSize+5)*sizeof(char));
|
|
// load data from the file :
|
|
file.FileRead(m_fileData, 1, fileSize);
|
|
// close the file:
|
|
file.FileClose();
|
|
|
|
// now change the OGL context ...
|
|
RemoveContext();
|
|
UpdateContext();
|
|
}
|
|
|
|
|
|
|