Initial commit.
Another nuke! This time, trying to do a client <-> server thing. Also a bit of messing with Lua.
This commit is contained in:
commit
46b2ed80ae
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.d/
|
||||
.o/
|
||||
imgui/
|
||||
main_client
|
||||
main_server
|
||||
*.png
|
||||
res/
|
190
Makefile
Normal file
190
Makefile
Normal file
@ -0,0 +1,190 @@
|
||||
.PHONY: all clean
|
||||
.POSIX:
|
||||
|
||||
# {{{ Flags
|
||||
SRCDIR := src
|
||||
OBJDIR := .o
|
||||
DEPDIR := .d
|
||||
TESTDIR := test
|
||||
MKDIR := mkdir -p
|
||||
# }}}
|
||||
|
||||
PROGS := main_client main_server
|
||||
|
||||
IMGUI_INCLUDE := -Iimgui -Iimgui/backends
|
||||
IMGUI_SRCS := \
|
||||
imgui/backends/imgui_impl_glfw.cpp \
|
||||
imgui/backends/imgui_impl_opengl3.cpp \
|
||||
imgui/imgui.cpp \
|
||||
imgui/imgui_demo.cpp \
|
||||
imgui/imgui_draw.cpp \
|
||||
imgui/imgui_tables.cpp \
|
||||
imgui/imgui_widgets.cpp
|
||||
|
||||
SRCS := $(wildcard $(SRCDIR)/*.cpp) $(IMGUI_SRCS)
|
||||
OBJS := $(patsubst %,$(OBJDIR)/%.o,$(basename $(SRCS)))
|
||||
DEPS := $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
|
||||
|
||||
$(shell $(MKDIR) $(dir $(OBJS)) >/dev/null)
|
||||
$(shell $(MKDIR) $(dir $(DEPS)) >/dev/null)
|
||||
|
||||
COMMON_OBJS := \
|
||||
$(OBJDIR)/src/lib_lua_common.o \
|
||||
$(OBJDIR)/src/lib_SDL_common.o \
|
||||
$(OBJDIR)/src/signal_common.o
|
||||
|
||||
SERVER_OBJS := \
|
||||
$(OBJDIR)/src/server_main.o \
|
||||
$(OBJDIR)/src/Server.o \
|
||||
$(COMMON_OBJS)
|
||||
|
||||
CLIENT_OBJS := \
|
||||
$(OBJDIR)/src/camera.o \
|
||||
$(OBJDIR)/src/client_common.o \
|
||||
$(OBJDIR)/src/client_main.o \
|
||||
$(OBJDIR)/src/Client.o \
|
||||
$(OBJDIR)/src/cube.o \
|
||||
$(OBJDIR)/src/FileIO.o \
|
||||
$(OBJDIR)/src/lib_GL_common.o \
|
||||
$(OBJDIR)/src/object.o \
|
||||
$(OBJDIR)/src/quad.o \
|
||||
$(OBJDIR)/src/shader.o \
|
||||
$(OBJDIR)/src/UDP_Write.o \
|
||||
$(COMMON_OBJS)
|
||||
|
||||
IMGUI_OBJS := $(patsubst %,$(OBJDIR)/%.o,$(basename $(IMGUI_SRCS)))
|
||||
|
||||
TEST_OBJ_COMMON := \
|
||||
$(OBJDIR)/src/FileIO.o \
|
||||
$(COMMON_OBJS)
|
||||
|
||||
|
||||
TESTS := test_FileIO test_File_Write_UDP test_Object test_lua
|
||||
TEST_PROGS := $(addprefix $(TESTDIR)/,$(TESTS))
|
||||
|
||||
# {{{ Flags
|
||||
CC := gcc
|
||||
CXX := g++
|
||||
LD := g++
|
||||
ifeq ($(CLANG),1)
|
||||
CC := clang-12
|
||||
CXX := clang++-12
|
||||
LD := clang-12
|
||||
endif
|
||||
|
||||
SRCDIR := src
|
||||
OBJDIR := .o
|
||||
DEPDIR := .d
|
||||
|
||||
RM := rm -rf
|
||||
|
||||
PKGS := SDL2_image SDL2_mixer SDL2_ttf SDL2_net sdl2 gl glew lua54
|
||||
CPPFLAGS := $(shell pkg-config --cflags $(PKGS))
|
||||
LDLIBS := $(shell pkg-config --libs $(PKGS)) -lm
|
||||
|
||||
DEFS := -D_FILE_OFFSET_BITS=64
|
||||
INCS := -Iinclude $(IMGUI_INCLUDE)
|
||||
|
||||
DEBUG := -g
|
||||
ifeq ($(D),1)
|
||||
DEBUG := -ggdb
|
||||
OPT := -O0
|
||||
DEFS += -DDEBUG=1
|
||||
endif
|
||||
|
||||
OPT := -O0
|
||||
ifeq ($(O),1)
|
||||
OPT := -O1 -g
|
||||
endif
|
||||
ifeq ($(O),2)
|
||||
OPT := -O2 -g
|
||||
endif
|
||||
ifeq ($(O),3)
|
||||
OPT := -O3 -g0
|
||||
endif
|
||||
|
||||
ifeq ($(LTO),1)
|
||||
LDFLAGS += -flto -fwhole-program
|
||||
endif
|
||||
|
||||
ifeq ($(PG),1)
|
||||
CFLAGS += -pg -coverage
|
||||
endif
|
||||
|
||||
ifeq ($(PEDANTIC),1)
|
||||
CFLAGS += -pedantic
|
||||
endif
|
||||
|
||||
CFLAGS += -std=c99
|
||||
CXXFLAGS += -std=c++14
|
||||
CPPFLAGS += -fPIC -W -Wextra -Wall $(DEFS) $(DEBUG) $(INCS) $(OPT)
|
||||
|
||||
# flags required for dependency generation; passed to compilers
|
||||
DEPFLAGS = -MT $@ -MD -MP -MF $(DEPDIR)/$*.Td
|
||||
|
||||
# compile C source files
|
||||
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o $@
|
||||
# compile C++ source files
|
||||
COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -o $@
|
||||
# link object files to binary
|
||||
LINK.o = $(LD) $(LDFLAGS) -o $@
|
||||
LINK.so = $(LD) $(LDFLAGS) -o $@ -shared
|
||||
# precompile step
|
||||
PRECOMPILE =
|
||||
# postcompile step
|
||||
POSTCOMPILE = mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d
|
||||
|
||||
# }}}
|
||||
|
||||
.SUFFIXES: .c .cc .cpp .cxx .o .1
|
||||
|
||||
all: $(OBJS) $(PROGS)
|
||||
|
||||
main_client: $(CLIENT_OBJS)
|
||||
$(LINK.o) $^ $(LDLIBS)
|
||||
|
||||
main_server: $(SERVER_OBJS)
|
||||
$(LINK.o) $^ $(LDLIBS)
|
||||
|
||||
test: $(TEST_PROGS)
|
||||
|
||||
test/test_FileIO: $(TEST_OBJ_COMMON)
|
||||
|
||||
test/test_File_Write_UDP: $(TEST_OBJ_COMMON) $(OBJDIR)/src/client_common.o $(OBJDIR)/src/UDP_Write.o $(OBJDIR)/src/Client.o
|
||||
|
||||
test/test_Object: $(TEST_OBJ_COMMON) $(OBJDIR)/src/object.o $(OBJDIR)/src/quad.o $(OBJDIR)/src/cube.o $(OBJDIR)/src/lib_GL_common.o
|
||||
|
||||
test/test_lua: $(TEST_OBJ_COMMON) $(OBJDIR)/src/lib_lua_common.o
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
$(OBJDIR)/%.o: %.c $(DEPDIR)/%.d
|
||||
$(PRECOMPILE)
|
||||
$(COMPILE.c) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
$(OBJDIR)/%.o: %.cpp $(DEPDIR)/%.d
|
||||
$(PRECOMPILE)
|
||||
$(COMPILE.cc) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
$(OBJDIR)/%.o: %.cc
|
||||
$(OBJDIR)/%.o: %.cc $(DEPDIR)/%.d
|
||||
$(PRECOMPILE)
|
||||
$(COMPILE.cc) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
$(OBJDIR)/%.o: %.cxx
|
||||
$(OBJDIR)/%.o: %.cxx $(DEPDIR)/%.d
|
||||
$(PRECOMPILE)
|
||||
$(COMPILE.cc) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
clean:
|
||||
@echo $(RM) $(DEPDIR) $(OBJDIR) $(PROGS)
|
||||
@echo $(RM) $(TEST_PROGS)
|
||||
|
||||
.PRECIOUS: $(DEPDIR)/%.d
|
||||
$(DEPDIR)/%.d: ;
|
||||
|
||||
-include $(DEPS)
|
46
glsl/header.f.glsl
Normal file
46
glsl/header.f.glsl
Normal file
@ -0,0 +1,46 @@
|
||||
/* vim: set ft=c: */
|
||||
|
||||
#version 440 core
|
||||
|
||||
uniform float iChannelTime[4];
|
||||
uniform float iFrameRate;
|
||||
uniform float iSampleRate;
|
||||
uniform float iTime;
|
||||
uniform float iTimeDelta;
|
||||
uniform int iFrame;
|
||||
uniform vec3 iChannelResolution[4];
|
||||
uniform vec3 iResolution;
|
||||
uniform vec4 iDate;
|
||||
uniform vec4 iMouse;
|
||||
|
||||
uniform sampler2D iChannel0;
|
||||
uniform sampler2D iChannel1;
|
||||
uniform sampler2D iChannel2;
|
||||
uniform sampler2D iChannel3;
|
||||
|
||||
/*
|
||||
TODO: Generate this section
|
||||
uniform sampler2D iChannel0;
|
||||
uniform samplerCube iChannel0;
|
||||
uniform sampler3D iChannel0;
|
||||
uniform sampler2D iChannel0;
|
||||
|
||||
uniform struct {
|
||||
sampler2D sampler;
|
||||
samplerCube sampler;
|
||||
sampler3D sampler;
|
||||
vec3 size;
|
||||
float time;
|
||||
int loaded;
|
||||
} iCh0;
|
||||
*/
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 TexCoords;
|
||||
|
||||
void mainImage(out vec4, in vec2);
|
||||
|
||||
void main(void) {
|
||||
mainImage(fragColor, gl_FragCoord.xy);
|
||||
}
|
15
glsl/new.f.glsl
Normal file
15
glsl/new.f.glsl
Normal file
@ -0,0 +1,15 @@
|
||||
/* vim: set ft=c: */
|
||||
|
||||
/* <https://www.shadertoy.com/new> */
|
||||
|
||||
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;
|
||||
|
||||
// Time varying pixel color
|
||||
vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));
|
||||
|
||||
// Output to screen
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
21
include/Client.h
Normal file
21
include/Client.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL_net.h>
|
||||
|
||||
class Client
|
||||
{
|
||||
std::string mHost;
|
||||
Uint16 mPort;
|
||||
int mChannel;
|
||||
std::vector<UDPsocket> UDPsocks;
|
||||
public:
|
||||
Client (void)
|
||||
{
|
||||
}
|
||||
Client (const char* host, const Uint16 port, const int channel);
|
||||
UDPsocket UDP_Open (const char* host, const Uint16 port, const int channel);
|
||||
void UDP_CloseAll (void);
|
||||
};
|
43
include/FileIO.h
Normal file
43
include/FileIO.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64 /* off_t */
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
|
||||
class FileIO
|
||||
{
|
||||
FILE* fp;
|
||||
std::string path;
|
||||
public:
|
||||
~FileIO (void)
|
||||
{
|
||||
if (fp)
|
||||
{
|
||||
Close ();
|
||||
fp = NULL;
|
||||
}
|
||||
}
|
||||
FileIO (const std::string&, const std::string&);
|
||||
FileIO (FILE* f)
|
||||
{
|
||||
fp = f;
|
||||
}
|
||||
FILE* Open (const std::string&, const std::string&);
|
||||
int Close (void);
|
||||
int Seek (const off_t, const int);
|
||||
off_t Tell (void);
|
||||
size_t Read(void*, const size_t);
|
||||
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);
|
||||
};
|
6
include/SDL_clamp.h
Normal file
6
include/SDL_clamp.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* <https://github.com/libsdl-org/SDL/commit/35c1bbfa49b1247c2c6240f7f95871f3b3331874>
|
||||
*/
|
||||
#define SDL_clamp(x, a, b) ((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x))
|
38
include/Server.h
Normal file
38
include/Server.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_net.h>
|
||||
|
||||
/* MTU */
|
||||
#define MAX_PACKET_SIZE (1024*1024)
|
||||
|
||||
class Server
|
||||
{
|
||||
bool mProcessPacketCallbackRunning;
|
||||
SDL_TimerID mProcessPacketCallbackTimerID;
|
||||
static Uint32 ProcessPacketCallback (Uint32, void*);
|
||||
public:
|
||||
std::vector<UDPsocket> UDPsocks;
|
||||
SDLNet_SocketSet SocketSet;
|
||||
UDPpacket **UDPPacketV;
|
||||
Server (void)
|
||||
{
|
||||
mProcessPacketCallbackRunning = false;
|
||||
UDPsocks.clear ();
|
||||
SocketSet = NULL;
|
||||
UDPPacketV = NULL;
|
||||
}
|
||||
Server (const char* host, const Uint16 port);
|
||||
UDPsocket UDP_Open (Uint16 port);
|
||||
void UDP_CloseAll (void);
|
||||
void ProcessPacket (UDPpacket* packet);
|
||||
void Start (void);
|
||||
void Stop (void);
|
||||
bool ProcessPacketCallbackRunning (void)
|
||||
{
|
||||
return mProcessPacketCallbackRunning;
|
||||
}
|
||||
};
|
0
include/ToggleFullscreen.h
Normal file
0
include/ToggleFullscreen.h
Normal file
8
include/UDP_Write.h
Normal file
8
include/UDP_Write.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL_net.h>
|
||||
|
||||
int Buffer_Write_UDP (UDPsocket udpsock, const int channel, const size_t mtu, const void* buf, const size_t size);
|
||||
int File_Write_UDP (UDPsocket udpsock, const int channel, const size_t mtu, const char* path);
|
||||
int SendFile_UDP (const char* host, const Uint16 port, const int channel, const size_t mtu, const char* path);
|
||||
int SendBuffer_UDP (const char* host, const Uint16 port, const int channel, const size_t mtu, const void* buf, const size_t size);
|
71
include/camera.h
Normal file
71
include/camera.h
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
/**
|
||||
* Default camera values
|
||||
*/
|
||||
#define DEFAULT_CAMERA_YAW (-90.0f)
|
||||
#define DEFAULT_CAMERA_PITCH (0.0f)
|
||||
#define DEFAULT_CAMERA_ROLL (0.0f)
|
||||
#define DEFAULT_CAMERA_SPEED (1.0f)
|
||||
#define DEFAULT_CAMERA_SENSITIVITY (1.0f)
|
||||
#define DEFAULT_CAMERA_JOYSENSITIVITY (1.0f)
|
||||
#define DEFAULT_CAMERA_ZOOM (45.0f)
|
||||
|
||||
/*
|
||||
* Decelerate at gravity speed (9.8 m/s) / ???
|
||||
*/
|
||||
#define DEFAULT_CAMERA_DECELERATIONSPEED (0.98f)
|
||||
#define DEFAULT_CAMERA_MOUSEDECELERATIONSPEED (0.098f)
|
||||
|
||||
class Camera
|
||||
{
|
||||
/**
|
||||
* An abstract camera class that processes input and calculates the corresponding
|
||||
*/
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Front;
|
||||
glm::vec3 Right;
|
||||
glm::vec3 Up;
|
||||
glm::vec3 WorldUp;
|
||||
|
||||
/** Euler Angles, Vectors and Matrices for use in OpenGL. */
|
||||
glm::vec3 Angles;
|
||||
|
||||
/* XXX Maybe we shouldn't let the camera move? */
|
||||
glm::vec3 Direction; /* Position movement */
|
||||
glm::vec2 ViewDirection; /* Yaw, Pitch movement */
|
||||
|
||||
void updateCameraVectors (void);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Defines several possible options for camera movement.
|
||||
* Used as abstraction to stay away from window-system specific input methods
|
||||
*/
|
||||
enum Movement
|
||||
{
|
||||
FORWARD, BACKWARD, LEFT, RIGHT, UP, DOWN, CW, CCW, NONE
|
||||
};
|
||||
|
||||
/** Camera options */
|
||||
float MovementSpeed, MouseSensitivity, Zoom;
|
||||
float DecelerationSpeed, ViewDecelerationSpeed, JoystickSensitivity;
|
||||
float zNear, zFar;
|
||||
|
||||
Camera (
|
||||
const glm::vec3 position = glm::vec3(0.0f, 0.0f, 1.0f)
|
||||
, const glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
, const float yaw = DEFAULT_CAMERA_YAW
|
||||
, const float pitch = DEFAULT_CAMERA_PITCH
|
||||
, const float roll = DEFAULT_CAMERA_ROLL);
|
||||
|
||||
glm::mat4 GetViewMatrix (const bool constrainPitch = true);
|
||||
void ProcessJoystickMovement (const float xoffset, const float yoffset, const float deltaTime);
|
||||
void ProcessKeyboard (const Camera::Movement direction, const float deltaTime);
|
||||
void ProcessMouseMovement (const float xoffset, const float yoffset, const float deltaTime);
|
||||
void ProcessMouseScroll (const float xoffset, const float yoffset, const float deltaTime);
|
||||
};
|
12
include/cube.h
Normal file
12
include/cube.h
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object.h"
|
||||
|
||||
class Cube : Object
|
||||
{
|
||||
public:
|
||||
Cube (void)
|
||||
{
|
||||
}
|
||||
Cube (const GLsizei);
|
||||
|
||||
void Draw (void);
|
||||
};
|
23
include/debug.h
Normal file
23
include/debug.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <SDL_log.h>
|
||||
#include <stdarg.h>
|
||||
#define DEBUG_LOG(...) debug_log (__FILE__, __LINE__, __VA_ARGS__)
|
||||
static void debug_log (const char* filename, const int lineno, const char* fmt, ...)
|
||||
{
|
||||
char buf[8192];
|
||||
va_list ap;
|
||||
SDL_memset (buf, 0, sizeof buf);
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsnprintf (buf, (sizeof buf) - 1, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
SDL_LogMessage (SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG, "%s:%d: %s", filename, lineno, buf);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#define DEBUG_LOG(...)
|
||||
#endif
|
5
include/events_common.h
Normal file
5
include/events_common.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
enum {
|
||||
PACKET_SDL_EVENT = SDL_USEREVENT,
|
||||
};
|
14
include/glCheckErrors.h
Normal file
14
include/glCheckErrors.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <GL/glew.h>
|
||||
|
||||
#define glCheckErrors() \
|
||||
do \
|
||||
{ \
|
||||
GLenum err; \
|
||||
while ((err = glGetError()) != GL_NO_ERROR) \
|
||||
{ \
|
||||
fprintf (stderr, "%s:%d: %s\n", __FILE__, __LINE__, glewGetErrorString(err)); \
|
||||
} \
|
||||
} while (0)
|
14
include/lib_GL_common.h
Normal file
14
include/lib_GL_common.h
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <SDL_video.h>
|
||||
|
||||
void common_GL_Init (SDL_Window*, SDL_GLContext*, int);
|
||||
|
||||
void common_GL_TexParameters (const GLenum, const GLenum, const GLenum, const GLenum, const GLenum);
|
||||
GLuint common_GL_SurfaceFormat (SDL_Surface*);
|
||||
GLuint common_GL_LoadTextureSurface (SDL_Surface*);
|
||||
GLuint common_GL_LoadTexturePath (const std::string&);
|
21
include/lib_SDL_common.h
Normal file
21
include/lib_SDL_common.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <SDL_mixer.h>
|
||||
#include <SDL_net.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
void common_SDL_Init (void);
|
||||
void common_SDL_Quit (void);
|
||||
|
||||
void common_SDL_CreateWindow (SDL_Window**);
|
||||
|
||||
int common_SDL_ToggleFullscreen (SDL_Window*);
|
||||
|
||||
SDL_Surface* common_SDL_LoadSurfacePath (const std::string&);
|
17
include/lib_lua_common.h
Normal file
17
include/lib_lua_common.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
void common_lua_stack_dump (lua_State*);
|
||||
int common_lua_run (lua_State*, const char*, const char*, const size_t);
|
19
include/object.h
Normal file
19
include/object.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
class Object
|
||||
{
|
||||
protected:
|
||||
GLsizei mGLsizei;
|
||||
GLuint VBO, EBO;
|
||||
|
||||
public:
|
||||
GLuint VAO;
|
||||
|
||||
Object (void) : mGLsizei (0)
|
||||
{
|
||||
}
|
||||
Object (const GLsizei);
|
||||
~Object (void);
|
||||
};
|
12
include/quad.h
Normal file
12
include/quad.h
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object.h"
|
||||
|
||||
class Quad : Object
|
||||
{
|
||||
public:
|
||||
Quad (void)
|
||||
{
|
||||
}
|
||||
Quad (const GLsizei);
|
||||
|
||||
void Draw (void);
|
||||
};
|
36
include/shader.h
Normal file
36
include/shader.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
class ShaderProgram
|
||||
{
|
||||
bool mUniformLocationsNeedRefresh;
|
||||
std::map<const std::string, GLint> UniformLocationCache;
|
||||
static GLint my_checkCompileSuccess (const GLuint id, const GLenum type);
|
||||
public:
|
||||
GLuint ID;
|
||||
ShaderProgram (void);
|
||||
ShaderProgram (const std::string&, const std::string&, const std::string&);
|
||||
GLint getCachedLoc (const std::string&);
|
||||
void RefreshUniformLocations (void);
|
||||
void Use (void);
|
||||
void Bool (const std::string&, const bool&value);
|
||||
void Float (const std::string&, const float&value);
|
||||
void Int (const std::string&, const int&value);
|
||||
void Vec2 (const std::string&, const glm::vec2& value);
|
||||
void Vec3 (const std::string&, const glm::vec3& value);
|
||||
void Vec4 (const std::string&, const glm::vec4& value);
|
||||
void Mat2 (const std::string&, const glm::mat2& value);
|
||||
void Mat3 (const std::string&, const glm::mat3& value);
|
||||
void Mat4 (const std::string&, const glm::mat4& value);
|
||||
|
||||
GLuint CompileShaderBuffer (const std::string&, const GLenum type);
|
||||
GLuint CompileShaderPath (const std::string&, const GLenum type);
|
||||
GLint LinkProgram (void);
|
||||
};
|
3
include/signal_common.h
Normal file
3
include/signal_common.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void common_Signal_Init (void);
|
36
include/trim.h
Normal file
36
include/trim.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
/* https://stackoverflow.com/a/217605 */
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
|
||||
// trim from start
|
||||
static inline
|
||||
std::string&
|
||||
ltrim (std::string& s)
|
||||
{
|
||||
s.erase (s.begin (), std::find_if (s.begin (), s.end (), std::not1 (std::ptr_fun<int, int>(std::isspace))));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// trim from end
|
||||
static inline
|
||||
std::string&
|
||||
rtrim (std::string& s)
|
||||
{
|
||||
s.erase (std::find_if (s.rbegin (), s.rend (), std::not1 (std::ptr_fun <int, int>(std::isspace))).base (), s.end ());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// trim from both ends
|
||||
static inline
|
||||
std::string&
|
||||
trim (std::string& s)
|
||||
{
|
||||
return ltrim (rtrim (s));
|
||||
}
|
7
include/unused.h
Normal file
7
include/unused.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef UNUSED
|
||||
#undef UNUSED
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) ((void)(x))
|
53
src/Client.cpp
Normal file
53
src/Client.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "debug.h"
|
||||
#include "Client.h"
|
||||
|
||||
Client::Client (const char* host, const Uint16 port, const int channel)
|
||||
{
|
||||
UDPsocket udpsock;
|
||||
if (NULL != (udpsock = UDP_Open (host, SDL_SwapBE16 (port), channel)))
|
||||
{
|
||||
mHost = host;
|
||||
mPort = port;
|
||||
mChannel = channel;
|
||||
UDPsocks.push_back (udpsock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UDPsocket
|
||||
Client::UDP_Open (const char* host, const Uint16 port, const int channel)
|
||||
{
|
||||
IPaddress address;
|
||||
UDPsocket udpsock;
|
||||
if (!(udpsock = SDLNet_UDP_Open (0)))
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_UDP_Open: %s", SDLNet_GetError ());
|
||||
return NULL;
|
||||
}
|
||||
if (SDLNet_ResolveHost (&address, host, port) < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_ResolveHost: %s", SDLNet_GetError ());
|
||||
return NULL;
|
||||
}
|
||||
if (SDLNet_UDP_Bind (udpsock, channel, &address) < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_UDP_Bind: %s", SDLNet_GetError ());
|
||||
return NULL;
|
||||
}
|
||||
return udpsock;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Client::UDP_CloseAll (void)
|
||||
{
|
||||
size_t i;
|
||||
const size_t nclients = UDPsocks.size ();
|
||||
for (i = 0; i < nclients; i++)
|
||||
{
|
||||
SDLNet_UDP_Unbind (UDPsocks[i], mChannel);
|
||||
SDLNet_UDP_Close (UDPsocks[i]);
|
||||
UDPsocks[i] = NULL;
|
||||
}
|
||||
UDPsocks.clear ();
|
||||
}
|
100
src/FileIO.cpp
Normal file
100
src/FileIO.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include "FileIO.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <errno.h> /* errno */
|
||||
#include <stdio.h> /* FILE* */
|
||||
#include <sys/stat.h> /* stat */
|
||||
#include <sys/types.h> /* stat */
|
||||
#include <unistd.h> /* stat */
|
||||
|
||||
FileIO::FileIO (const std::string& filename, const std::string& mode)
|
||||
{
|
||||
if (!(fp = Open (filename, mode)))
|
||||
throw errno;
|
||||
path = filename;
|
||||
}
|
||||
|
||||
|
||||
FILE*
|
||||
FileIO::Open (const std::string& filename, const std::string& mode)
|
||||
{
|
||||
return fopen (filename.c_str (), mode.c_str ());
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FileIO::Close (void)
|
||||
{
|
||||
return fclose (fp);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FileIO::Seek (const off_t offset, const int whence)
|
||||
{
|
||||
return fseeko (fp, offset, whence);
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
FileIO::Tell (void)
|
||||
{
|
||||
return ftello (fp);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
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)
|
||||
{
|
||||
return fwrite (dst, sizeof (char), size, fp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileIO::Rewind (void)
|
||||
{
|
||||
rewind (fp);
|
||||
}
|
||||
|
||||
|
||||
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 rc;
|
||||
Seek (0, SEEK_END);
|
||||
rc = Tell ();
|
||||
Rewind ();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
FileIO::ReadToString (void)
|
||||
{
|
||||
off_t size = Size () + 1;
|
||||
std::vector<char> b (size);
|
||||
off_t nread = Read (b.data (), size);
|
||||
return std::string ((const char *) b.data (), nread);
|
||||
}
|
34
src/SDL_ReadWrite64.cpp
Normal file
34
src/SDL_ReadWrite64.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_net.h>
|
||||
|
||||
/* Write a 64-bit value to network packet buffer */
|
||||
#define SDLNet_Write64(value, areap) _SDLNet_Write64 (value, areap)
|
||||
|
||||
/* Read a 64-bit value from network packet buffer */
|
||||
#define SDLNet_Read64(areap) _SDLNet_Read64 (areap)
|
||||
|
||||
SDL_FORCE_INLINE void
|
||||
_SDLNet_Write64 (Uint64 value, void* areap)
|
||||
{
|
||||
Uint8* area = (Uint8*) areap;
|
||||
area[0] = (value >> 56) & 0xFF;
|
||||
area[1] = (value >> 48) & 0xFF;
|
||||
area[2] = (value >> 40) & 0xFF;
|
||||
area[3] = (value >> 32) & 0xFF;
|
||||
area[4] = (value >> 24) & 0xFF;
|
||||
area[5] = (value >> 16) & 0xFF;
|
||||
area[6] = (value >> 8) & 0xFF;
|
||||
area[7] = value & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
SDL_FORCE_INLINE Uint64
|
||||
_SDLNet_Read64 (const void* areap)
|
||||
{
|
||||
const Uint8* area = (const Uint8*) areap;
|
||||
return (
|
||||
((Uint64) area[0]) << 56) | (((Uint64) area[1]) << 48) |
|
||||
(((Uint64) area[2]) << 40) | (((Uint64) area[3]) << 32) |
|
||||
(((Uint64) area[4]) << 24) | (((Uint64) area[5]) << 16) |
|
||||
(((Uint64) area[6]) << 8) | (((Uint64) area[7]));
|
||||
}
|
179
src/Server.cpp
Normal file
179
src/Server.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#include "debug.h"
|
||||
#include "Server.h"
|
||||
#include "events_common.h"
|
||||
|
||||
#include <arpa/inet.h> /* inet_ntop */
|
||||
|
||||
Server::Server (const char *host, const Uint16 port)
|
||||
{
|
||||
IPaddress ipaddress;
|
||||
UDPsocket udpsock;
|
||||
char hoststring[128];
|
||||
if (SDLNet_ResolveHost (&ipaddress, host, SDL_SwapBE16 (port)) < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_ResolveHost: %s", SDLNet_GetError ());
|
||||
return;
|
||||
}
|
||||
if (NULL != (udpsock = UDP_Open (ipaddress.port)))
|
||||
{
|
||||
UDPsocks.push_back (udpsock);
|
||||
mProcessPacketCallbackRunning = false;
|
||||
inet_ntop (AF_INET, &ipaddress.host, hoststring, 128);
|
||||
SDL_Log ("Listening on %s:%d", hoststring, ipaddress.port);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log ("Unable to bind to port %d; is it in use?", ipaddress.port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::UDP_CloseAll (void)
|
||||
{
|
||||
size_t i, nclients;
|
||||
nclients = UDPsocks.size ();
|
||||
SDL_Log ("Server::~Server %ld", nclients);
|
||||
for (i = 0; i < nclients; i++)
|
||||
{
|
||||
SDLNet_UDP_Close (UDPsocks[i]);
|
||||
UDPsocks[i] = NULL;
|
||||
}
|
||||
UDPsocks.clear ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open and keep track of a UDP socket.
|
||||
*/
|
||||
UDPsocket
|
||||
Server::UDP_Open (const Uint16 port)
|
||||
{
|
||||
UDPsocket udpsock;
|
||||
if (!(udpsock = SDLNet_UDP_Open (port)))
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_UDP_Open: %s", SDLNet_GetError ());
|
||||
return NULL;
|
||||
}
|
||||
return udpsock;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::ProcessPacket (UDPpacket * packet)
|
||||
{
|
||||
size_t len;
|
||||
SDL_Event event;
|
||||
SDL_UserEvent userevent;
|
||||
UDPpacket *temp;
|
||||
len = packet->len;
|
||||
temp = SDLNet_AllocPacket (len);
|
||||
SDL_memcpy (&temp->address, &packet->address, sizeof (IPaddress));
|
||||
SDL_memcpy (temp->data, packet->data, len);
|
||||
temp->len = len;
|
||||
SDL_zero (event);
|
||||
SDL_zero (userevent);
|
||||
userevent.type = PACKET_SDL_EVENT;
|
||||
userevent.code = 0;
|
||||
userevent.data1 = (void *) temp;
|
||||
userevent.data2 = (void *) NULL;
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user = userevent;
|
||||
SDL_PushEvent (&event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::Start (void)
|
||||
{
|
||||
size_t i;
|
||||
int nclients, numused;
|
||||
nclients = (int) UDPsocks.size ();
|
||||
SDL_Log ("Server %d clients", nclients);
|
||||
if (!(UDPPacketV = SDLNet_AllocPacketV (nclients, MAX_PACKET_SIZE)))
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_AllocPacketV: %s", SDLNet_GetError ());
|
||||
return;
|
||||
}
|
||||
if (!(SocketSet = SDLNet_AllocSocketSet (nclients)))
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_AllocSocketSet: %s", SDLNet_GetError ());
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < (size_t) nclients; i++)
|
||||
{
|
||||
numused = SDLNet_UDP_AddSocket (SocketSet, UDPsocks[i]);
|
||||
if (numused < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_AddSocket: %s", SDLNet_GetError ());
|
||||
return;
|
||||
}
|
||||
}
|
||||
mProcessPacketCallbackRunning = true;
|
||||
mProcessPacketCallbackTimerID = SDL_AddTimer (10, Server::ProcessPacketCallback, (void *) this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Server::Stop (void)
|
||||
{
|
||||
size_t i, nclients;
|
||||
mProcessPacketCallbackRunning = false;
|
||||
SDL_RemoveTimer (mProcessPacketCallbackTimerID);
|
||||
|
||||
nclients = UDPsocks.size ();
|
||||
for (i = 0; i < nclients; i++)
|
||||
{
|
||||
SDLNet_UDP_DelSocket (SocketSet, UDPsocks[i]);
|
||||
}
|
||||
SDLNet_FreeSocketSet (SocketSet);
|
||||
SocketSet = NULL;
|
||||
|
||||
SDLNet_FreePacketV (UDPPacketV);
|
||||
UDPPacketV = NULL;
|
||||
}
|
||||
|
||||
|
||||
Uint32
|
||||
Server::ProcessPacketCallback (Uint32 interval, void *param)
|
||||
{
|
||||
int numrecv, numready;
|
||||
size_t i, j;
|
||||
|
||||
SDL_assert (NULL != param);
|
||||
Server & server = *(Server *) param;
|
||||
|
||||
if (!server.ProcessPacketCallbackRunning ())
|
||||
return 0;
|
||||
|
||||
numready = SDLNet_CheckSockets (server.SocketSet, ~0);
|
||||
if (numready < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_CheckSockets: %s", SDLNet_GetError ());
|
||||
return 0;
|
||||
}
|
||||
else if (numready > 0)
|
||||
{
|
||||
DEBUG_LOG ("There are %d sockets with activity!", numready);
|
||||
}
|
||||
|
||||
/* check all sockets with SDLNet_SocketReady and handle the active ones. */
|
||||
for (i = 0; i < (size_t) numready; i++)
|
||||
{
|
||||
if (SDLNet_SocketReady (server.UDPsocks[i]))
|
||||
{
|
||||
numrecv = SDLNet_UDP_RecvV (server.UDPsocks[i], &server.UDPPacketV[i]);
|
||||
if (numrecv < 0)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_UDP_RecvV: %s", SDLNet_GetError ());
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < (size_t) numrecv; j++)
|
||||
{
|
||||
server.ProcessPacket (server.UDPPacketV[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
123
src/UDP_Write.cpp
Normal file
123
src/UDP_Write.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include "debug.h"
|
||||
#include "FileIO.h"
|
||||
#include "Client.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <math.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_net.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
/* XXX gross */
|
||||
int
|
||||
Buffer_Write_UDP (UDPsocket udpsock, const int channel, const size_t mtu, const void *buf, const size_t size)
|
||||
{
|
||||
const char *bufPtr;
|
||||
const char *bufPtrEnd;
|
||||
int numsent, npackets;
|
||||
IPaddress *address;
|
||||
size_t i, our_nsent, our_mtu;
|
||||
UDPpacket **packetV;
|
||||
SDL_assert (mtu > 0);
|
||||
SDL_assert (size > 0);
|
||||
numsent = 0;
|
||||
our_mtu = mtu;
|
||||
if (size < our_mtu)
|
||||
our_mtu = size;
|
||||
npackets = ceil ((double) size / (double) our_mtu);
|
||||
if (!npackets)
|
||||
{
|
||||
DEBUG_LOG ("File_Write_UDP: zero length packet\n");
|
||||
return 0;
|
||||
}
|
||||
packetV = SDLNet_AllocPacketV (npackets, our_mtu);
|
||||
if (!packetV)
|
||||
{
|
||||
DEBUG_LOG ("SDLNet_AllocPacketV: %s\n", SDLNet_GetError ());
|
||||
return 0;
|
||||
}
|
||||
i = 0;
|
||||
bufPtr = (const char *) buf;
|
||||
bufPtrEnd = bufPtr + size;
|
||||
address = SDLNet_UDP_GetPeerAddress (udpsock, channel);
|
||||
size_t nsent = size;
|
||||
while (i < (size_t) npackets && bufPtr < bufPtrEnd)
|
||||
{
|
||||
our_nsent = nsent;
|
||||
if (our_nsent > our_mtu)
|
||||
our_nsent = our_mtu;
|
||||
packetV[i]->channel = channel;
|
||||
SDL_memcpy (&packetV[i]->address, address, sizeof (IPaddress));
|
||||
SDL_memset (packetV[i]->data, 0, our_mtu);
|
||||
SDL_memcpy (packetV[i]->data, bufPtr, our_nsent);
|
||||
packetV[i]->len = our_nsent;
|
||||
bufPtr += our_mtu;
|
||||
nsent -= our_mtu;
|
||||
i++;
|
||||
}
|
||||
numsent = SDLNet_UDP_SendV (udpsock, packetV, npackets);
|
||||
if (!numsent)
|
||||
{
|
||||
SDL_Log ("SDLNet_UDP_SendV (%d): %s\n", npackets, SDLNet_GetError ());
|
||||
}
|
||||
SDLNet_FreePacketV (packetV);
|
||||
return numsent;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
File_Write_UDP (UDPsocket udpsock, const int channel, const char *path, const size_t mtu)
|
||||
{
|
||||
int numsent;
|
||||
Sint64 size;
|
||||
numsent = 0;
|
||||
try
|
||||
{
|
||||
FileIO f (path, "r");
|
||||
size = f.Size ();
|
||||
std::vector<char> b (size + 1);
|
||||
f.Read (b.data (), size);
|
||||
numsent = Buffer_Write_UDP (udpsock, channel, mtu, b.data (), b.size ());
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
SDL_Log ("File_Write_UDP: %s", strerror (errno));
|
||||
}
|
||||
|
||||
return numsent;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SendBuffer_UDP (const char *host, const Uint16 port, const int channel, const size_t mtu, const void *buf, const size_t size)
|
||||
{
|
||||
int numsent;
|
||||
UDPsocket udpsock;
|
||||
numsent = 0;
|
||||
Client client (host, port, channel);
|
||||
if (udpsock)
|
||||
{
|
||||
numsent = Buffer_Write_UDP (udpsock, channel, mtu, buf, size);
|
||||
client.UDP_CloseAll ();
|
||||
}
|
||||
return numsent;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SendFile_UDP (const char *host, const Uint16 port, const int channel, const size_t mtu, const char *path)
|
||||
{
|
||||
int numsent;
|
||||
UDPsocket udpsock;
|
||||
numsent = 0;
|
||||
Client client (host, port, channel);
|
||||
if (udpsock)
|
||||
{
|
||||
numsent = File_Write_UDP (udpsock, channel, path, mtu);
|
||||
client.UDP_CloseAll ();
|
||||
}
|
||||
return numsent;
|
||||
}
|
160
src/camera.cpp
Normal file
160
src/camera.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "camera.h"
|
||||
#include "SDL_clamp.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
/* https://graphicscompendium.com/opengl/22-interpolation */
|
||||
static inline
|
||||
glm::vec2
|
||||
lerp (const glm::vec2 x, const glm::vec2 y, const float t)
|
||||
{
|
||||
return x * (1.f - t) + y * t;
|
||||
}
|
||||
|
||||
|
||||
static inline
|
||||
glm::vec3
|
||||
lerp (const glm::vec3 x, const glm::vec3 y, const float t)
|
||||
{
|
||||
return x * (1.f - t) + y * t;
|
||||
}
|
||||
|
||||
|
||||
Camera::Camera (const glm::vec3 position, const glm::vec3 up, const float yaw, const float pitch, const float roll)
|
||||
{
|
||||
Front = glm::vec3 (0.0f, 0.0f, -1.0f);
|
||||
WorldUp = up;
|
||||
MovementSpeed = DEFAULT_CAMERA_SPEED;
|
||||
MouseSensitivity = DEFAULT_CAMERA_SENSITIVITY;
|
||||
Zoom = DEFAULT_CAMERA_ZOOM;
|
||||
DecelerationSpeed = DEFAULT_CAMERA_DECELERATIONSPEED;
|
||||
ViewDecelerationSpeed = DEFAULT_CAMERA_MOUSEDECELERATIONSPEED;
|
||||
JoystickSensitivity = DEFAULT_CAMERA_JOYSENSITIVITY;
|
||||
Position = position;
|
||||
Angles = glm::vec3 (yaw, pitch, roll);
|
||||
Direction = glm::vec3 (0);
|
||||
ViewDirection = glm::vec2 (0);
|
||||
zNear = 0.1f;
|
||||
zFar = 1000.0f;
|
||||
updateCameraVectors ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the front vector from the Camera's (updated) Euler Angles
|
||||
*/
|
||||
void
|
||||
Camera::updateCameraVectors (void)
|
||||
{
|
||||
const glm::mat4 roll_mat =
|
||||
glm::rotate (glm::mat4 (1.0f), glm::radians (Angles.z), Front);
|
||||
/**
|
||||
* Calculate the new Front vector
|
||||
*/
|
||||
Front = glm::normalize (glm::vec3
|
||||
( cos (glm::radians (Angles.x)) * cos (glm::radians (Angles.y))
|
||||
, sin (glm::radians (Angles.y))
|
||||
, sin (glm::radians (Angles.x)) * cos (glm::radians (Angles.y))));
|
||||
// std::cout << glm::to_string (roll_mat) << std::endl;
|
||||
/**
|
||||
* Also re-calculate the Right and Up vector
|
||||
* normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
|
||||
*/
|
||||
Right = glm::normalize (glm::cross (Front, WorldUp));
|
||||
Up = glm::mat3 (roll_mat) * glm::normalize (glm::cross (Right, Front));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the view matrix calculated using Euler Angles and the LookAt Matrix
|
||||
*/
|
||||
glm::mat4 Camera::GetViewMatrix (const bool constrainPitch)
|
||||
{
|
||||
/*
|
||||
* XXX Where to handle acceleration?
|
||||
*
|
||||
* Seems like since we're probably calling this every frame, this is the place to do it!
|
||||
*/
|
||||
Position += Direction;
|
||||
Angles.x = fmod (Angles.x + ViewDirection.x, 360.0f);
|
||||
Angles.y += ViewDirection.y;
|
||||
if (constrainPitch)
|
||||
{
|
||||
Angles.y = SDL_clamp (Angles.y, -89.9f, 89.9f);
|
||||
}
|
||||
Zoom = SDL_clamp (Zoom, 1.0f, 45.0f);
|
||||
/**
|
||||
* Update Front, Right and Up Vectors using the updated Euler angles
|
||||
*/
|
||||
updateCameraVectors ();
|
||||
Direction = lerp (Direction, glm::vec3 (0.0f), DecelerationSpeed);
|
||||
ViewDirection =
|
||||
lerp (ViewDirection, glm::vec2 (0.0f), ViewDecelerationSpeed);
|
||||
// std::cout << glm::to_string (Position) << std::endl;
|
||||
return glm::lookAt (Position, Position + Front, Up);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes input received from any keyboard-like input system.
|
||||
* Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
|
||||
*/
|
||||
void
|
||||
Camera::ProcessKeyboard (Camera::Movement direction, const float deltaTime)
|
||||
{
|
||||
const float velocity = MovementSpeed * deltaTime;
|
||||
switch (direction)
|
||||
{
|
||||
case FORWARD: Direction += Front * velocity; break;
|
||||
case BACKWARD: Direction -= Front * velocity; break;
|
||||
case LEFT: Direction -= Right * velocity; break;
|
||||
case RIGHT: Direction += Right * velocity; break;
|
||||
case UP: Direction += Up * velocity; break;
|
||||
case DOWN: Direction -= Up * velocity; break;
|
||||
case CW: Angles.z += velocity; break;
|
||||
case CCW: Angles.z -= velocity; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
|
||||
void
|
||||
Camera::ProcessJoystickMovement (const float xoffset, const float yoffset, const float deltaTime)
|
||||
{
|
||||
const float velocity = JoystickSensitivity * deltaTime;
|
||||
const float Xoffset = xoffset * velocity;
|
||||
const float Yoffset = yoffset * velocity;
|
||||
ViewDirection.x += Xoffset;
|
||||
ViewDirection.y += Yoffset;
|
||||
}
|
||||
|
||||
|
||||
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
|
||||
void
|
||||
Camera::ProcessMouseMovement (const float xoffset, const float yoffset, const float deltaTime)
|
||||
{
|
||||
const float velocity = MouseSensitivity * deltaTime;
|
||||
const float Xoffset = xoffset * velocity;
|
||||
const float Yoffset = yoffset * velocity;
|
||||
ViewDirection.x += Xoffset;
|
||||
ViewDirection.y += Yoffset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Processes input received from a mouse scroll-wheel event.
|
||||
* Only requires input on the vertical wheel-axis.
|
||||
*/
|
||||
void
|
||||
Camera::ProcessMouseScroll (const float xoffset, const float yoffset, const float deltaTime)
|
||||
{
|
||||
(void) xoffset;
|
||||
(void) deltaTime;
|
||||
// Angles.z += (float) xoffset;
|
||||
Zoom += (float) yoffset;
|
||||
}
|
417
src/client_main.cpp
Normal file
417
src/client_main.cpp
Normal file
@ -0,0 +1,417 @@
|
||||
#include "camera.h"
|
||||
#include "Client.h"
|
||||
#include "cube.h"
|
||||
#include "debug.h"
|
||||
#include "glCheckErrors.h"
|
||||
#include "lib_GL_common.h"
|
||||
#include "lib_SDL_common.h"
|
||||
#include "quad.h"
|
||||
#include "shader.h"
|
||||
#include "signal_common.h"
|
||||
#include "UDP_Write.h"
|
||||
#include "unused.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <getopt.h> /* getopt */
|
||||
#include <stdlib.h> /* exit */
|
||||
#include <string.h> /* memset */
|
||||
#include <unistd.h> /* getopt */
|
||||
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#define Perf_Diff(a, b) ((double) 1000 * ((double)(((double) (b) - (double) (a)) / (double) SDL_GetPerformanceFrequency ())))
|
||||
|
||||
#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 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 *);
|
||||
|
||||
struct Uniform_Values
|
||||
{
|
||||
int iFrame;
|
||||
float iFrameRate;
|
||||
float iSampleRate;
|
||||
float iTime;
|
||||
float iTimeDelta;
|
||||
glm::vec3 iResolution;
|
||||
glm::vec4 iDate;
|
||||
glm::vec4 iMouse;
|
||||
std::vector<unsigned int> iChannel;
|
||||
std::vector<float> iChannelTime;
|
||||
std::vector<glm::vec3> iChannelResolution;
|
||||
};
|
||||
|
||||
struct Client_State
|
||||
{
|
||||
int quit;
|
||||
|
||||
Uint64 start, end;
|
||||
double diff;
|
||||
|
||||
UDPsocket udpsock;
|
||||
const char* host;
|
||||
Uint16 port;
|
||||
int channel;
|
||||
int mtu;
|
||||
|
||||
SDL_GLContext GLContext;
|
||||
SDL_Window *Window;
|
||||
int Window_Height;
|
||||
int Window_Width;
|
||||
|
||||
double ShaderTimeDividend;
|
||||
bool ImGuiEnabled;
|
||||
bool ShaderPlaying;
|
||||
bool InputCaptureMouse;
|
||||
bool InputFirstMouse;
|
||||
bool InputRelativeMouseMode;
|
||||
bool RenderShowQuad;
|
||||
};
|
||||
|
||||
static std::shared_ptr<Cube> cube;
|
||||
static std::shared_ptr<Quad> quad;
|
||||
|
||||
static Camera camera;
|
||||
static ShaderProgram shader;
|
||||
static struct Client_State state;
|
||||
static struct Uniform_Values values;
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
SDL_Event event;
|
||||
glm::mat4 model, view, projection;
|
||||
|
||||
my_Init (argc, argv);
|
||||
|
||||
shader = ShaderProgram ("../handmade-x/glsl/camera.v.glsl", "", "./glsl/new.f.glsl");
|
||||
if (!shader.ID)
|
||||
{
|
||||
SDL_Log ("Unable to load shader.");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
camera = Camera ();
|
||||
cube = std::make_shared<Cube> (1);
|
||||
quad = std::make_shared<Quad> (1);
|
||||
|
||||
state.mtu = 1450;
|
||||
state.quit = 0;
|
||||
if (NULL == (state.udpsock = Client::UDP_Open (state.host, state.port, state.channel)))
|
||||
{
|
||||
SDL_Log ("Unable to open client port");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
while (!state.quit)
|
||||
{
|
||||
state.end = SDL_GetPerformanceCounter ();
|
||||
state.diff = Perf_Diff (state.start, state.end);
|
||||
while (state.diff < MIN_FRAME_MS)
|
||||
{
|
||||
SDL_Delay (1);
|
||||
state.end = SDL_GetPerformanceCounter ();
|
||||
state.diff = Perf_Diff (state.start, state.end);
|
||||
}
|
||||
state.start = SDL_GetPerformanceCounter ();
|
||||
|
||||
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
|
||||
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
|
||||
|
||||
while (!state.quit && SDL_PollEvent (&event))
|
||||
{
|
||||
state.quit = my_Input (&event);
|
||||
}
|
||||
my_AnalogInput ();
|
||||
|
||||
my_UpdateValues ();
|
||||
|
||||
projection = glm::perspective (glm::radians (camera.Zoom), (float) values.iResolution.x / (float) values.iResolution.y, camera.zNear, camera.zFar);
|
||||
view = camera.GetViewMatrix ();
|
||||
model = glm::mat4 (1.0f);
|
||||
|
||||
shader.Use ();
|
||||
shader.Int ("iFrame", values.iFrame);
|
||||
shader.Float ("iTime", values.iTime);
|
||||
shader.Float ("iTimeDelta", values.iTimeDelta);
|
||||
shader.Vec3 ("iResolution", values.iResolution);
|
||||
|
||||
shader.Mat4 ("Projection", projection);
|
||||
shader.Mat4 ("View", view);
|
||||
shader.Mat4 ("Model", model);
|
||||
|
||||
my_Render ();
|
||||
SDL_GL_SwapWindow (state.Window);
|
||||
}
|
||||
|
||||
_out:
|
||||
client.UDP_CloseAll ();
|
||||
SDL_GL_DeleteContext (state.GLContext);
|
||||
SDL_DestroyWindow (state.Window);
|
||||
common_SDL_Quit ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Init (int argc, char** argv)
|
||||
{
|
||||
common_Signal_Init ();
|
||||
my_GetOpt (argc, argv);
|
||||
|
||||
state.start = state.end = SDL_GetPerformanceCounter ();
|
||||
|
||||
common_SDL_Init ();
|
||||
common_SDL_CreateWindow (&state.Window);
|
||||
common_GL_Init (state.Window, &state.GLContext, 1);
|
||||
SDL_GetWindowSize (state.Window, &state.Window_Width, &state.Window_Height);
|
||||
|
||||
state.ShaderPlaying = true;
|
||||
state.ShaderTimeDividend = 1000;
|
||||
state.InputRelativeMouseMode = false;
|
||||
state.InputCaptureMouse = false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_UpdateValues (void)
|
||||
{
|
||||
values.iFrame++;
|
||||
if (state.ShaderPlaying)
|
||||
{
|
||||
values.iTime += ((double) state.diff / (double) state.ShaderTimeDividend);
|
||||
}
|
||||
values.iTimeDelta = ((double) state.diff / (double) 1000);
|
||||
values.iResolution.x = state.Window_Width;
|
||||
values.iResolution.y = state.Window_Height;
|
||||
values.iResolution.z = 1.0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Render (void)
|
||||
{
|
||||
glClearColor (0, 0, 0, 1);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
if (state.RenderShowQuad)
|
||||
{
|
||||
// glEnable (GL_DEPTH_TEST);
|
||||
cube->Draw ();
|
||||
}
|
||||
else
|
||||
quad->Draw ();
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
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;
|
||||
|
||||
if (state.InputFirstMouse)
|
||||
{
|
||||
values.iMouse.x = xpos;
|
||||
values.iMouse.y = ypos;
|
||||
state.InputFirstMouse = false;
|
||||
}
|
||||
|
||||
// reversed since y-coordinates go from bottom to top
|
||||
const float
|
||||
Xoffset = xpos - values.iMouse.x;
|
||||
const float
|
||||
Yoffset = values.iMouse.y - ypos;
|
||||
|
||||
values.iMouse.x = xpos;
|
||||
values.iMouse.y = ypos;
|
||||
|
||||
camera.ProcessMouseMovement (Xoffset, Yoffset, 0.1);
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
my_SDL_MouseButton (SDL_Event * event)
|
||||
{
|
||||
int down;
|
||||
int quit;
|
||||
SDL_assert (NULL != event);
|
||||
down = event->type == SDL_MOUSEBUTTONDOWN;
|
||||
quit = SDL_FALSE;
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
my_Input (SDL_Event * event)
|
||||
{
|
||||
int quit;
|
||||
SDL_assert (NULL != event);
|
||||
quit = SDL_FALSE;
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
quit = SDL_TRUE;
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
quit = my_Input_Key (event);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
my_SDL_MouseMotion (event);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
my_SDL_MouseButton (event);
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
my_SDL_WindowEvent (event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
my_AnalogInput (void)
|
||||
{
|
||||
const Uint8 *
|
||||
kbd = SDL_GetKeyboardState (NULL);
|
||||
const float
|
||||
dt = 0.016;
|
||||
(void) state;
|
||||
|
||||
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);
|
||||
camera.ProcessKeyboard (kbd[SDL_SCANCODE_A] ? Camera::Movement::LEFT : Camera::Movement::NONE, dt);
|
||||
camera.ProcessKeyboard (kbd[SDL_SCANCODE_D] ? Camera::Movement::RIGHT : Camera::Movement::NONE, dt);
|
||||
|
||||
camera.ProcessKeyboard (kbd[SDL_SCANCODE_LSHIFT] ? Camera::Movement::DOWN : Camera::Movement::NONE, dt);
|
||||
camera.ProcessKeyboard (kbd[SDL_SCANCODE_SPACE] ? Camera::Movement::UP : Camera::Movement::NONE, dt);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
my_Input_Key (SDL_Event * event)
|
||||
{
|
||||
int down;
|
||||
int quit;
|
||||
SDL_assert (NULL != event);
|
||||
down = event->type == SDL_KEYDOWN;
|
||||
quit = SDL_FALSE;
|
||||
switch (event->key.keysym.sym)
|
||||
{
|
||||
case SDLK_ESCAPE:
|
||||
quit = SDL_TRUE;
|
||||
break;
|
||||
case SDLK_F11:
|
||||
{
|
||||
if (down)
|
||||
{
|
||||
state.InputCaptureMouse = true;
|
||||
state.InputFirstMouse = true;
|
||||
state.InputRelativeMouseMode = true;
|
||||
common_SDL_ToggleFullscreen (SDL_GetWindowFromID (event->key.windowID));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDLK_r:
|
||||
{
|
||||
if (down)
|
||||
camera = Camera ();
|
||||
}
|
||||
break;
|
||||
case SDLK_c:
|
||||
{
|
||||
if (down)
|
||||
state.RenderShowQuad = !state.RenderShowQuad;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
Buffer_Write_UDP (state.udpsock, state.channel, state.mtu, event, sizeof (SDL_Event));
|
||||
}
|
||||
}
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
my_SDL_WindowEvent (SDL_Event * event)
|
||||
{
|
||||
int quit;
|
||||
SDL_assert (NULL != event);
|
||||
quit = SDL_FALSE;
|
||||
switch (event->window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
{
|
||||
state.Window_Width = event->window.data1;
|
||||
state.Window_Height = event->window.data2;
|
||||
glViewport (0, 0, (float) state.Window_Width, (float) state.Window_Height);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return quit;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Usage (const char *argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-h] [-s host] [-p port]\n", argv0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_GetOpt (int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
state.channel = 1;
|
||||
state.host = "localhost";
|
||||
state.port = 6666;
|
||||
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'p':
|
||||
state.port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
state.host = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
my_Usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
73
src/cube.cpp
Normal file
73
src/cube.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "cube.h"
|
||||
|
||||
Cube::Cube (const GLsizei size)
|
||||
: Object (size)
|
||||
{
|
||||
const float vertices[] = {
|
||||
// positions // normals // texture coords
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
glBindVertexArray (VAO);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray (VAO);
|
||||
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray (0);
|
||||
|
||||
// glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
// glEnableVertexAttribArray (1);
|
||||
|
||||
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
glEnableVertexAttribArray (1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Cube::Draw (void)
|
||||
{
|
||||
glBindVertexArray (VAO);
|
||||
glDrawArrays (GL_TRIANGLES, 0, 36);
|
||||
}
|
104
src/lib_GL_common.cpp
Normal file
104
src/lib_GL_common.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include "FileIO.h"
|
||||
#include "lib_SDL_common.h"
|
||||
#include "lib_GL_common.h"
|
||||
#include "glCheckErrors.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
void
|
||||
common_GL_Init (SDL_Window * wind, SDL_GLContext * ctx, int SwapInterval)
|
||||
{
|
||||
GLenum err;
|
||||
SDL_assert (NULL != ctx);
|
||||
*ctx = SDL_GL_CreateContext (wind);
|
||||
SDL_assert (NULL != *ctx);
|
||||
SDL_GL_MakeCurrent (wind, *ctx);
|
||||
SDL_GL_SetSwapInterval (SwapInterval);
|
||||
glewExperimental = true;
|
||||
if ((err = glewInit ()) != GLEW_OK)
|
||||
{
|
||||
SDL_Log ("glewInit: %s", glewGetErrorString (err));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
SDL_assert (err == GLEW_OK);
|
||||
glCheckErrors ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_GL_TexParameters (const GLenum id, const GLenum wrap_s, const GLenum wrap_t, const GLenum min_filter, const GLenum mag_filter)
|
||||
{
|
||||
/* all upcoming GL_TEXTURE_2D operations now have effect on this texture object */
|
||||
glBindTexture (GL_TEXTURE_2D, id);
|
||||
/* set the texture wrapping parameters
|
||||
* set texture wrapping to GL_REPEAT (default wrapping method) */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t);
|
||||
/* set texture filtering parameters */
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
|
||||
}
|
||||
|
||||
|
||||
GLenum
|
||||
common_GL_SurfaceFormat (SDL_Surface * surface)
|
||||
{
|
||||
SDL_assert (NULL != surface);
|
||||
switch (surface->format->BytesPerPixel)
|
||||
{
|
||||
case 1: return GL_RED;
|
||||
case 3: return GL_RGB;
|
||||
case 4: return GL_RGBA;
|
||||
}
|
||||
return GL_RED;
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
common_GL_LoadTextureSurface (SDL_Surface* surface)
|
||||
{
|
||||
GLenum format;
|
||||
GLuint texture;
|
||||
glGenTextures (1, &texture);
|
||||
if (!texture)
|
||||
return 0;
|
||||
if (!SDL_LockSurface (surface))
|
||||
{
|
||||
common_GL_TexParameters (texture, GL_REPEAT, GL_REPEAT, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
||||
format = common_GL_SurfaceFormat (surface);
|
||||
glBindTexture (GL_TEXTURE_2D, texture);
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
|
||||
glGenerateMipmap (GL_TEXTURE_2D);
|
||||
SDL_UnlockSurface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log ("SDL_LockSurface: %s", SDL_GetError ());
|
||||
texture = 0;
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
common_GL_LoadTexturePath (const char *path)
|
||||
{
|
||||
GLuint id;
|
||||
SDL_Surface *surface;
|
||||
if (NULL != (surface = common_SDL_LoadSurfacePath (path)))
|
||||
{
|
||||
id = common_GL_LoadTextureSurface (surface);
|
||||
SDL_FreeSurface (surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_Log ("common_SDL_LoadSurfacePath: error");
|
||||
id = 0;
|
||||
}
|
||||
return id;
|
||||
}
|
146
src/lib_SDL_common.cpp
Normal file
146
src/lib_SDL_common.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include "debug.h"
|
||||
#include "unused.h"
|
||||
#include "lib_SDL_common.h"
|
||||
|
||||
#include <stdlib.h> /* exit */
|
||||
|
||||
#define DEFAULT_WINDOW_TITLE "Unicorn's Horn"
|
||||
#define DEFAULT_WINDOW_WIDTH 800
|
||||
#define DEFAULT_WINDOW_HEIGHT 600
|
||||
|
||||
static void
|
||||
my_SDLNet_Init (void)
|
||||
{
|
||||
if (SDLNet_Init () == -1)
|
||||
{
|
||||
SDL_Log ("SDLNet_Init: %s", SDLNet_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_IMG_Init (int flags)
|
||||
{
|
||||
int initted;
|
||||
initted = IMG_Init (flags);
|
||||
if ((initted & flags) != flags)
|
||||
{
|
||||
SDL_Log ("IMG_Init: %s\n", IMG_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
SDL_assert ((initted & flags) == flags);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_TTF_Init (void)
|
||||
{
|
||||
if (TTF_Init () == -1)
|
||||
{
|
||||
SDL_Log ("TTF_Init: %s", TTF_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
SDL_assert (1 == TTF_WasInit ());
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Mix_Init (int flags)
|
||||
{
|
||||
int initted;
|
||||
initted = Mix_Init (flags);
|
||||
if ((initted & flags) != flags)
|
||||
{
|
||||
SDL_Log ("Mix_Init: %s\n", Mix_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
SDL_assert ((initted & flags) == flags);
|
||||
}
|
||||
|
||||
|
||||
static SDL_AssertState
|
||||
my_SDL_AssertionHandler(const SDL_AssertData* data, void* userdata)
|
||||
{
|
||||
UNUSED (data);
|
||||
UNUSED (userdata);
|
||||
return SDL_ASSERTION_ABORT;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_SDL_Assert_Init (void)
|
||||
{
|
||||
SDL_SetAssertionHandler(my_SDL_AssertionHandler, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_SDL_Init (void)
|
||||
{
|
||||
Uint32 Flags;
|
||||
Flags = SDL_INIT_EVERYTHING;
|
||||
if (SDL_Init (Flags) < 0)
|
||||
{
|
||||
SDL_Log ("SDL_Init: %s", SDL_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
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 ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_SDL_Quit (void)
|
||||
{
|
||||
SDL_SetAssertionHandler (SDL_GetDefaultAssertionHandler (), NULL);
|
||||
IMG_Quit ();
|
||||
SDLNet_Quit ();
|
||||
TTF_Quit ();
|
||||
SDL_Quit ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_SDL_CreateWindow (SDL_Window ** wind)
|
||||
{
|
||||
Uint32 Flags;
|
||||
SDL_assert (NULL != wind);
|
||||
Flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL;
|
||||
*wind = SDL_CreateWindow (DEFAULT_WINDOW_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT, Flags);
|
||||
SDL_assert (NULL != *wind);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
common_SDL_ToggleFullscreen (SDL_Window * window)
|
||||
{
|
||||
Uint32 Flags = SDL_GetWindowFlags (window);
|
||||
if (Flags & SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||||
{
|
||||
Flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
Flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
SDL_SetWindowFullscreen (window, Flags);
|
||||
return Flags & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
|
||||
SDL_Surface *
|
||||
common_SDL_LoadSurfacePath (const std::string& path)
|
||||
{
|
||||
SDL_Surface *image;
|
||||
if (!(image = IMG_Load (path.c_str ())))
|
||||
{
|
||||
DEBUG_LOG ("IMG_Load: %s", IMG_GetError ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return image;
|
||||
}
|
197
src/lib_lua_common.cpp
Normal file
197
src/lib_lua_common.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include "lib_lua_common.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int l_map (lua_State*);
|
||||
static int l_split (lua_State*);
|
||||
static void call_va (lua_State*, const char*, const char*, ...);
|
||||
static void error (lua_State*, const char*, ...);
|
||||
|
||||
int
|
||||
common_lua_run (lua_State* L, const char* name, const char* buff, const size_t buff_len)
|
||||
{
|
||||
int error;
|
||||
error = luaL_loadbuffer (L, buff, buff_len, name) || lua_pcall (L, 0, 0, 0);
|
||||
if (error)
|
||||
{
|
||||
fprintf (stderr, "%s\n", lua_tostring (L, -1));
|
||||
lua_pop (L, 1); /* pop error message from the stack */
|
||||
}
|
||||
// common_lua_stack_dump (L);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_lua_stack_dump (lua_State* L)
|
||||
{
|
||||
int i, t, top;
|
||||
top = lua_gettop (L);
|
||||
for (i = 1; i <= top; i++)
|
||||
{ /* repeat for each level */
|
||||
t = lua_type (L, i);
|
||||
switch (t)
|
||||
{
|
||||
case LUA_TSTRING: /* strings */
|
||||
printf ("`%s'", lua_tostring (L, i));
|
||||
break;
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
printf (lua_toboolean (L, i) ? "true" : "false");
|
||||
break;
|
||||
case LUA_TNUMBER: /* numbers */
|
||||
printf ("%g", lua_tonumber (L, i));
|
||||
break;
|
||||
default: /* other values */
|
||||
printf ("%s", lua_typename (L, t));
|
||||
break;
|
||||
}
|
||||
printf (" "); /* put a separator */
|
||||
}
|
||||
printf ("\n"); /* end the listing */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
error (lua_State* L, const char* fmt, ...)
|
||||
{
|
||||
va_list argp;
|
||||
va_start (argp, fmt);
|
||||
vfprintf (stderr, fmt, argp);
|
||||
va_end (argp);
|
||||
lua_close (L);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load (const char* filename, int* width, int* height)
|
||||
{
|
||||
lua_State* L = luaL_newstate ();
|
||||
luaL_openlibs (L);
|
||||
if (luaL_loadfile (L, filename) || lua_pcall (L, 0, 0, 0))
|
||||
error (L, "cannot run configuration file: %s", lua_tostring (L, -1));
|
||||
lua_getglobal (L, "width");
|
||||
lua_getglobal (L, "height");
|
||||
if (!lua_isnumber (L, -2))
|
||||
error (L, "`width' should be a number\n");
|
||||
if (!lua_isnumber (L, -1))
|
||||
error (L, "`height' should be a number\n");
|
||||
*width = (int) lua_tonumber (L, -2);
|
||||
*height = (int) lua_tonumber (L, -1);
|
||||
lua_close (L);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
call_va (lua_State* L, const char* func, const char* sig, ...)
|
||||
{
|
||||
va_list vl;
|
||||
int narg, nres; /* number of arguments and results */
|
||||
va_start (vl, sig);
|
||||
lua_getglobal (L, func); /* get function */
|
||||
/* push arguments */
|
||||
narg = 0;
|
||||
while (*sig)
|
||||
{ /* push arguments */
|
||||
switch (*sig++)
|
||||
{
|
||||
case 'd': /* double argument */
|
||||
lua_pushnumber (L, va_arg (vl, double));
|
||||
break;
|
||||
case 'i': /* int argument */
|
||||
lua_pushnumber (L, va_arg (vl, int));
|
||||
break;
|
||||
case 's': /* string argument */
|
||||
lua_pushstring (L, va_arg (vl, char *));
|
||||
break;
|
||||
case '>':
|
||||
goto endwhile;
|
||||
default:
|
||||
error (L, "invalid option (%c)", *(sig - 1));
|
||||
}
|
||||
narg++;
|
||||
luaL_checkstack (L, 1, "too many arguments");
|
||||
}
|
||||
endwhile:
|
||||
/* do the call */
|
||||
nres = strlen (sig); /* number of expected results */
|
||||
/* do the call */
|
||||
if (lua_pcall (L, narg, nres, 0) != 0)
|
||||
error (L, "error running function `%s': %s", func, lua_tostring (L, -1));
|
||||
/* retrieve results */
|
||||
nres = -nres; /* stack index of first result */
|
||||
while (*sig)
|
||||
{ /* get results */
|
||||
switch (*sig++)
|
||||
{
|
||||
case 'd': /* double result */
|
||||
if (!lua_isnumber (L, nres))
|
||||
error (L, "wrong result type");
|
||||
*va_arg (vl, double *) = lua_tonumber (L, nres);
|
||||
break;
|
||||
case 'i': /* int result */
|
||||
if (!lua_isnumber (L, nres))
|
||||
error (L, "wrong result type");
|
||||
*va_arg (vl, int *) = (int) lua_tonumber (L, nres);
|
||||
break;
|
||||
case 's': /* string result */
|
||||
if (!lua_isstring (L, nres))
|
||||
error (L, "wrong result type");
|
||||
*va_arg (vl, const char **) = lua_tostring (L, nres);
|
||||
break;
|
||||
default:
|
||||
error (L, "invalid option (%c)", *(sig - 1));
|
||||
}
|
||||
nres++;
|
||||
}
|
||||
va_end (vl);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
l_map (lua_State * L)
|
||||
{
|
||||
int i, n;
|
||||
/* 1st argument must be a table (t) */
|
||||
luaL_checktype (L, 1, LUA_TTABLE);
|
||||
/* 2nd argument must be a function (f) */
|
||||
luaL_checktype (L, 2, LUA_TFUNCTION);
|
||||
n = luaL_len (L, 1); /* get size of table */
|
||||
for (i = 1; i <= n; i++)
|
||||
{
|
||||
lua_pushvalue (L, 2); /* push f */
|
||||
lua_rawgeti (L, 1, i); /* push t[i] */
|
||||
lua_call (L, 1, 1); /* call f(t[i]) */
|
||||
lua_rawseti (L, 1, i); /* t[i] = result */
|
||||
}
|
||||
return 0; /* no results */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
l_split (lua_State* L)
|
||||
{
|
||||
int i;
|
||||
const char* s;
|
||||
const char* e;
|
||||
const char* sep;
|
||||
i = 1;
|
||||
s = luaL_checkstring (L, 1);
|
||||
sep = luaL_checkstring (L, 2);
|
||||
lua_newtable (L); /* result */
|
||||
/* repeat for each separator */
|
||||
while ((e = strchr (s, *sep)) != NULL)
|
||||
{
|
||||
/* push substring */
|
||||
lua_pushlstring (L, s, e - s);
|
||||
lua_rawseti (L, -2, i++);
|
||||
s = e + 1; /* skip separator */
|
||||
}
|
||||
/* push last substring */
|
||||
lua_pushstring (L, s);
|
||||
lua_rawseti (L, -2, i);
|
||||
return 1; /* return the table */
|
||||
}
|
24
src/object.cpp
Normal file
24
src/object.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "object.h"
|
||||
|
||||
Object::Object (const GLsizei size)
|
||||
: mGLsizei (size)
|
||||
{
|
||||
if (mGLsizei > 0)
|
||||
{
|
||||
glGenVertexArrays (mGLsizei, &VAO);
|
||||
glGenBuffers (mGLsizei, &VBO);
|
||||
glGenBuffers (mGLsizei, &EBO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object::~Object (void)
|
||||
{
|
||||
if (mGLsizei > 0)
|
||||
{
|
||||
glDeleteVertexArrays (mGLsizei, &VAO);
|
||||
glDeleteBuffers (mGLsizei, &VBO);
|
||||
glDeleteBuffers (mGLsizei, &EBO);
|
||||
mGLsizei = 0;
|
||||
}
|
||||
}
|
48
src/quad.cpp
Normal file
48
src/quad.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "quad.h"
|
||||
|
||||
Quad::Quad (const GLsizei size)
|
||||
: Object (size)
|
||||
{
|
||||
const unsigned int indices[] =
|
||||
{
|
||||
0, 1, 3, // first triangle
|
||||
1, 2, 3 // second triangle
|
||||
};
|
||||
|
||||
const float vertices[] =
|
||||
{
|
||||
// positions // texture coords
|
||||
// top right
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
// bottom right
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
// bottom left
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
// top left
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
glBindVertexArray (VAO);
|
||||
|
||||
glBindBuffer (GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof indices, indices, GL_STATIC_DRAW);
|
||||
|
||||
// position attribute
|
||||
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof (float), (void *) 0);
|
||||
glEnableVertexAttribArray (0);
|
||||
|
||||
// texture coord attribute
|
||||
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof (float), (void *) (3 * sizeof (float)));
|
||||
glEnableVertexAttribArray (1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Quad::Draw (void)
|
||||
{
|
||||
glBindVertexArray (VAO);
|
||||
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
}
|
245
src/server_main.cpp
Normal file
245
src/server_main.cpp
Normal file
@ -0,0 +1,245 @@
|
||||
#include "debug.h"
|
||||
#include "lib_SDL_common.h" /* SDL* */
|
||||
#include "Server.h"
|
||||
#include "signal_common.h"
|
||||
#include "unused.h"
|
||||
#include "events_common.h"
|
||||
#include "trim.h"
|
||||
#include "lib_lua_common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <stdlib.h> /* exit */
|
||||
#include <unistd.h> /* getopt */
|
||||
#include <getopt.h> /* getopt */
|
||||
#include <arpa/inet.h> /* inet_ntop */
|
||||
|
||||
static bool my_SDL_UserEvent (SDL_Event *);
|
||||
static void my_Usage (const char *);
|
||||
static void my_GetOpt (int, char **);
|
||||
static void my_ProcessPacket (UDPpacket *);
|
||||
|
||||
static const char* host = NULL;
|
||||
static Uint16 port = 6666;
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
bool done;
|
||||
SDL_Event ev;
|
||||
Server server;
|
||||
|
||||
my_GetOpt (argc, argv);
|
||||
common_Signal_Init ();
|
||||
common_SDL_Init ();
|
||||
|
||||
server = Server (host, port);
|
||||
server.Start ();
|
||||
|
||||
done = false;
|
||||
while (!done)
|
||||
{
|
||||
SDL_Delay (1);
|
||||
while (!done && SDL_PollEvent (&ev))
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
done = true;
|
||||
break;
|
||||
case SDL_USEREVENT:
|
||||
{
|
||||
done = my_SDL_UserEvent (&ev);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server.UDP_CloseAll ();
|
||||
server.Stop ();
|
||||
|
||||
common_SDL_Quit ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
my_SDL_UserEvent (SDL_Event * ev)
|
||||
{
|
||||
SDL_assert (NULL != ev);
|
||||
switch (ev->user.type)
|
||||
{
|
||||
case PACKET_SDL_EVENT:
|
||||
{
|
||||
UDPpacket *packet = (UDPpacket *) ev->user.data1;
|
||||
my_ProcessPacket (packet);
|
||||
SDLNet_FreePacket (packet);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* XXX gross */
|
||||
static std::vector<char> server_data;
|
||||
static bool left_shift = false;
|
||||
|
||||
/* XXX gross */
|
||||
static void
|
||||
my_ProcessPacket (UDPpacket* packet)
|
||||
{
|
||||
char c;
|
||||
size_t len;
|
||||
char hoststring[128];
|
||||
SDL_Event event;
|
||||
|
||||
if (!packet)
|
||||
return;
|
||||
SDL_assert (NULL != packet);
|
||||
if (!packet->len)
|
||||
return;
|
||||
SDL_assert (packet->len > 0);
|
||||
|
||||
len = packet->len;
|
||||
SDL_memcpy (&event, packet->data, len);
|
||||
|
||||
if ((event.type != SDL_KEYDOWN) && (event.type != SDL_KEYUP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key.keysym.scancode != SDL_GetScancodeFromKey (event.key.keysym.sym))
|
||||
{
|
||||
DEBUG_LOG ("Physical %s key acting as %s key", SDL_GetScancodeName (event.key.keysym.scancode), SDL_GetKeyName (event.key.keysym.sym));
|
||||
}
|
||||
std::string str = std::string (SDL_GetKeyName (event.key.keysym.sym));
|
||||
bool down = (event.type == SDL_KEYDOWN);
|
||||
|
||||
inet_ntop (AF_INET, &packet->address.host, hoststring, 128);
|
||||
DEBUG_LOG ("%d bytes from %s:%d:\n%s", packet->len, hoststring, ntohs (packet->address.port), str.c_str ());
|
||||
|
||||
// SDL_Log ("%d \"%s\"", str.length(), str.c_str ());
|
||||
|
||||
/* XXX ultra gross */
|
||||
if (down) {
|
||||
if (str.length () > 1)
|
||||
{
|
||||
if (str == "Return")
|
||||
{
|
||||
server_data.push_back ('\0');
|
||||
lua_State* L = luaL_newstate ();
|
||||
luaL_openlibs (L);
|
||||
std::string buf = std::string ((const char*)server_data.data ());
|
||||
printf ("\n => ");
|
||||
fflush (stdout);
|
||||
common_lua_run (L, "line", buf.c_str (), buf.length ());
|
||||
fflush (stdout);
|
||||
lua_close (L);
|
||||
server_data.clear ();
|
||||
}
|
||||
else if (str == "Left Shift")
|
||||
{
|
||||
left_shift = (bool) true;
|
||||
}
|
||||
else if (str == "Space")
|
||||
{
|
||||
server_data.push_back (' ');
|
||||
putchar (' ');
|
||||
fflush (stdout);
|
||||
}
|
||||
else if (str == "Backspace")
|
||||
{
|
||||
off_t size = server_data.size () - 1;
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
server_data.resize (size);
|
||||
printf ("\x08\e[0K");
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = tolower (str[0]);
|
||||
if (isalpha (c))
|
||||
{
|
||||
if (left_shift)
|
||||
c = toupper (c);
|
||||
}
|
||||
else if (isdigit (c))
|
||||
{
|
||||
const char* sym = ")!@#$%^&*(";
|
||||
if (left_shift)
|
||||
c = sym[c - '0'];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left_shift)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\'': c = '"'; break;
|
||||
case ',': c = '<'; break;
|
||||
case '-': c = '_'; break;
|
||||
case '.': c = '>'; break;
|
||||
case '/': c = '?'; break;
|
||||
case ';': c = ':'; break;
|
||||
case '=': c = '+'; break;
|
||||
case '[': c = '{'; break;
|
||||
case '\\': c = '|'; break;
|
||||
case ']': c = '}'; break;
|
||||
case '`': c = '~'; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
server_data.push_back (c);
|
||||
putchar (c);
|
||||
fflush (stdout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str == "Left Shift")
|
||||
{
|
||||
left_shift = (bool) false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_Usage (const char *argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-h] [-s server] [-p port]\n", argv0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
my_GetOpt (int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'p':
|
||||
port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 's':
|
||||
host = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
my_Usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
258
src/shader.cpp
Normal file
258
src/shader.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
#include "debug.h"
|
||||
#include "shader.h"
|
||||
#include "FileIO.h"
|
||||
#include "lib_GL_common.h"
|
||||
|
||||
#include <SDL_assert.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#define DEFAULT_FRAGMENT_HEADER "./glsl/header.f.glsl"
|
||||
|
||||
ShaderProgram::ShaderProgram (void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ShaderProgram::ShaderProgram (const std::string& vertexPath, const std::string& geometryPath, const std::string& fragmentPath)
|
||||
{
|
||||
GLuint vertex, geometry, fragment;
|
||||
|
||||
ID = glCreateProgram ();
|
||||
if (ID)
|
||||
{
|
||||
vertex = CompileShaderPath (vertexPath, GL_VERTEX_SHADER);
|
||||
|
||||
geometry = 0;
|
||||
if (!geometryPath.empty ())
|
||||
geometry = CompileShaderPath (geometryPath, GL_GEOMETRY_SHADER);
|
||||
|
||||
FileIO f1 (DEFAULT_FRAGMENT_HEADER, "r");
|
||||
FileIO f2 (fragmentPath, "r");
|
||||
std::string buf = f1.ReadToString () + "\n" + f2.ReadToString ();
|
||||
fragment = CompileShaderBuffer (buf.c_str (), GL_FRAGMENT_SHADER);
|
||||
|
||||
if (vertex)
|
||||
glAttachShader (ID, vertex);
|
||||
if (geometry)
|
||||
glAttachShader (ID, geometry);
|
||||
if (fragment)
|
||||
glAttachShader (ID, fragment);
|
||||
|
||||
glLinkProgram (ID);
|
||||
|
||||
if (!my_checkCompileSuccess (ID, GL_PROGRAM))
|
||||
{
|
||||
throw "glLinkProgram error";
|
||||
ID = 0;
|
||||
}
|
||||
|
||||
glDeleteShader (vertex);
|
||||
glDeleteShader (geometry);
|
||||
glDeleteShader (fragment);
|
||||
|
||||
RefreshUniformLocations ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ID = 0;
|
||||
throw "ShaderProgram error";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Use (void)
|
||||
{
|
||||
glUseProgram (ID);
|
||||
}
|
||||
|
||||
|
||||
GLint ShaderProgram::getCachedLoc (const std::string& name)
|
||||
{
|
||||
if (mUniformLocationsNeedRefresh)
|
||||
RefreshUniformLocations ();
|
||||
auto const& ref = UniformLocationCache.find (name);
|
||||
if (ref == UniformLocationCache.end ())
|
||||
{
|
||||
/* It didn't exist */
|
||||
int loc = glGetUniformLocation (ID, name.c_str ());
|
||||
if (loc == -1)
|
||||
{
|
||||
}
|
||||
UniformLocationCache[name] = loc;
|
||||
}
|
||||
return UniformLocationCache[name];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::RefreshUniformLocations (void)
|
||||
{
|
||||
for (auto& itm : UniformLocationCache)
|
||||
{
|
||||
itm.second = glGetUniformLocation (ID, itm.first.c_str ());
|
||||
if (itm.second == -1)
|
||||
UniformLocationCache.erase (itm.first);
|
||||
}
|
||||
mUniformLocationsNeedRefresh = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Bool (const std::string& name, const bool&value)
|
||||
{
|
||||
glUniform1i (getCachedLoc (name), (int) value);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Float (const std::string& name, const float&value)
|
||||
{
|
||||
glUniform1f (getCachedLoc (name), (float) value);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Int (const std::string& name, const int&value)
|
||||
{
|
||||
glUniform1i (getCachedLoc (name), (int) value);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Vec2 (const std::string& name, const glm::vec2& value)
|
||||
{
|
||||
glUniform2fv (getCachedLoc (name), 1, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Vec3 (const std::string& name, const glm::vec3& value)
|
||||
{
|
||||
glUniform3fv (getCachedLoc (name), 1, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Vec4 (const std::string& name, const glm::vec4& value)
|
||||
{
|
||||
glUniform4fv (getCachedLoc (name), 1, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Mat2 (const std::string& name, const glm::mat2& value)
|
||||
{
|
||||
glUniformMatrix2fv (getCachedLoc (name), 1, GL_FALSE, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Mat3 (const std::string& name, const glm::mat3& value)
|
||||
{
|
||||
glUniformMatrix3fv (getCachedLoc (name), 1, GL_FALSE, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ShaderProgram::Mat4 (const std::string& name, const glm::mat4& value)
|
||||
{
|
||||
glUniformMatrix4fv (getCachedLoc (name), 1, GL_FALSE, glm::value_ptr (value));
|
||||
}
|
||||
|
||||
|
||||
GLuint ShaderProgram::CompileShaderPath (const std::string& path, const GLenum type)
|
||||
{
|
||||
FileIO f (path, "r");
|
||||
std::string buf = f.ReadToString ();
|
||||
|
||||
if (buf.empty ())
|
||||
return 0;
|
||||
|
||||
return CompileShaderBuffer (buf.c_str (), type);
|
||||
}
|
||||
|
||||
|
||||
GLuint ShaderProgram::CompileShaderBuffer (const std::string& buf, const GLenum type)
|
||||
{
|
||||
GLuint id;
|
||||
if (buf.empty ())
|
||||
return 0;
|
||||
id = glCreateShader (type);
|
||||
if (id)
|
||||
{
|
||||
SDL_assert (0 != id);
|
||||
const char* code = buf.c_str ();
|
||||
glShaderSource (id, 1, &code, NULL);
|
||||
glCompileShader (id);
|
||||
if (!my_checkCompileSuccess (id, type))
|
||||
{
|
||||
DEBUG_LOG ("CompileShaderBuffer error");
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
GLint
|
||||
ShaderProgram::my_checkCompileSuccess (const GLuint id, const GLenum type)
|
||||
{
|
||||
GLint infoLogLength, success;
|
||||
std::string infoLog;
|
||||
std::string typeName = "UNKNOWN";
|
||||
infoLogLength = 0;
|
||||
success = GL_FALSE;
|
||||
switch (type)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
typeName = "GL_VERTEX_SHADER";
|
||||
goto HANDLE_SHADER;
|
||||
case GL_GEOMETRY_SHADER:
|
||||
typeName = "GL_GEOMETRY_SHADER";
|
||||
goto HANDLE_SHADER;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
typeName = "GL_FRAGMENT_SHADER";
|
||||
HANDLE_SHADER:
|
||||
glGetShaderiv (id, GL_COMPILE_STATUS,&success);
|
||||
if (GL_FALSE == success)
|
||||
glGetShaderiv (id, GL_INFO_LOG_LENGTH,&infoLogLength);
|
||||
break;
|
||||
case GL_PROGRAM:
|
||||
typeName = "PROGRAM";
|
||||
glGetProgramiv (id, GL_LINK_STATUS,&success);
|
||||
if (GL_FALSE == success)
|
||||
glGetProgramiv (id, GL_INFO_LOG_LENGTH,&success);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!infoLogLength)
|
||||
{
|
||||
return success;
|
||||
}
|
||||
infoLog.reserve (infoLogLength);
|
||||
switch (type)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
case GL_GEOMETRY_SHADER:
|
||||
case GL_FRAGMENT_SHADER:
|
||||
glGetShaderInfoLog (id, infoLogLength, NULL, &infoLog.front ());
|
||||
break;
|
||||
case GL_PROGRAM:
|
||||
glGetProgramInfoLog (id, infoLogLength, NULL, &infoLog.front ());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (infoLog[0] != '\0')
|
||||
{
|
||||
DEBUG_LOG ("%8s ERROR ============================================================\n%s", typeName.c_str (), infoLog.c_str ());
|
||||
}
|
||||
return success;
|
||||
}
|
63
src/signal_common.cpp
Normal file
63
src/signal_common.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#define _POSIX_C_SOURCE
|
||||
|
||||
#include "signal_common.h" /* conflict with signal.h probably */
|
||||
#include "unused.h"
|
||||
|
||||
#include <stdio.h> /* fputs */
|
||||
#include <signal.h> /* struct sigaction */
|
||||
#include <stdlib.h> /* exit */
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
/* TODO longjmp to cleanup handler */
|
||||
/* #include <setjmp.h> */
|
||||
/* sigjmp_buf env; */
|
||||
|
||||
static void
|
||||
my_Signal_Handler (int sig, siginfo_t* si, void* uap)
|
||||
{
|
||||
SDL_Event QUIT_EVENT = {SDL_QUIT};
|
||||
|
||||
UNUSED (sig);
|
||||
UNUSED (uap);
|
||||
UNUSED (si);
|
||||
|
||||
SDL_PushEvent (&QUIT_EVENT);
|
||||
exit (EXIT_FAILURE);
|
||||
/* siglongjmp (env, sig); */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
common_Signal_Init (void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = my_Signal_Handler;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
|
||||
if (sigaction (SIGINT, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGINT handler\n", stderr);
|
||||
}
|
||||
if (sigaction (SIGTERM, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGTERM handler\n", stderr);
|
||||
}
|
||||
if (sigaction (SIGILL, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGILL handler\n", stderr);
|
||||
}
|
||||
if (sigaction (SIGBUS, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGBUS handler\n", stderr);
|
||||
}
|
||||
if (sigaction (SIGSEGV, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGSEGV handler\n", stderr);
|
||||
}
|
||||
if (sigaction (SIGABRT, &sa, NULL) == -1)
|
||||
{
|
||||
fputs ("Failed to setup SIGABRT handler\n", stderr);
|
||||
}
|
||||
}
|
4
test/.gitignore
vendored
Normal file
4
test/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
test_FileIO
|
||||
test_File_Write_UDP
|
||||
test_lua
|
||||
test_Object
|
77
test/test_FileIO.cpp
Normal file
77
test/test_FileIO.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#include "FileIO.h"
|
||||
|
||||
#include <stdint.h> /* uint8_t */
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <errno.h> /* errno */
|
||||
#include <string.h> /* strerror */
|
||||
|
||||
static int
|
||||
IsProbablyAscii (const void *buf, const size_t len)
|
||||
{
|
||||
const uint8_t *bufPtr;
|
||||
const uint8_t *bufPtrEnd;
|
||||
size_t nAsciiCount;
|
||||
nAsciiCount = 0;
|
||||
bufPtr = (const uint8_t *) buf;
|
||||
bufPtrEnd = bufPtr + len;
|
||||
while (bufPtr < bufPtrEnd && (NULL != bufPtr) && (*bufPtr != '\0'))
|
||||
{
|
||||
nAsciiCount += (*bufPtr >= ' ') && (*bufPtr <= '~');
|
||||
bufPtr++;
|
||||
}
|
||||
return (int) round ((double) nAsciiCount / (double) len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
HexDump (const void *buf, const size_t len)
|
||||
{
|
||||
const uint8_t *bufPtr;
|
||||
const uint8_t *bufPtrEnd;
|
||||
const size_t width = 16;
|
||||
size_t nout;
|
||||
nout = 0;
|
||||
bufPtr = (const uint8_t *) buf;
|
||||
bufPtrEnd = bufPtr + len;
|
||||
while (bufPtr < bufPtrEnd && (NULL != bufPtr))
|
||||
{
|
||||
if (nout == width)
|
||||
{
|
||||
printf ("\n");
|
||||
nout = 0;
|
||||
}
|
||||
printf ("%02x ", *bufPtr);
|
||||
bufPtr++;
|
||||
nout++;
|
||||
}
|
||||
puts ("");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
rc = 1;
|
||||
try
|
||||
{
|
||||
while (argc-- > 1)
|
||||
{
|
||||
FileIO f (argv[argc], "r");
|
||||
std::string buf = f.ReadToString ();
|
||||
if (IsProbablyAscii (buf.c_str (), buf.size ()))
|
||||
printf ("%s", buf.c_str ());
|
||||
else
|
||||
HexDump (buf.c_str (), buf.size ());
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
catch (int err)
|
||||
{
|
||||
puts (strerror (errno));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
89
test/test_File_Write_UDP.cpp
Normal file
89
test/test_File_Write_UDP.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "FileIO.h"
|
||||
#include "UDP_Write.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <SDL_net.h>
|
||||
|
||||
static void usage (const char* argv0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-f path] [-h] [-p port] [-s server]\n", argv0);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
int opt;
|
||||
int numsent;
|
||||
int mtu;
|
||||
int channel;
|
||||
const char* path;
|
||||
const char* server;
|
||||
Uint16 port;
|
||||
|
||||
path = NULL;
|
||||
server = "localhost";
|
||||
port = 6666;
|
||||
channel = 1;
|
||||
mtu = 1450;
|
||||
numsent = 0;
|
||||
|
||||
while ((opt = getopt (argc, argv, "hs:p:f:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'h':
|
||||
usage (argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
case 's':
|
||||
server = optarg;
|
||||
if (!strcmp (server, "NULL"))
|
||||
server = NULL;
|
||||
break;
|
||||
case 'p':
|
||||
port = strtol (optarg, NULL, 0);
|
||||
break;
|
||||
case 'f':
|
||||
path = optarg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (optind < argc) {
|
||||
printf("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf("%s ", argv[optind++]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((optind < argc) && (argv[optind][0] == '-'))
|
||||
{
|
||||
const size_t size = 8192;
|
||||
std::vector<char> buf (size);
|
||||
std::fill (buf.begin(), buf.end(), 0);
|
||||
size_t nread = fread (buf.data (), sizeof (char), size - 1, stdin);
|
||||
numsent = SendBuffer_UDP (server, port, channel, mtu, buf.data (), nread);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (path)
|
||||
{
|
||||
numsent = SendFile_UDP (server, port, channel, mtu, path);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Log ("%d", numsent);
|
||||
|
||||
return 0;
|
||||
}
|
70
test/test_Object.cpp
Normal file
70
test/test_Object.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "lib_SDL_common.h"
|
||||
#include "lib_GL_common.h"
|
||||
|
||||
#include "object.h"
|
||||
#include "cube.h"
|
||||
#include "quad.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int Window_Height;
|
||||
int Window_Width;
|
||||
SDL_GLContext GLContext;
|
||||
SDL_Window *Window;
|
||||
|
||||
common_SDL_Init ();
|
||||
common_SDL_CreateWindow (&Window);
|
||||
common_GL_Init (Window, &GLContext, 1);
|
||||
SDL_GetWindowSize (Window, &Window_Width, &Window_Height);
|
||||
|
||||
try {
|
||||
SDL_Log ("Object o;");
|
||||
Object o;
|
||||
SDL_Log ("Cube c;");
|
||||
Cube c;
|
||||
SDL_Log ("Quad q;");
|
||||
Quad q;
|
||||
}
|
||||
catch (int e)
|
||||
{
|
||||
printf ("%d\n", e);
|
||||
}
|
||||
|
||||
try {
|
||||
SDL_Log ("Object (1);");
|
||||
Object o = Object (1);
|
||||
SDL_Log ("Cube (1);");
|
||||
Cube c = Cube (1);
|
||||
SDL_Log ("Quad (1);");
|
||||
Quad q = Quad (1);
|
||||
}
|
||||
catch (int e)
|
||||
{
|
||||
printf ("%d\n", e);
|
||||
}
|
||||
|
||||
try {
|
||||
SDL_Log ("Object o;");
|
||||
Object o;
|
||||
SDL_Log ("Cube c;");
|
||||
Cube c;
|
||||
SDL_Log ("Quad q;");
|
||||
Quad q;
|
||||
SDL_Log ("Object (1);");
|
||||
o = Object (1);
|
||||
SDL_Log ("Cube (1);");
|
||||
c = Cube (1);
|
||||
SDL_Log ("Quad (1);");
|
||||
q = Quad (1);
|
||||
}
|
||||
catch (int e)
|
||||
{
|
||||
printf ("%d\n", e);
|
||||
}
|
||||
|
||||
SDL_GL_DeleteContext (GLContext);
|
||||
SDL_DestroyWindow (Window);
|
||||
common_SDL_Quit ();
|
||||
}
|
24
test/test_lua.cpp
Normal file
24
test/test_lua.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "lib_lua_common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char buf[8192];
|
||||
lua_State* L;
|
||||
L = luaL_newstate ();
|
||||
luaL_openlibs (L);
|
||||
while (fgets (buf, 8191, stdin))
|
||||
{
|
||||
if (buf[strlen(buf)-1] == '\n')
|
||||
buf[strlen(buf)-1] = 0;
|
||||
if (strlen (buf) > 0)
|
||||
{
|
||||
printf (" => ");
|
||||
fflush (stdout);
|
||||
common_lua_run (L, "line", buf, strlen (buf));
|
||||
}
|
||||
}
|
||||
lua_close (L);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user