Acabat de repasar jail_shader.cpp
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#include "jail_shader.h"
|
#include "jail_shader.h"
|
||||||
#include <SDL2/SDL.h> // para SDL_Point
|
#include <SDL2/SDL.h> // para SDL_Point
|
||||||
#include <stdlib.h> // para NULL, free, malloc, exit
|
#include <cstdlib> // para NULL, free, malloc, exit
|
||||||
#include <string.h> // para strncmp
|
#include <cstring> // para strncmp
|
||||||
#include <iostream> // para basic_ostream, char_traits, operator<<
|
#include <iostream> // para std::cout, std::endl
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
@@ -10,10 +10,11 @@
|
|||||||
|
|
||||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#include <OpenGL/gl3.h>
|
#include <OpenGL/gl3.h>
|
||||||
#else // NOT ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
#else // NO ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
#endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
#endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||||
#else // NOT __APPLE__
|
|
||||||
|
#else // SI NO ES __APPLE__
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
@@ -25,12 +26,10 @@ namespace shader
|
|||||||
SDL_Texture *backBuffer = nullptr;
|
SDL_Texture *backBuffer = nullptr;
|
||||||
SDL_Point win_size = {320 * 4, 256 * 4};
|
SDL_Point win_size = {320 * 4, 256 * 4};
|
||||||
SDL_Point tex_size = {320, 256};
|
SDL_Point tex_size = {320, 256};
|
||||||
bool usingOpenGL;
|
bool usingOpenGL = false;
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
|
// Declaración de funciones de extensión de OpenGL (evitando GLEW)
|
||||||
// I'm avoiding the use of GLEW or some extensions handler, but that
|
|
||||||
// doesn't mean you should...
|
|
||||||
PFNGLCREATESHADERPROC glCreateShader;
|
PFNGLCREATESHADERPROC glCreateShader;
|
||||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||||
@@ -66,119 +65,125 @@ namespace shader
|
|||||||
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
|
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
|
||||||
glUseProgram;
|
glUseProgram;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GLuint compileShader(const char *source, GLuint shaderType)
|
// Función para compilar un shader a partir de un std::string
|
||||||
|
GLuint compileShader(const std::string &source, GLuint shaderType)
|
||||||
{
|
{
|
||||||
// Create ID for shader
|
if (source.empty())
|
||||||
GLuint result = glCreateShader(shaderType);
|
|
||||||
|
|
||||||
// Add define depending on shader type
|
|
||||||
const char *sources[2] = {shaderType == GL_VERTEX_SHADER ? "#define VERTEX\n" : "#define FRAGMENT\n", source};
|
|
||||||
|
|
||||||
// Define shader text
|
|
||||||
glShaderSource(result, 2, sources, nullptr);
|
|
||||||
|
|
||||||
// Compile shader
|
|
||||||
glCompileShader(result);
|
|
||||||
|
|
||||||
// Check vertex shader for errors
|
|
||||||
GLint shaderCompiled = GL_FALSE;
|
|
||||||
glGetShaderiv(result, GL_COMPILE_STATUS, &shaderCompiled);
|
|
||||||
if (shaderCompiled != GL_TRUE)
|
|
||||||
{
|
{
|
||||||
std::cout << "Error en la compilación: " << result << "!" << std::endl;
|
throw std::runtime_error("ERROR FATAL: El código fuente del shader está vacío.");
|
||||||
GLint logLength;
|
|
||||||
glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength);
|
|
||||||
if (logLength > 0)
|
|
||||||
{
|
|
||||||
GLchar *log = (GLchar *)malloc(logLength);
|
|
||||||
glGetShaderInfoLog(result, logLength, &logLength, log);
|
|
||||||
std::cout << "Shader compile log:" << log << std::endl;
|
|
||||||
free(log);
|
|
||||||
}
|
|
||||||
glDeleteShader(result);
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource)
|
// Crear identificador del shader
|
||||||
|
GLuint resultado = glCreateShader(shaderType);
|
||||||
|
|
||||||
|
// Agregar una directiva según el tipo de shader
|
||||||
|
std::string directiva = (shaderType == GL_VERTEX_SHADER)
|
||||||
|
? "#define VERTEX\n"
|
||||||
|
: "#define FRAGMENT\n";
|
||||||
|
|
||||||
|
const char *sources[2] = {directiva.c_str(), source.c_str()};
|
||||||
|
|
||||||
|
// Especificar el código fuente del shader
|
||||||
|
glShaderSource(resultado, 2, sources, nullptr);
|
||||||
|
|
||||||
|
// Compilar el shader
|
||||||
|
glCompileShader(resultado);
|
||||||
|
|
||||||
|
// Verificar si la compilación fue exitosa
|
||||||
|
GLint compiladoCorrectamente = GL_FALSE;
|
||||||
|
glGetShaderiv(resultado, GL_COMPILE_STATUS, &compiladoCorrectamente);
|
||||||
|
if (compiladoCorrectamente != GL_TRUE)
|
||||||
{
|
{
|
||||||
GLuint programId = 0;
|
std::cout << "Error en la compilación del shader (" << resultado << ")!" << std::endl;
|
||||||
GLuint vtxShaderId, fragShaderId;
|
GLint longitudLog;
|
||||||
|
glGetShaderiv(resultado, GL_INFO_LOG_LENGTH, &longitudLog);
|
||||||
programId = glCreateProgram();
|
if (longitudLog > 0)
|
||||||
|
|
||||||
vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
|
||||||
fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
if (vtxShaderId && fragShaderId)
|
|
||||||
{
|
{
|
||||||
// Associate shader with program
|
std::vector<GLchar> log(longitudLog);
|
||||||
glAttachShader(programId, vtxShaderId);
|
glGetShaderInfoLog(resultado, longitudLog, &longitudLog, log.data());
|
||||||
glAttachShader(programId, fragShaderId);
|
std::cout << "Registro de compilación del shader: " << log.data() << std::endl;
|
||||||
glLinkProgram(programId);
|
|
||||||
glValidateProgram(programId);
|
|
||||||
|
|
||||||
// Check the status of the compile/link
|
|
||||||
GLint logLen;
|
|
||||||
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
|
|
||||||
if (logLen > 0)
|
|
||||||
{
|
|
||||||
char *log = (char *)malloc(logLen * sizeof(char));
|
|
||||||
|
|
||||||
// Show any errors as appropriate
|
|
||||||
glGetProgramInfoLog(programId, logLen, &logLen, log);
|
|
||||||
std::cout << "Prog Info Log: " << std::endl
|
|
||||||
<< log << std::endl;
|
|
||||||
free(log);
|
|
||||||
}
|
}
|
||||||
|
glDeleteShader(resultado);
|
||||||
|
resultado = 0;
|
||||||
}
|
}
|
||||||
if (vtxShaderId)
|
return resultado;
|
||||||
{
|
|
||||||
glDeleteShader(vtxShaderId);
|
|
||||||
}
|
|
||||||
if (fragShaderId)
|
|
||||||
{
|
|
||||||
glDeleteShader(fragShaderId);
|
|
||||||
}
|
|
||||||
return programId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool init(SDL_Window *win, SDL_Texture *backBuffer, const char *vertexShader, const char *fragmentShader)
|
// Función para compilar un programa de shaders (vertex y fragment) a partir de std::string
|
||||||
|
GLuint compileProgram(const std::string &vertexShaderSource, const std::string &fragmentShaderSource)
|
||||||
{
|
{
|
||||||
shader::win = win;
|
GLuint idPrograma = glCreateProgram();
|
||||||
shader::renderer = SDL_GetRenderer(win);
|
|
||||||
shader::backBuffer = backBuffer;
|
// Si el fragment shader está vacío, reutilizamos el código del vertex shader
|
||||||
SDL_GetWindowSize(win, &win_size.x, &win_size.y);
|
GLuint idShaderVertice = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||||
int access;
|
GLuint idShaderFragmento = compileShader(fragmentShaderSource.empty() ? vertexShaderSource : fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||||
SDL_QueryTexture(backBuffer, nullptr, &access, &tex_size.x, &tex_size.y);
|
|
||||||
if (access != SDL_TEXTUREACCESS_TARGET)
|
if (idShaderVertice && idShaderFragmento)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("ERROR FATAL: La textura debe tener SDL_TEXTUREACCESS_TARGET definido.");
|
// Asociar los shaders al programa
|
||||||
|
glAttachShader(idPrograma, idShaderVertice);
|
||||||
|
glAttachShader(idPrograma, idShaderFragmento);
|
||||||
|
glLinkProgram(idPrograma);
|
||||||
|
glValidateProgram(idPrograma);
|
||||||
|
|
||||||
|
// Verificar el estado del enlace
|
||||||
|
GLint longitudLog;
|
||||||
|
glGetProgramiv(idPrograma, GL_INFO_LOG_LENGTH, &longitudLog);
|
||||||
|
if (longitudLog > 0)
|
||||||
|
{
|
||||||
|
std::vector<char> log(longitudLog);
|
||||||
|
glGetProgramInfoLog(idPrograma, longitudLog, &longitudLog, log.data());
|
||||||
|
std::cout << "Registro de información del programa:" << std::endl
|
||||||
|
<< log.data() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idShaderVertice)
|
||||||
|
{
|
||||||
|
glDeleteShader(idShaderVertice);
|
||||||
|
}
|
||||||
|
if (idShaderFragmento)
|
||||||
|
{
|
||||||
|
glDeleteShader(idShaderFragmento);
|
||||||
|
}
|
||||||
|
return idPrograma;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RendererInfo rendererInfo;
|
bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader)
|
||||||
SDL_GetRendererInfo(renderer, &rendererInfo);
|
{
|
||||||
|
shader::win = ventana;
|
||||||
|
shader::renderer = SDL_GetRenderer(ventana);
|
||||||
|
shader::backBuffer = texturaBackBuffer;
|
||||||
|
SDL_GetWindowSize(ventana, &win_size.x, &win_size.y);
|
||||||
|
|
||||||
if (!strncmp(rendererInfo.name, "opengl", 6))
|
int acceso;
|
||||||
|
SDL_QueryTexture(texturaBackBuffer, nullptr, &acceso, &tex_size.x, &tex_size.y);
|
||||||
|
if (acceso != SDL_TEXTUREACCESS_TARGET)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("ERROR FATAL: La textura debe tener definido SDL_TEXTUREACCESS_TARGET.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RendererInfo infoRenderer;
|
||||||
|
SDL_GetRendererInfo(renderer, &infoRenderer);
|
||||||
|
|
||||||
|
// Verificar que el renderer sea OpenGL
|
||||||
|
if (!strncmp(infoRenderer.name, "opengl", 6))
|
||||||
{
|
{
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
if (!initGLExtensions())
|
if (!initGLExtensions())
|
||||||
{
|
{
|
||||||
std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl;
|
std::cout << "ADVERTENCIA: No se han podido inicializar las extensiones de OpenGL." << std::endl;
|
||||||
usingOpenGL = false;
|
usingOpenGL = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Compilar el shader y dejarlo listo para usar.
|
// Compilar el programa de shaders utilizando std::string
|
||||||
programId = compileProgram(vertexShader, fragmentShader);
|
programId = compileProgram(vertexShader, fragmentShader);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl;
|
std::cout << "ADVERTENCIA: El driver del renderer no es OpenGL." << std::endl;
|
||||||
usingOpenGL = false;
|
usingOpenGL = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -249,6 +254,7 @@ namespace shader
|
|||||||
// Configurar la proyección ortográfica usando el espacio lógico
|
// Configurar la proyección ortográfica usando el espacio lógico
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
// Queremos que el origen esté en la esquina superior izquierda del espacio lógico.
|
// Queremos que el origen esté en la esquina superior izquierda del espacio lógico.
|
||||||
glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1);
|
glOrtho(0, static_cast<GLdouble>(logicalW), static_cast<GLdouble>(logicalH), 0, -1, 1);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL2/SDL_render.h> // para SDL_Texture
|
#include <SDL2/SDL_render.h> // para SDL_Texture
|
||||||
#include <SDL2/SDL_video.h> // para SDL_Window
|
#include <SDL2/SDL_video.h> // para SDL_Window
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// TIPS:
|
// TIPS:
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -38,8 +39,7 @@
|
|||||||
|
|
||||||
namespace shader
|
namespace shader
|
||||||
{
|
{
|
||||||
const bool init(SDL_Window *win, SDL_Texture *backBuffer,
|
//const bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const char *vertexShader, const char *fragmentShader = nullptr);
|
||||||
const char *vertexShader, const char *fragmentShader = nullptr);
|
bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader = "");
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
}
|
}
|
||||||
@@ -327,7 +327,7 @@ void Screen::initShaders()
|
|||||||
{
|
{
|
||||||
loadShaders();
|
loadShaders();
|
||||||
}
|
}
|
||||||
shader::init(window_, game_canvas_, shaderSource.c_str());
|
shader::init(window_, game_canvas_, shaderSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el tamaño de la ventana
|
// Calcula el tamaño de la ventana
|
||||||
|
|||||||
Reference in New Issue
Block a user