Add SHADER_PROGRAM_REFRESH, and a bunch of debug crap because of events.

So when PACKET_SDL_EVENT was SDL_USEREVENT, things worked fine in the
main loop it would see SDL_USEREVENT and send it off to my_SDL_UserEvent.

But when I started adding more events, the SDL_UserEvent paradigm given
in the SDL Wiki stopped working.

The example here is broken: https://wiki.libsdl.org/SDL_AddTimer
The example here is working and "correct": https://wiki.libsdl.org/SDL_UserEvent

All SDL_RegisterEvents is increase a static counter. SDL doesn't
actually use these events anyway. It's purely symbolic, as far as I can tell.

So anyway. Now events work after a bunch of debugging.

SHADER_PROGRAM_REFRESH is the second user event I've done.

The ShaderProgram runs an SDL_TimerID that looks at mVertexPath,
mGeometryPath if present, and mFragmentPath. mVertexPath and
mFragmentPath are required by Compile3ShaderBuffers.
In the future I'd like to change the way this class behaves.
This commit is contained in:
Bubblegumdrop 2022-01-09 23:37:48 -05:00
parent 0fbcdbbabb
commit 2403f060eb
26 changed files with 502 additions and 178 deletions

View File

@ -29,6 +29,7 @@ DEPS := $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
COMMON_OBJS := \
$(OBJDIR)/src/lib_lua_common.o \
$(OBJDIR)/src/lib_SDL_common.o \
$(OBJDIR)/src/lib_SDL_Log.o \
$(OBJDIR)/src/signal_common.o \
$(OBJDIR)/src/UDPbase.o \
$(OBJDIR)/src/UDPpacketVBuffer.o \

View File

@ -5,7 +5,7 @@
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoord;
out vec2 iTexCoord;
out vec2 TexCoords;
uniform mat4 Model;
uniform mat4 View;
@ -13,5 +13,5 @@ uniform mat4 Projection;
void main(void) {
gl_Position = Projection * View * Model * vec4(aPos, 1.0f);
iTexCoord = aTexCoord;
TexCoords = aTexCoord;
}

View File

@ -39,8 +39,8 @@ out vec4 fragColor;
in vec2 TexCoords;
void mainImage(out vec4, in vec2);
void mainImage (out vec4, in vec2);
void main(void) {
mainImage(fragColor, gl_FragCoord.xy);
void main (void) {
mainImage (fragColor, gl_FragCoord.xy);
}

View File

@ -4,11 +4,11 @@
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// Normalized pixel coordinates (from 0 to 1)
// vec2 uv = TexCoords; // fragCoord / iResolution.xy;
vec2 uv = fragCoord / iResolution.xy;
vec2 uv = TexCoords; // fragCoord / iResolution.xy;
// vec2 uv = fragCoord / iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));
vec3 col = 0.5 + 0.5 * cos(iTime + fract (1.5 * (0.5 - uv.xyx) / (0.5 - uv.yxy) + iTime) + vec3(0, 2, 4));
// Output to screen
fragColor = vec4(col, 1.0);

View File

@ -26,7 +26,6 @@ class FileIO
size_t Write (const void *, const size_t);
void Rewind (void);
/* I added these. */
time_t Mtime (void);
off_t Size (void);
std::string ReadToString (void);
};

View File

@ -7,7 +7,7 @@
class UDPbase
{
IPaddress addr;
IPaddress mIPAddress;
public:
UDPbase (const char* host, const Uint16 port);
~UDPbase (void);
@ -17,4 +17,5 @@ class UDPbase
int Bind (UDPsocket sock, const int channel);
void Unbind (UDPsocket sock, const int channel);
std::string toString (void);
IPaddress* GetPeerAddress (UDPsocket sock, const int channel);
};

View File

@ -2,6 +2,38 @@
#include <SDL_net.h>
/**
# UDPpacketVBuffer
Create your `UDPsocket` somewhere:
UDPsocket sock;
...
You have a buffer:
FileIO f (path, "r");
std::string buf = f.ReadToString ();
Allocate a setup packet and set `len` to your MTU, set your destination `address`, and the destination `channel`.
I'm not sure -1 will work as a channel, be sure to set it to your active channel.
UDPpacket* packet = SDL_AllocPacket (buf.length ());
packet->len = DEFAULT_MAX_PACKET_SIZE;
packet->channel = -1;
packet->address = GetPeerAddress (sock, packet->channel);
Use `UDPpacketVBuffer` wrapper to send the data, the destructor will automatically free the `UDPpacket**`:
UDPpacketVBuffer packetV (&buf[0], buf.length ());
packetV.Send (sock);
Then free the leftover setup packet:
SDLNet_FreePacket (packet);
*/
class UDPpacketVBuffer
{
int npackets;

View File

@ -3,5 +3,10 @@
#include <SDL_events.h>
enum {
PACKET_SDL_EVENT = SDL_USEREVENT,
SDL_USEREVENT_FIRST = SDL_USEREVENT,
PACKET_SDL_EVENT,
SHADER_PROGRAM_REFRESH,
SDL_USEREVENT_LAST,
};

15
include/lib_SDL_Log.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include <SDL_assert.h>
#include <SDL_log.h>
#include <SDL_mutex.h>
struct LogWrapper
{
void* userdata;
SDL_mutex* mutex;
SDL_LogOutputFunction fn;
};
// static void my_SDL_Log (void* userdata, int category, SDL_LogPriority priority, const char* message);
void my_SDL_Log_Init (void);

View File

@ -3,20 +3,43 @@
#include <map>
#include <string>
#include <time.h>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <SDL.h>
class ShaderProgram
{
/* TODO there's gotta be a better way of doing this! */
std::string mVertexPath, mGeometryPath, mFragmentPath;
SDL_TimerID mShaderWatchTimer;
/* most recent modification times for the three in order */
time_t mMtime[3];
bool mUniformLocationsNeedRefresh;
std::map<const std::string, GLint> UniformLocationCache;
static GLint my_checkCompileSuccess (const GLuint, const GLenum);
static Uint32 my_WatchShaderHelper (Uint32 interval, void* param);
GLint getCachedLoc (const std::string&);
public:
/*
* Set-able
*/
GLuint ID;
ShaderProgram (const std::string&, const std::string&, const std::string&);
GLint getCachedLoc (const std::string&);
~ShaderProgram (void);
/*
* gl* stuff. These modify the current `ID`.
*/
void RefreshUniformLocations (void);
void Use (void);
void Bool (const std::string&, const bool&);
@ -29,8 +52,22 @@ class ShaderProgram
void Mat3 (const std::string&, const glm::mat3&);
void Mat4 (const std::string&, const glm::mat4&);
/*
* Program/util stuff
*/
GLuint CompileShaderBuffer (const std::string&, const GLenum);
GLuint Compile3ShaderBuffers (const std::string&, const std::string&, const std::string&);
GLuint CompileShaderPath (const std::string&, const GLenum);
GLint LinkProgram (void);
/*
* Monitor the modification time of the loaded shaders
*/
void StartWatchingShader (void);
void StopWatchingShader (void);
bool NeedsReloading (bool);
const std::string& getVertexPath (void) const { return mVertexPath; }
const std::string& getGeometryPath (void) const { return mGeometryPath; }
const std::string& getFragmentPath (void) const { return mFragmentPath; }
};

View File

@ -12,5 +12,3 @@ int util_IsProbablyAscii (const void *, const size_t);
void util_HexDump (const void *, const size_t);
void util_UDP_DumpPacket (UDPpacket*);
UDPpacket** Buffer_To_UDPPacketV (UDPpacket* src, const void* buf, const size_t size);

View File

@ -3,6 +3,7 @@
#include <algorithm>
#include <string>
#include <string.h> /* strerror */
#include <errno.h> /* errno */
#include <stdio.h> /* FILE* */
#include <sys/stat.h> /* stat */
@ -12,12 +13,12 @@
FileIO::FileIO (const std::string& filename, const std::string& mode)
{
if (!(fp = Open (filename, mode)))
throw errno;
throw "FileIO::FileIO: " + std::string (strerror (errno));
path = filename;
}
FileIO::~FileIO(void)
FileIO::~FileIO (void)
{
if (fp)
{
@ -48,22 +49,21 @@ FileIO::Seek (const off_t offset, const int whence)
}
off_t
FileIO::Tell (void)
off_t FileIO::Tell (void)
{
return ftello (fp);
}
size_t
FileIO::Read (void *dst, const size_t size)
FileIO::Read (void* dst, const size_t size)
{
return fread (dst, sizeof (char), size, fp);
}
size_t
FileIO::Write (const void *dst, const size_t size)
FileIO::Write (const void* dst, const size_t size)
{
return fwrite (dst, sizeof (char), size, fp);
}
@ -76,22 +76,7 @@ FileIO::Rewind (void)
}
time_t
FileIO::Mtime (void)
{
time_t rc;
struct stat sb;
rc = 0;
if (!stat (path.c_str (),&sb))
rc = sb.st_mtime;
else
throw errno;
return rc;
}
off_t
FileIO::Size (void)
off_t FileIO::Size (void)
{
off_t rc;
Seek (0, SEEK_END);
@ -101,8 +86,7 @@ FileIO::Size (void)
}
std::string
FileIO::ReadToString (void)
std::string FileIO::ReadToString (void)
{
off_t size = Size ();
std::string b (size, 0);

View File

@ -23,6 +23,8 @@ Server::Server (const char *host, const Uint16 port)
Server::~Server (void)
{
Stop ();
CloseAllSockets ();
if (packetV)
@ -187,7 +189,6 @@ void
Server::ProcessPacketHelper (UDPpacket* src)
{
SDL_Event event;
SDL_UserEvent userevent;
UDPpacket *dst;
dst = SDLNet_AllocPacket (src->len);
@ -200,13 +201,8 @@ Server::ProcessPacketHelper (UDPpacket* src)
SDL_memcpy (dst->data, src->data, src->len);
SDL_zero (event);
SDL_zero (userevent);
userevent.type = PACKET_SDL_EVENT;
userevent.code = 0;
userevent.data1 = (void *) dst;
userevent.data2 = (void *) NULL;
event.type = SDL_USEREVENT;
event.user = userevent;
event.type = PACKET_SDL_EVENT;
event.user.data1 = (void *) dst;
SDL_PushEvent (&event);
}
@ -216,9 +212,10 @@ Uint32 Server::FetchPacketsCallback (Uint32 interval, void *param)
int i, j;
int numrecv, numready;
UDPpacket** packetV;
Server* server;
SDL_assert (NULL != param);
Server* server = (Server *) param;
server = (Server *) param;
if (server->Lock () < 0)
{
@ -226,6 +223,7 @@ Uint32 Server::FetchPacketsCallback (Uint32 interval, void *param)
return 0;
}
/* TODO Make this interruptable */
numready = SDLNet_CheckSockets (server->getSocketSet (), 1);
if (numready < 0)
{

View File

@ -2,7 +2,7 @@
UDPbase::UDPbase (const char* host, const Uint16 port)
{
if (SDLNet_ResolveHost (&addr, host, port) < 0)
if (SDLNet_ResolveHost (&mIPAddress, host, port) < 0)
{
throw "SDLNet_ResolveHost: " + std::string (SDLNet_GetError ());
}
@ -14,29 +14,43 @@ UDPbase::~UDPbase (void)
}
UDPsocket UDPbase::Open (void)
UDPsocket
UDPbase::Open (void)
{
return Open (addr.port);
return Open (mIPAddress.port);
}
UDPsocket UDPbase::Open (const Uint16 port)
UDPsocket
UDPbase::Open (const Uint16 port)
{
IPaddress* addr = NULL;
UDPsocket sock = NULL;
if (NULL == (sock = SDLNet_UDP_Open (port)))
{
throw "SDLNet_UDP_Open: " + std::string (SDLNet_GetError ());
}
if (NULL != (addr = SDLNet_UDP_GetPeerAddress (sock, -1)))
if (NULL != GetPeerAddress (sock, -1))
{
SDL_Log ("Opened UDP port %d", SDLNet_Read16 (&addr->port));
SDL_Log ("Opened UDP port %d", SDLNet_Read16 (&mIPAddress.port));
}
return sock;
}
void UDPbase::Close (UDPsocket sock)
IPaddress*
UDPbase::GetPeerAddress (UDPsocket sock, const int channel)
{
IPaddress* addr = NULL;
if (NULL == (addr = SDLNet_UDP_GetPeerAddress (sock, channel)))
{
throw "SDLNet_UDP_GetPeerAddress: " + std::string (SDLNet_GetError ());
}
return addr;
}
void
UDPbase::Close (UDPsocket sock)
{
SDL_assert (NULL != sock);
SDLNet_UDP_Close (sock);
@ -44,11 +58,12 @@ void UDPbase::Close (UDPsocket sock)
}
int UDPbase::Bind (UDPsocket sock, const int channel)
int
UDPbase::Bind (UDPsocket sock, const int channel)
{
int binding;
SDL_assert (NULL != sock);
if (-1 == (binding = SDLNet_UDP_Bind (sock, channel, &addr)))
if (-1 == (binding = SDLNet_UDP_Bind (sock, channel, &mIPAddress)))
{
throw "SDLNet_UDP_Bind: " + std::string (SDLNet_GetError ());
}
@ -57,7 +72,8 @@ int UDPbase::Bind (UDPsocket sock, const int channel)
}
void UDPbase::Unbind (UDPsocket sock, const int channel)
void
UDPbase::Unbind (UDPsocket sock, const int channel)
{
SDLNet_UDP_Unbind (sock, channel);
}
@ -65,5 +81,6 @@ void UDPbase::Unbind (UDPsocket sock, const int channel)
std::string UDPbase::toString (void)
{
return std::string (SDLNet_ResolveIP (&addr)) + ":" + std::to_string (SDLNet_Read16 (&addr.port));
return std::string (SDLNet_ResolveIP (&mIPAddress)) + ":" +
std::to_string (SDLNet_Read16 (&mIPAddress.port));
}

View File

@ -8,14 +8,14 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
const uint8_t* bufPtr;
const uint8_t* bufPtrEnd;
SDL_assert (NULL != src);
SDL_assert (NULL != buf);
SDL_assert (NULL != src);
mtu = src->len;
SDL_assert (mtu > 0);
npackets = (int) ceil ((double) size / (double) mtu);
// SDL_Log ("%d", npackets);
npackets = (int)ceil ((double) size / (double) mtu);
SDL_Log ("%d", npackets);
if (NULL == (packetV = SDLNet_AllocPacketV (npackets, mtu)))
{
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
@ -23,7 +23,7 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
i = 0;
nsent = size;
bufPtr = (const uint8_t*)buf;
bufPtr = (const uint8_t*) buf;
bufPtrEnd = bufPtr + size;
while ((i < npackets) && (bufPtr < bufPtrEnd) && (nsent > 0))
{

View File

@ -10,6 +10,7 @@
#include "unused.h"
#include "UDPbase.h"
#include "UDPpacketVBuffer.h"
#include "events_common.h"
#include <memory>
#include <vector>
@ -26,16 +27,17 @@
#define MIN_FRAME_MS 7 /* 144 Hz */
static int my_AnalogInput (void);
static int my_Input (SDL_Event *);
static int my_Input_Key (SDL_Event *);
static int my_SDL_WindowEvent (SDL_Event *);
static bool my_AnalogInput (void);
static bool my_Input_Key (SDL_Event*);
static bool my_Input (SDL_Event*);
static bool my_SDL_UserEvent (SDL_Event*);
static bool my_SDL_WindowEvent (SDL_Event*);
static void my_GetOpt (int, char **);
static void my_GetOpt (int, char**);
static void my_Init (int, char**);
static void my_Render (void);
static void my_UpdateValues (void);
static void my_Usage (const char *);
static void my_Usage (const char*);
struct Uniform_Values
{
@ -54,7 +56,7 @@ struct Uniform_Values
struct Client_State
{
int quit;
bool done;
Uint64 start, end;
double diff;
@ -66,7 +68,7 @@ struct Client_State
int mtu;
SDL_GLContext GLContext;
SDL_Window *Window;
SDL_Window* Window;
int Window_Height;
int Window_Width;
@ -91,7 +93,7 @@ static struct Client_State state;
static struct Uniform_Values values;
int
main (int argc, char **argv)
main (int argc, char** argv)
{
glm::mat4 model, view, projection;
SDL_Event event;
@ -114,7 +116,7 @@ main (int argc, char **argv)
quad = std::make_unique<Quad> (1);
state.mtu = 1450;
state.quit = 0;
state.done = false;
client = std::make_unique<UDPbase> (state.host, state.port);
if (NULL == (state.udpsock = client->Open (0)))
{
@ -127,7 +129,7 @@ main (int argc, char **argv)
goto _out;
}
while (!state.quit)
while (!state.done)
{
state.end = SDL_GetPerformanceCounter ();
state.diff = Perf_Diff (state.start, state.end);
@ -142,9 +144,9 @@ main (int argc, char **argv)
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
while (!state.quit && SDL_PollEvent (&event))
while (!state.done && SDL_PollEvent (&event))
{
state.quit = my_Input (&event);
state.done = my_Input (&event);
}
my_AnalogInput ();
@ -234,19 +236,19 @@ my_Render (void)
cube->Draw ();
}
else
quad->Draw ();
quad->Draw ();
}
static int
my_SDL_MouseMotion (SDL_Event * event)
static bool
my_SDL_MouseMotion (SDL_Event* event)
{
SDL_assert (NULL != event);
const float xpos = event->motion.x;
const float ypos = event->motion.y;
if (!state.InputCaptureMouse || state.ImGuiEnabled)
return SDL_FALSE;
return false;
if (state.InputFirstMouse)
{
@ -264,36 +266,34 @@ my_SDL_MouseMotion (SDL_Event * event)
camera.ProcessMouseMovement (Xoffset, Yoffset, 0.1);
return SDL_FALSE;
return false;
}
static int
my_SDL_MouseButton (SDL_Event * event)
static bool
my_SDL_MouseButton (SDL_Event* event)
{
int down;
int quit;
bool done = false;
SDL_assert (NULL != event);
down = event->type == SDL_MOUSEBUTTONDOWN;
quit = SDL_FALSE;
return quit;
return done;
}
static int
my_Input (SDL_Event * event)
static bool
my_Input (SDL_Event* event)
{
int quit;
bool done = false;
SDL_assert (NULL != event);
quit = SDL_FALSE;
switch (event->type)
{
case SDL_QUIT:
quit = SDL_TRUE;
done = true;
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
quit = my_Input_Key (event);
done = my_Input_Key (event);
break;
case SDL_MOUSEMOTION:
my_SDL_MouseMotion (event);
@ -302,17 +302,21 @@ my_Input (SDL_Event * event)
case SDL_MOUSEBUTTONUP:
my_SDL_MouseButton (event);
break;
case SHADER_PROGRAM_REFRESH:
my_SDL_UserEvent (event);
break;
break;
case SDL_WINDOWEVENT:
my_SDL_WindowEvent (event);
break;
default:
break;
}
return quit;
return done;
}
static int
static bool
my_AnalogInput (void)
{
const Uint8* kbd = SDL_GetKeyboardState (NULL);
@ -320,7 +324,7 @@ my_AnalogInput (void)
(void) state;
if (!state.AnalogInputEnabled)
return SDL_FALSE;
return false;
camera.ProcessKeyboard (kbd[SDL_SCANCODE_W] ? Camera::Movement::FORWARD : Camera::Movement::NONE, dt);
camera.ProcessKeyboard (kbd[SDL_SCANCODE_S] ? Camera::Movement::BACKWARD : Camera::Movement::NONE, dt);
@ -332,48 +336,54 @@ my_AnalogInput (void)
camera.ProcessKeyboard (kbd[SDL_SCANCODE_Q] ? Camera::Movement::CW : Camera::Movement::NONE, dt);
camera.ProcessKeyboard (kbd[SDL_SCANCODE_E] ? Camera::Movement::CCW : Camera::Movement::NONE, dt);
return SDL_FALSE;
return false;
}
static int
my_Input_Key (SDL_Event * event)
static bool
my_Input_Key (SDL_Event* event)
{
int down;
int quit;
bool done = false;
SDL_Keycode key;
SDL_assert (NULL != event);
down = event->type == SDL_KEYDOWN;
quit = SDL_FALSE;
key = event->key.keysym.sym;
if (!state.ImpulseInputEnabled)
{
switch (event->key.keysym.sym)
switch (key)
{
case SDLK_i:
state.ImpulseInputEnabled = true;
break;
case SDLK_ESCAPE:
quit = SDL_TRUE;
done = true;
break;
case SDLK_F11:
{
if (down)
{
if (down)
{
state.InputFirstMouse = true;
state.InputCaptureMouse = true;
state.InputRelativeMouseMode = true;
common_SDL_ToggleFullscreen (SDL_GetWindowFromID (event->key.windowID));
}
state.InputFirstMouse = true;
state.InputCaptureMouse = true;
state.InputRelativeMouseMode = true;
common_SDL_ToggleFullscreen (SDL_GetWindowFromID (event->key.windowID));
}
break;
}
break;
default:
break;
}
return SDL_FALSE;
return done;
}
switch (event->key.keysym.sym)
switch (key)
{
case SDLK_ESCAPE:
quit = SDL_TRUE;
done = true;
break;
case SDLK_F11:
{
@ -422,28 +432,61 @@ my_Input_Key (SDL_Event * event)
IPaddress* addr = SDLNet_UDP_GetPeerAddress (state.udpsock, state.channel);
if (addr)
{
SDL_Log ("%s:%d", SDLNet_ResolveIP (addr), SDLNet_Read16(&addr->port));
// SDL_Log ("%s:%d", SDLNet_ResolveIP (addr), SDLNet_Read16(&addr->port));
packet->address = *addr;
UDPpacketVBuffer packetV (packet, (const void*)event, sizeof (SDL_Event));
packetV.Send (state.udpsock);
}
SDLNet_FreePacket (packet);
}
// SDL_Log ("%d %d %ld", state.channel, state.mtu, sizeof (SDL_Event));
// Buffer_Write_UDP (state.udpsock, state.channel, state.mtu, (const void*)event, sizeof (SDL_Event));
}
}
return quit;
return done;
}
static int
my_SDL_WindowEvent (SDL_Event * event)
static bool
my_SDL_UserEvent (SDL_Event* event)
{
int quit;
bool done = false;
SDL_assert (NULL != event);
switch (event->user.type)
{
case SHADER_PROGRAM_REFRESH:
{
SDL_Log ("SHADER_PROGRAM_REFRESH");
/* Actually do the refresh */
GLuint id;
try {
id = shader->Compile3ShaderBuffers (shader->getVertexPath (), shader->getGeometryPath (), shader->getFragmentPath ());
}
catch (const std::string& e)
{
SDL_Log ("%s", e.c_str ());
id = 0;
}
if (id)
{
glUseProgram (0);
glDeleteProgram (shader->ID);
shader->ID = id;
shader->Use ();
shader->NeedsReloading (true);
shader->RefreshUniformLocations ();
}
}
break;
}
return done;
}
static bool
my_SDL_WindowEvent (SDL_Event* event)
{
bool done = false;
SDL_assert (NULL != event);
quit = SDL_FALSE;
switch (event->window.event)
{
case SDL_WINDOWEVENT_RESIZED:
@ -456,19 +499,19 @@ my_SDL_WindowEvent (SDL_Event * event)
default:
break;
}
return quit;
return done;
}
static void
my_Usage (const char *argv0)
my_Usage (const char* argv0)
{
fprintf (stderr, "Usage: %s [-h] [-s host] [-p port]\n", argv0);
}
static void
my_GetOpt (int argc, char **argv)
my_GetOpt (int argc, char** argv)
{
int opt;
state.host = "localhost";

View File

@ -1,3 +1,4 @@
#include "debug.h"
#include "FileIO.h"
#include "lib_SDL_common.h"
#include "lib_GL_common.h"
@ -10,6 +11,8 @@
#include <SDL.h>
#include <SDL_image.h>
static void common_GL_DebugInfo (void);
void
common_GL_Init (SDL_Window * wind, SDL_GLContext * ctx, int SwapInterval)
{
@ -26,6 +29,7 @@ common_GL_Init (SDL_Window * wind, SDL_GLContext * ctx, int SwapInterval)
exit (EXIT_FAILURE);
}
SDL_assert (err == GLEW_OK);
common_GL_DebugInfo ();
glCheckErrors ();
}
@ -102,3 +106,16 @@ common_GL_LoadTexturePath (const char *path)
}
return id;
}
static void common_GL_DebugInfo (void)
{
GLint i, n;
glGetIntegerv (GL_NUM_EXTENSIONS, &n);
for (i = 0; i < n; i++)
{
DEBUG_LOG ("%d %s", i, (const char*)glGetStringi (GL_EXTENSIONS, i));
}
}

24
src/lib_SDL_Log.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "lib_SDL_Log.h"
#include "unused.h"
static struct LogWrapper LogWrapper { };
static void
my_SDL_Log (void* userdata, int category, SDL_LogPriority priority, const char* message)
{
// struct LogWrapper* LogWrapper = (struct LogWrapper*) userdata;
// SDL_assert (NULL != LogWrapper);
UNUSED (userdata);
SDL_LockMutex (LogWrapper.mutex);
LogWrapper.fn (LogWrapper.userdata, category, priority, message);
SDL_UnlockMutex (LogWrapper.mutex);
}
void
my_SDL_Log_Init (void)
{
LogWrapper.mutex = SDL_CreateMutex ();
SDL_LogGetOutputFunction (&LogWrapper.fn, &LogWrapper.userdata);
SDL_LogSetOutputFunction (my_SDL_Log, &LogWrapper);
}

View File

@ -2,6 +2,8 @@
#include "lib_SDL_common.h"
#include "unused.h"
#include "signal_common.h"
#include "lib_SDL_Log.h"
#include "events_common.h"
#include <stdlib.h> /* exit */
@ -16,8 +18,8 @@ my_SDL_Linked_Version (const char* lib, const SDL_version* compile_version, cons
SDL_assert (NULL != lib);
SDL_assert (NULL != compile_version);
SDL_assert (NULL != link_version);
SDL_Log (msg, "compiled", lib, compile_version->major, compile_version->minor, compile_version->patch);
SDL_Log (msg, "linked", lib, link_version->major, link_version->minor, link_version->patch);
DEBUG_LOG (msg, "compiled", lib, compile_version->major, compile_version->minor, compile_version->patch);
DEBUG_LOG (msg, "linked", lib, link_version->major, link_version->minor, link_version->patch);
}
static void
@ -112,7 +114,7 @@ common_SDL_Init (void)
{
Uint32 Flags;
// common_Signal_Init ();
common_Signal_Init ();
Flags = SDL_INIT_EVERYTHING;
if (SDL_Init (Flags) < 0)
@ -120,12 +122,25 @@ common_SDL_Init (void)
SDL_Log ("SDL_Init: %s", SDL_GetError ());
exit (EXIT_FAILURE);
}
/* TODO SDL_GL_SetAttribute */
my_SDL_Log_Init ();
my_SDLNet_Init ();
my_IMG_Init (IMG_INIT_JPG | IMG_INIT_PNG);
my_TTF_Init ();
my_Mix_Init (MIX_INIT_OGG);
SDL_LogSetPriority (SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
my_SDL_Assert_Init ();
Flags = SDL_RegisterEvents (SDL_USEREVENT_LAST - SDL_USEREVENT);
if ( (Flags == ((Uint32)-1)) || (Flags != SDL_USEREVENT_FIRST) )
{
SDL_Log ("SDL_RegisterEvents: %s", SDL_GetError ());
exit (EXIT_FAILURE);
}
}

View File

@ -13,9 +13,9 @@ Quad::Quad (const GLsizei size)
{
// positions // texture coords
// top right
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// bottom right
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
// bottom left
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
// top left

View File

@ -66,7 +66,7 @@ main (int argc, char **argv)
case SDL_QUIT:
done = true;
break;
case SDL_USEREVENT:
case PACKET_SDL_EVENT:
{
done = my_SDL_UserEvent (&ev);
}
@ -99,7 +99,7 @@ my_SDL_UserEvent (SDL_Event * ev)
UDPpacket* packet = (UDPpacket *) ev->user.data1;
if (packet)
{
SDL_Log ("PACKET_SDL_EVENT");
// SDL_Log ("PACKET_SDL_EVENT");
my_ProcessPacket (packet);
SDLNet_FreePacket (packet);
}
@ -286,19 +286,23 @@ static int my_StdinThread(void* param)
{
std::string buf;
UNUSED (param);
_top:
while (!done)
{
my_ShowPrompt ();
try {
my_ShowPrompt ();
while (!done && getline (std::cin, buf))
{
buf = trim (buf);
if (buf.empty () || my_StdinThread_Helper (buf))
if (buf.empty ())
{
goto _top;
}
if (my_StdinThread_Helper (buf))
{
done = true;
break;
}
my_ShowPrompt ();
}
}
catch (std::ifstream::failure& e) {

View File

@ -2,6 +2,13 @@
#include "shader.h"
#include "FileIO.h"
#include "lib_GL_common.h"
#include "events_common.h"
#include "glCheckErrors.h"
#include "util.h"
#include <sys/stat.h> /* stat */
#include <sys/types.h> /* stat */
#include <unistd.h> /* stat */
#include <SDL_assert.h>
@ -13,11 +20,28 @@
#define DEFAULT_FRAGMENT_HEADER "./glsl/header.f.glsl"
ShaderProgram::ShaderProgram (const std::string& vertexPath, const std::string& geometryPath, const std::string& fragmentPath)
: mVertexPath (vertexPath)
, mGeometryPath (geometryPath)
, mFragmentPath (fragmentPath)
{
GLuint id = Compile3ShaderBuffers (vertexPath, geometryPath, fragmentPath);
SDL_memset (&mMtime, 0, sizeof mMtime);
GLuint id = Compile3ShaderBuffers (mVertexPath, mGeometryPath, mFragmentPath);
if (id)
{
ID = id;
NeedsReloading (true);
StartWatchingShader ();
}
}
ShaderProgram::~ShaderProgram (void)
{
StopWatchingShader ();
if (ID)
{
glDeleteProgram (ID);
ID = 0;
}
}
@ -31,19 +55,25 @@ ShaderProgram::Use (void)
GLint ShaderProgram::getCachedLoc (const std::string& name)
{
if (mUniformLocationsNeedRefresh)
RefreshUniformLocations ();
GLint loc;
auto const& ref = UniformLocationCache.find (name);
if (ref == UniformLocationCache.end ())
{
/* It didn't exist */
int loc = glGetUniformLocation (ID, name.c_str ());
if (loc == -1)
/* It didn't exist, have to get it */
loc = glGetUniformLocation (ID, name.c_str ());
if (loc != -1)
{
UniformLocationCache[name] = loc;
}
UniformLocationCache[name] = loc;
}
return UniformLocationCache[name];
else
{
/* Got cache ref */
loc = ref->second;
}
return loc;
}
@ -149,7 +179,7 @@ GLuint ShaderProgram::CompileShaderBuffer (const std::string& buf, const GLenum
glCompileShader (id);
if (!my_checkCompileSuccess (id, type))
{
DEBUG_LOG ("CompileShaderBuffer error");
SDL_Log ("CompileShaderBuffer error");
id = 0;
}
}
@ -162,20 +192,34 @@ GLuint ShaderProgram::Compile3ShaderBuffers (const std::string& vertexPath, cons
{
GLuint vertex, geometry, fragment, id;
glCheckErrors ();
id = glCreateProgram ();
if (!id)
return 0;
glCheckErrors ();
vertex = CompileShaderPath (vertexPath, GL_VERTEX_SHADER);
if (!vertex)
{
SDL_Log ("Compile3ShaderBuffers requires vertex shader");
return 0;
}
glCheckErrors ();
geometry = 0;
if (!geometryPath.empty ())
geometry = CompileShaderPath (geometryPath, GL_GEOMETRY_SHADER);
glCheckErrors ();
FileIO f1 (DEFAULT_FRAGMENT_HEADER, "r");
FileIO f2 (fragmentPath, "r");
std::string buf = f1.ReadToString () + "\n" + f2.ReadToString ();
fragment = CompileShaderBuffer (buf, GL_FRAGMENT_SHADER);
if (!fragment)
{
SDL_Log ("Compile3ShaderBuffers requires fragment shader");
goto _out;
}
if (vertex)
glAttachShader (id, vertex);
@ -186,20 +230,17 @@ GLuint ShaderProgram::Compile3ShaderBuffers (const std::string& vertexPath, cons
glLinkProgram (id);
if (!my_checkCompileSuccess (id, GL_PROGRAM))
{
throw "glLinkProgram error";
id = 0;
}
else
{
RefreshUniformLocations ();
}
_out:
glDeleteShader (vertex);
glDeleteShader (geometry);
glDeleteShader (fragment);
if (!my_checkCompileSuccess (id, GL_PROGRAM))
{
glDeleteProgram (id);
id = 0;
}
return id;
}
@ -223,15 +264,15 @@ ShaderProgram::my_checkCompileSuccess (const GLuint id, const GLenum type)
case GL_FRAGMENT_SHADER:
typeName = "GL_FRAGMENT_SHADER";
HANDLE_SHADER:
glGetShaderiv (id, GL_COMPILE_STATUS,&success);
glGetShaderiv (id, GL_COMPILE_STATUS, &success);
if (GL_FALSE == success)
glGetShaderiv (id, GL_INFO_LOG_LENGTH,&infoLogLength);
glGetShaderiv (id, GL_INFO_LOG_LENGTH, &infoLogLength);
break;
case GL_PROGRAM:
typeName = "PROGRAM";
glGetProgramiv (id, GL_LINK_STATUS,&success);
glGetProgramiv (id, GL_LINK_STATUS, &success);
if (GL_FALSE == success)
glGetProgramiv (id, GL_INFO_LOG_LENGTH,&success);
glGetProgramiv (id, GL_INFO_LOG_LENGTH, &success);
break;
default:
break;
@ -256,7 +297,65 @@ ShaderProgram::my_checkCompileSuccess (const GLuint id, const GLenum type)
}
if (infoLog[0] != '\0')
{
DEBUG_LOG ("%8s ERROR ============================================================\n%s", typeName.c_str (), infoLog.c_str ());
DEBUG_LOG ("%8s ERROR\n%s", typeName.c_str (), infoLog.c_str ());
}
return success;
}
bool
ShaderProgram::NeedsReloading (bool update)
{
bool needs = false;
time_t mtime[3];
struct stat sb;
SDL_memset (&mtime, 0, sizeof mtime);
if (!stat (mVertexPath.c_str (), &sb)) mtime[0] = sb.st_mtime;
if (!stat (mGeometryPath.c_str (), &sb)) mtime[1] = sb.st_mtime;
if (!stat (mFragmentPath.c_str (), &sb)) mtime[2] = sb.st_mtime;
needs = (mMtime[0] < mtime[0]) || (mMtime[1] < mtime[1]) || (mMtime[2] < mtime[2]);
// SDL_Log ("%ld %ld %ld %ld %ld %ld %d", mMtime[0], mMtime[1], mMtime[2], mtime[0], mtime[1], mtime[2], needs);
if (update) {
mMtime[0] = mtime[0];
mMtime[1] = mtime[1];
mMtime[2] = mtime[2];
}
return needs;
}
Uint32 ShaderProgram::my_WatchShaderHelper (Uint32 interval, void* param)
{
SDL_Event event;
ShaderProgram* shader;
SDL_assert (NULL != param);
shader = (ShaderProgram*) param;
if (shader->NeedsReloading (false))
{
SDL_zero (event);
event.type = SHADER_PROGRAM_REFRESH;
SDL_PushEvent (&event);
}
return interval;
}
void ShaderProgram::StartWatchingShader (void)
{
mShaderWatchTimer = SDL_AddTimer (1000, ShaderProgram::my_WatchShaderHelper, (void *) this);
}
void ShaderProgram::StopWatchingShader (void)
{
SDL_RemoveTimer (mShaderWatchTimer);
}

View File

@ -4,6 +4,7 @@
#include <stdio.h> /* fputs */
#include <signal.h> /* struct sigaction */
#include <stdlib.h> /* exit */
#include <string.h> /* strsignal */
#include <SDL.h>
@ -20,6 +21,7 @@ my_Signal_Handler (int sig, siginfo_t* si, void* uap)
UNUSED (sig);
UNUSED (uap);
UNUSED (si);
SDL_Log ("Got %s", strsignal (sig));
SDL_PushEvent (&QUIT_EVENT);
if (signal_requested++ > 0)
{

View File

@ -79,9 +79,9 @@ util_UDP_DumpPacket (UDPpacket* packet)
if (packet->len > 0)
{
buf = (const uint8_t*)packet->data;
// if (util_IsProbablyAscii (buf, packet->len))
// SDL_Log ("data:\n%s\n", buf);
// else
if (util_IsProbablyAscii (buf, packet->len))
SDL_Log ("data:\n%s\n", buf);
else
util_HexDump (buf, packet->len);
}
else

View File

@ -1,13 +1,13 @@
#include "FileIO.h"
#include "util.h"
#include <string>
#include <iostream>
#include <stdint.h> /* uint8_t */
#include <stdio.h>
#include <math.h>
#include <errno.h> /* errno */
#include <string.h> /* strerror */
int
main (int argc, char **argv)
{
@ -20,15 +20,15 @@ main (int argc, char **argv)
FileIO f (argv[argc], "r");
std::string buf = f.ReadToString ();
if (util_IsProbablyAscii (buf.c_str (), buf.size ()))
printf ("%s", buf.c_str ());
std::cout << buf << std::endl;
else
util_HexDump (buf.c_str (), buf.size ());
rc = 0;
}
}
catch (int err)
catch (const std::string& e)
{
puts (strerror (errno));
std::cerr << e << std::endl;
}
return rc;

View File

@ -1,24 +1,57 @@
#include "lib_lua_common.h"
#include "trim.h"
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char** argv)
static const char* prompt_str = "> ";
static void my_ShowPrompt (void)
{
char buf[8192];
printf ("\n%s", prompt_str);
fflush (stdout);
}
int main (int argc, char** argv)
{
std::string buf;
bool done = false;
lua_State* L;
L = luaL_newstate ();
luaL_openlibs (L);
while (fgets (buf, 8191, stdin))
while (!done)
{
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = 0;
if (strlen (buf) > 0)
my_ShowPrompt ();
try
{
printf (" => ");
fflush (stdout);
common_lua_run (L, "line", buf, strlen (buf));
getline (std::cin, buf);
}
catch (std::ifstream::failure& e)
{
done = true;
break;
}
if (std::cin.eof ())
{
done = true;
break;
}
buf = trim (buf);
if (buf.empty ())
{
std::cin.clear();
std::cin.ignore();
continue;
}
printf (" => ");
fflush (stdout);
common_lua_run (L, "line", buf.c_str (), buf.length ());
}
lua_close (L);
return 0;
}