diff --git a/data/basic.glsl b/data/basic.glsl deleted file mode 100644 index 08c3f69..0000000 --- a/data/basic.glsl +++ /dev/null @@ -1,32 +0,0 @@ -varying vec2 TEX0; - -#if defined(VERTEX) - -void main() -{ - TEX0 = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; -} - -#elif defined(FRAGMENT) - -uniform sampler2D Texture; - -void main() -{ - vec2 winsize = vec2(640.0,480.0); - vec2 pixpos = TEX0 * winsize; - float y = floor(pixpos.y); - if (mod(y,4.0) == 0.0) - { - vec4 color = texture2D(Texture, TEX0); - vec4 blend = vec4(0.8, 0.8, 0.8, 1.0); - gl_FragColor = color * blend; - } - else - { - gl_FragColor = texture2D(Texture, TEX0); - } -} - -#endif \ No newline at end of file diff --git a/data/game.ini b/data/game.ini index 397f023..74de424 100644 --- a/data/game.ini +++ b/data/game.ini @@ -1,5 +1,5 @@ -title=HOLA MINI -config=minitest +title=PAKU SIMBEL PROFANATION +config=paku width=160 -height=120 -zoom=3 +height=144 +zoom=4 diff --git a/data/gbc.glsl b/data/gbc.glsl new file mode 100644 index 0000000..8dc26f2 --- /dev/null +++ b/data/gbc.glsl @@ -0,0 +1,38 @@ +varying vec2 tex_coord; +varying vec2 pix_coord; + +#if defined(VERTEX) + +void main() +{ + pix_coord = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001; + tex_coord = vec2((gl_Vertex.x+1.0)*0.5, (-gl_Vertex.y+1.0)*0.5); + vec4 pos = vec4(gl_Vertex.x * 2.0, gl_Vertex.y * 2.0, gl_Vertex.z, gl_Vertex.w); + gl_Position = gl_Vertex; //(gl_Vertex*2)-vec3(1.0, 1.0, 1.0);//gl_ModelViewProjectionMatrix * gl_Vertex; +} + +#elif defined(FRAGMENT) + +uniform sampler2D Texture; + +void main() +{ + float x = sign(pix_coord.x)*floor(abs(pix_coord.x)+0.5); + float y = sign(pix_coord.y)*floor(abs(pix_coord.y)+0.5); + float column = mod(x,4.0); + float row = mod(y,4.0); + vec4 color = texture2D(Texture, tex_coord); + vec4 newcolor; + if ((column == 0.0) || (row == 0.0) ) { + newcolor = color * vec4(0.4, 0.4, 0.4, 1.0); + } else if ((column == 1.0) || (row == 1.0) ) { + newcolor = color * vec4(0.6, 0.7, 0.8, 1.0); + } else if ((column == 3.0) || (row == 3.0) ) { + newcolor = color * vec4(0.8, 0.7, 0.6, 1.0); + } else { + newcolor = color; + } + gl_FragColor = newcolor; +} + +#endif \ No newline at end of file diff --git a/data/logo.gif b/data/logo.gif new file mode 100644 index 0000000..9c53b04 Binary files /dev/null and b/data/logo.gif differ diff --git a/data/lynx.glsl b/data/lynx.glsl new file mode 100644 index 0000000..693ac4b --- /dev/null +++ b/data/lynx.glsl @@ -0,0 +1,37 @@ +varying vec2 tex_coord; +varying vec2 pix_coord; + +#if defined(VERTEX) + +void main() +{ + pix_coord = vec2(gl_MultiTexCoord0.x, 1.0-gl_MultiTexCoord0.y)*1.0001; + tex_coord = vec2((gl_Vertex.x+1.0)*0.5, (-gl_Vertex.y+1.0)*0.5); + vec4 pos = vec4(gl_Vertex.x * 2.0, gl_Vertex.y * 2.0, gl_Vertex.z, gl_Vertex.w); + gl_Position = gl_Vertex; //(gl_Vertex*2)-vec3(1.0, 1.0, 1.0);//gl_ModelViewProjectionMatrix * gl_Vertex; +} + +#elif defined(FRAGMENT) + +uniform sampler2D Texture; + +void main() +{ + float x = sign(pix_coord.x)*floor(abs(pix_coord.x)+0.5); + float column = mod(x,4.0); + vec4 color = texture2D(Texture, tex_coord); + color = color + vec4(0.5, 0.5, 0.5, 0.0) * (1.0-tex_coord.t); + vec4 newcolor; + if (column == 0.0) { + newcolor = color * vec4(1.0, 0.4, 0.6, 1.0); + } else if (column == 1.0) { + newcolor = color * vec4(0.4, 1.0, 0.4, 1.0); + } else if (column == 2.0) { + newcolor = color * vec4(0.6, 0.4, 1.0, 1.0); + } else { + newcolor = color * vec4(0.2, 0.2, 0.2, 1.0); + } + gl_FragColor = newcolor; +} + +#endif \ No newline at end of file diff --git a/data/main.lua b/data/main.lua index d40a3a2..5d59710 100644 --- a/data/main.lua +++ b/data/main.lua @@ -3,16 +3,30 @@ other = require "other" x=0 function mini.init() - s = surf.load("tiles01.gif") + s = surf.load("logo.gif") surf.source(s) - p = pal.load("tiles01.gif") + p = pal.load("logo.gif") pal.set(p) pal.trans(255) end function mini.update() - surf.cls(1) - draw.surf(0, 0, 64, 64, 10, 10) - if key.down(key.ESCAPE) then sys.quit() end - draw.text(sys.fps(), 0, 0, 4) + surf.cls(0) + draw.surf(0, 0, 160, 144, 0, 0) + + draw.text("PRESS START", 60, 110, 28) + if key.press(key.ESCAPE) then sys.quit() end + draw.text(sys.fps(), 1, 1, 28) + + if key.press(key.N1) then + shader.init("lynx.glsl") + shader.enable() + end + if key.press(key.N2) then + shader.init("gbc.glsl") + shader.enable() + end + if key.press(key.N3) then + shader.disable() + end end diff --git a/jfile.cpp b/jfile.cpp index 4fc7adf..9529c4f 100644 --- a/jfile.cpp +++ b/jfile.cpp @@ -130,10 +130,11 @@ FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool bi return f; } -char *file_getfilebuffer(const char *resourcename, int& filesize) { +char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zero_terminate) { FILE *f = file_getfilepointer(resourcename, filesize, true); - char* buffer = (char*)malloc(filesize); + char* buffer = (char*)malloc(zero_terminate?filesize:filesize+1); fread(buffer, filesize, 1, f); + if (zero_terminate) buffer[filesize]=0; fclose(f); return buffer; } diff --git a/jfile.h b/jfile.h index 560d602..9fe6c9b 100644 --- a/jfile.h +++ b/jfile.h @@ -12,7 +12,7 @@ void file_setresourcefolder(const char *str); void file_setsource(const int src); FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false); -char *file_getfilebuffer(const char *resourcename, int& filesize); +char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zero_terminate=false); const char* file_getconfigvalue(const char *key); void file_setconfigvalue(const char* key, const char* value); diff --git a/jshader.cpp b/jshader.cpp index 36e240a..4cd5e38 100644 --- a/jshader.cpp +++ b/jshader.cpp @@ -24,7 +24,8 @@ namespace shader SDL_Texture* backBuffer = nullptr; SDL_Point win_size = {640, 480}; SDL_FPoint tex_size = {320, 240}; - bool usingOpenGL; + bool can_use_opengl = false; + bool using_opengl = false; GLuint texture_number; GLuint nose; @@ -40,11 +41,13 @@ namespace shader PFNGLDELETESHADERPROC glDeleteShader; PFNGLATTACHSHADERPROC glAttachShader; PFNGLCREATEPROGRAMPROC glCreateProgram; + PFNGLDELETEPROGRAMPROC glDeleteProgram; PFNGLLINKPROGRAMPROC glLinkProgram; PFNGLVALIDATEPROGRAMPROC glValidateProgram; PFNGLGETPROGRAMIVPROC glGetProgramiv; PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; PFNGLUSEPROGRAMPROC glUseProgram; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; bool initGLExtensions() { glCreateShader = (PFNGLCREATESHADERPROC)SDL_GL_GetProcAddress("glCreateShader"); @@ -55,16 +58,18 @@ namespace shader glDeleteShader = (PFNGLDELETESHADERPROC)SDL_GL_GetProcAddress("glDeleteShader"); glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader"); glCreateProgram = (PFNGLCREATEPROGRAMPROC)SDL_GL_GetProcAddress("glCreateProgram"); + glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram"); glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram"); glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)SDL_GL_GetProcAddress("glValidateProgram"); glGetProgramiv = (PFNGLGETPROGRAMIVPROC)SDL_GL_GetProcAddress("glGetProgramiv"); glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)SDL_GL_GetProcAddress("glGetProgramInfoLog"); glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram"); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)SDL_GL_GetProcAddress("glGetUniformLocation"); return glCreateShader && glShaderSource && glCompileShader && glGetShaderiv && glGetShaderInfoLog && glDeleteShader && glAttachShader && glCreateProgram && - glLinkProgram && glValidateProgram && glGetProgramiv && glGetProgramInfoLog && - glUseProgram; + glDeleteProgram && glLinkProgram && glValidateProgram && glGetProgramiv && + glGetProgramInfoLog && glUseProgram && glGetUniformLocation; } #endif @@ -92,6 +97,7 @@ namespace shader GLchar *log = (GLchar*)malloc(logLength); glGetShaderInfoLog(result, logLength, &logLength, log); std::cout << "Shader compile log:" << log << std::endl; + //std::cout << source << std::endl; free(log); } glDeleteShader(result); @@ -105,7 +111,9 @@ namespace shader GLuint programId = 0; GLuint vtxShaderId, fragShaderId; + if (programId != 0) glDeleteProgram(programId); programId = glCreateProgram(); + vtxShaderId = compileShader(vertexShaderSource, GL_VERTEX_SHADER); fragShaderId = compileShader(fragmentShaderSource?fragmentShaderSource:vertexShaderSource, GL_FRAGMENT_SHADER); @@ -161,25 +169,36 @@ namespace shader if(!strncmp(renderer_name, "opengl", 6)) { #ifndef __APPLE__ - if (!initGLExtensions()) { - std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl; - usingOpenGL = false; - return false; + static bool gl_extensions_initialized = false; + if (!gl_extensions_initialized) { + if (!initGLExtensions()) { + std::cout << "WARNING: No s'han pogut inicialitzar les extensions d'OpenGL!" << std::endl; + can_use_opengl = false; + return false; + } + gl_extensions_initialized = true; } #endif // Compilar el shader y dejarlo listo para usar. + if (!vertexShader) { + can_use_opengl = false; + return false; + } programId = compileProgram(vertexShader, fragmentShader); } else { std::cout << "WARNING: El driver del renderer no es OpenGL." << std::endl; - usingOpenGL = false; + can_use_opengl = false; return false; } - usingOpenGL = true; + can_use_opengl = true; return true; } unsigned char pixels[512*240*4]; + void enable() { if (can_use_opengl) using_opengl = true; } + void disable() { using_opengl = false; } + void render() { SDL_FlushRenderer(renderer); @@ -188,7 +207,7 @@ namespace shader SDL_RenderClear(renderer); SDL_FlushRenderer(renderer); - if (usingOpenGL) + if (using_opengl) { GLint oldProgramId; if (programId != 0) @@ -206,16 +225,16 @@ namespace shader //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, ¶m); //printf("tex width: %i\n", param); glViewport(0, 0, win_size.x, win_size.y); - + glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(0.0f, 0.0f); - glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); - glVertex2f(tex_size.x, 0.0f); - glTexCoord2f(0.0f, 1.0f); - glVertex2f(0.0f, tex_size.y); - glTexCoord2f(1.0f, 1.0f); - glVertex2f(tex_size.x, tex_size.y); + glVertex2f(-1.0f, -1.0f); + glTexCoord2f(tex_size.x, 0.0f); + glVertex2f(1.0f, -1.0f); + glTexCoord2f(0.0f, tex_size.y); + glVertex2f(-1.0f, 1.0f); + glTexCoord2f(tex_size.x, tex_size.y); + glVertex2f(1.0f, 1.0f); glEnd(); SDL_GL_SwapWindow(win); diff --git a/jshader.h b/jshader.h index f2dc8e3..f0f6a03 100644 --- a/jshader.h +++ b/jshader.h @@ -40,5 +40,9 @@ namespace shader const bool init(SDL_Window* win, SDL_Texture* backBuffer, const char* vertexShader, const char* fragmentShader=nullptr); + + void enable(); + void disable(); + void render(); } diff --git a/lua.cpp b/lua.cpp index ff8d27d..4dfadf7 100644 --- a/lua.cpp +++ b/lua.cpp @@ -527,6 +527,27 @@ extern "C" { } + // shaders + // =============================================== + + static int cpp_shader_init(lua_State *L) { + const char* vstr = luaL_optstring(L, 1, NULL); + const char* fstr = luaL_optstring(L, 2, NULL); + shader_init(vstr, fstr); + return 0; + } + + static int cpp_shader_enable(lua_State *L) { + shader_enable(); + return 0; + } + + static int cpp_shader_disable(lua_State *L) { + shader_disable(); + return 0; + } + + // music // =============================================== @@ -875,6 +896,12 @@ void push_lua_funcs() { lua_pushcfunction(L,cpp_draw_text); lua_setfield(L, -2, "text"); lua_setglobal(L, "draw"); + lua_newtable(L); + lua_pushcfunction(L,cpp_shader_init); lua_setfield(L, -2, "init"); + lua_pushcfunction(L,cpp_shader_enable); lua_setfield(L, -2, "enable"); + lua_pushcfunction(L,cpp_shader_disable); lua_setfield(L, -2, "disable"); + lua_setglobal(L, "shader"); + lua_newtable(L); lua_pushcfunction(L,cpp_music_play); lua_setfield(L, -2, "play"); lua_pushcfunction(L,cpp_music_pause); lua_setfield(L, -2, "pause"); diff --git a/mini.cpp b/mini.cpp index c6e7acc..7d23fa3 100644 --- a/mini.cpp +++ b/mini.cpp @@ -298,11 +298,24 @@ uint8_t getmap() return 0; } +void shader_init(const char* vshader, const char* fshader) +{ + int filesize; + char *vshaderfile = file_getfilebuffer(vshader, filesize, true); + + char *fshaderfile = nullptr; + if (fshader) { fshaderfile = file_getfilebuffer(fshader, filesize, true); } + shader::init(mini_win, mini_shadertex, vshaderfile, fshaderfile); +} + +void shader_enable() { shader::enable(); } +void shader_disable() { shader::disable(); } + void createDisplay() { if (screen_zoom <= 0) screen_zoom = 1; while (screen_width*screen_zoom > desktop_width || screen_height*screen_zoom > desktop_height) screen_zoom--; - mini_win = SDL_CreateWindow(window_title, screen_width*screen_zoom, screen_height*screen_zoom, SDL_WINDOW_OPENGL|(screen_fullscreen?SDL_WINDOW_FULLSCREEN:SDL_WINDOW_RESIZABLE)); + mini_win = SDL_CreateWindow(window_title, screen_width*screen_zoom, screen_height*screen_zoom, SDL_WINDOW_OPENGL|(screen_fullscreen?SDL_WINDOW_FULLSCREEN:0)); windowID = SDL_GetWindowID(mini_win); SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); mini_ren = SDL_CreateRenderer(mini_win, NULL); @@ -320,9 +333,9 @@ void createDisplay() { mini_shadertex = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, screen_width*screen_zoom, screen_height*screen_zoom); SDL_SetTextureScaleMode(mini_shadertex, SDL_SCALEMODE_NEAREST); - int filesize; - char *shaderfile = file_getfilebuffer("basic.glsl", filesize); - shader::init(mini_win, mini_shadertex, shaderfile); + //int filesize; + //char *shaderfile = file_getfilebuffer("lynx.glsl", filesize); + shader::init(mini_win, mini_shadertex, nullptr); //SDL_GetWindowPosition(mini_win, &windowpos_x, &windowpos_y); } diff --git a/mini.h b/mini.h index 8c52b28..0e716bd 100644 --- a/mini.h +++ b/mini.h @@ -129,6 +129,10 @@ void setsource(uint8_t surface); void setmap(uint8_t surface); uint8_t getmap(); +void shader_init(const char* vshader, const char* fshader); +void shader_enable(); +void shader_disable(); + void cls(uint8_t color=0); void color(uint8_t color=6); void bcolor(uint8_t color=0); diff --git a/vscode/library.lua b/vscode/library.lua index b590793..86b3f2d 100644 --- a/vscode/library.lua +++ b/vscode/library.lua @@ -268,6 +268,27 @@ function draw.surfrot(sx, sy, sw, sh, x, y, a) end ---Draw text to (x,y) using the specified color function draw.text(text, x, y, color) end +---@class shader +shader = {} + +---Initialize shaders subsystem, still non functional without shaders +function shader.init() end + +---@param shader string +---Initialize shaders subsystem, specifying a file that contains both vertex and fragment shader +function shader.init(shader) end + +---@param vshader string +---@param fshader string +---Initialize shaders subsystem, specifying both a vertex shader file and a fragment shader file +function shader.init(vshader, fshader) end + +---Enable previously loaded shader +function shader.enable() end + +---Disable shaders +function shader.disable() end + ---@class music music = {}