Acabat de repasar jail_shader.cpp
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#include "jail_shader.h"
|
||||
#include <SDL2/SDL.h> // para SDL_Point
|
||||
#include <stdlib.h> // para NULL, free, malloc, exit
|
||||
#include <string.h> // para strncmp
|
||||
#include <iostream> // para basic_ostream, char_traits, operator<<
|
||||
#include <cstdlib> // para NULL, free, malloc, exit
|
||||
#include <cstring> // para strncmp
|
||||
#include <iostream> // para std::cout, std::endl
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "CoreFoundation/CoreFoundation.h"
|
||||
@@ -10,10 +10,11 @@
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#include <OpenGL/gl3.h>
|
||||
#else // NOT ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#else // NO ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#include <OpenGL/gl.h>
|
||||
#endif // ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#else // NOT __APPLE__
|
||||
|
||||
#else // SI NO ES __APPLE__
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#endif // __APPLE__
|
||||
|
||||
@@ -25,12 +26,10 @@ namespace shader
|
||||
SDL_Texture *backBuffer = nullptr;
|
||||
SDL_Point win_size = {320 * 4, 256 * 4};
|
||||
SDL_Point tex_size = {320, 256};
|
||||
bool usingOpenGL;
|
||||
bool usingOpenGL = false;
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
||||
// I'm avoiding the use of GLEW or some extensions handler, but that
|
||||
// doesn't mean you should...
|
||||
// Declaración de funciones de extensión de OpenGL (evitando GLEW)
|
||||
PFNGLCREATESHADERPROC glCreateShader;
|
||||
PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
@@ -66,119 +65,125 @@ namespace shader
|
||||
glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog &&
|
||||
glUseProgram;
|
||||
}
|
||||
|
||||
#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
|
||||
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)
|
||||
if (source.empty())
|
||||
{
|
||||
std::cout << "Error en la compilación: " << result << "!" << std::endl;
|
||||
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;
|
||||
throw std::runtime_error("ERROR FATAL: El código fuente del shader está vacío.");
|
||||
}
|
||||
|
||||
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;
|
||||
GLuint vtxShaderId, fragShaderId;
|
||||
|
||||
programId = glCreateProgram();
|
||||
|
||||
vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
fragShaderId = compileShader(fragmentShaderSource ? fragmentShaderSource : vertexShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
if (vtxShaderId && fragShaderId)
|
||||
std::cout << "Error en la compilación del shader (" << resultado << ")!" << std::endl;
|
||||
GLint longitudLog;
|
||||
glGetShaderiv(resultado, GL_INFO_LOG_LENGTH, &longitudLog);
|
||||
if (longitudLog > 0)
|
||||
{
|
||||
// Associate shader with program
|
||||
glAttachShader(programId, vtxShaderId);
|
||||
glAttachShader(programId, fragShaderId);
|
||||
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);
|
||||
std::vector<GLchar> log(longitudLog);
|
||||
glGetShaderInfoLog(resultado, longitudLog, &longitudLog, log.data());
|
||||
std::cout << "Registro de compilación del shader: " << log.data() << std::endl;
|
||||
}
|
||||
glDeleteShader(resultado);
|
||||
resultado = 0;
|
||||
}
|
||||
if (vtxShaderId)
|
||||
{
|
||||
glDeleteShader(vtxShaderId);
|
||||
}
|
||||
if (fragShaderId)
|
||||
{
|
||||
glDeleteShader(fragShaderId);
|
||||
}
|
||||
return programId;
|
||||
return resultado;
|
||||
}
|
||||
|
||||
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;
|
||||
shader::renderer = SDL_GetRenderer(win);
|
||||
shader::backBuffer = backBuffer;
|
||||
SDL_GetWindowSize(win, &win_size.x, &win_size.y);
|
||||
int access;
|
||||
SDL_QueryTexture(backBuffer, nullptr, &access, &tex_size.x, &tex_size.y);
|
||||
if (access != SDL_TEXTUREACCESS_TARGET)
|
||||
GLuint idPrograma = glCreateProgram();
|
||||
|
||||
// Si el fragment shader está vacío, reutilizamos el código del vertex shader
|
||||
GLuint idShaderVertice = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||
GLuint idShaderFragmento = compileShader(fragmentShaderSource.empty() ? vertexShaderSource : fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||
|
||||
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;
|
||||
SDL_GetRendererInfo(renderer, &rendererInfo);
|
||||
bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, const std::string &vertexShader, const std::string &fragmentShader)
|
||||
{
|
||||
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__
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
// Compilar el shader y dejarlo listo para usar.
|
||||
// Compilar el programa de shaders utilizando std::string
|
||||
programId = compileProgram(vertexShader, fragmentShader);
|
||||
}
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
@@ -249,6 +254,7 @@ namespace shader
|
||||
// Configurar la proyección ortográfica usando el espacio lógico
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
// 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);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL2/SDL_render.h> // para SDL_Texture
|
||||
#include <SDL2/SDL_video.h> // para SDL_Window
|
||||
#include <string>
|
||||
|
||||
// TIPS:
|
||||
// =======================================================================
|
||||
@@ -38,8 +39,7 @@
|
||||
|
||||
namespace shader
|
||||
{
|
||||
const bool init(SDL_Window *win, SDL_Texture *backBuffer,
|
||||
const char *vertexShader, const char *fragmentShader = nullptr);
|
||||
|
||||
//const bool init(SDL_Window *ventana, SDL_Texture *texturaBackBuffer, 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();
|
||||
}
|
||||
@@ -327,7 +327,7 @@ void Screen::initShaders()
|
||||
{
|
||||
loadShaders();
|
||||
}
|
||||
shader::init(window_, game_canvas_, shaderSource.c_str());
|
||||
shader::init(window_, game_canvas_, shaderSource);
|
||||
}
|
||||
|
||||
// Calcula el tamaño de la ventana
|
||||
|
||||
Reference in New Issue
Block a user