string GLSLError(uint obj, bool isprogram, const char *source) { GLint length = 0; if (isprogram) glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &length); else glGetShaderiv (obj, GL_INFO_LOG_LENGTH, &length); if (length > 1) { GLchar *log = new GLchar[length]; if (isprogram) glGetProgramInfoLog(obj, length, &length, log); else glGetShaderInfoLog (obj, length, &length, log); string err = "GLSL ERROR: "; err += log; int i = 0; if (source) for (;;) { err += inttoa(++i); err += ": "; const char *next = strchr(source, '\n'); if (next) { err += string(source, next - source + 1); source = next + 1; } else { err += string(source) + "\n"; break; } } delete[] log; return err; } return ""; }
char * UDP_Socket::addToProgram() { char *tcp = " 2 "; char my_InetAddr[MAX_INET_ADDR]; char myPortNum[8]; char me[30]; unsigned int thePort = this->getPortNumber(); int start = 0; inttoa(thePort,myPortNum,&start); gethostname(me,MAX_INET_ADDR); GetHostAddr(me,my_InetAddr); char *newStuff =(char *)malloc(100*sizeof(char)); for (int i=0; i<100; i++) newStuff[i] = ' '; strcpy(newStuff,tcp); strcat(newStuff," "); strcat(newStuff,my_InetAddr); strcat(newStuff," "); strcat(newStuff,myPortNum); strcat(newStuff," "); return newStuff; }
static void inttoa(unsigned int no, char *string, int *cnt) { if (no /10) { inttoa(no/10, string, cnt); *cnt = *cnt+1; } string[*cnt] = no % 10 + '0'; }
/* * Append an integer to the end of the message. */ static void ap_int(int num) { char buf[13]; inttoa(num, buf, sizeof buf); ap_str(buf); }
string Shader::Compile(const char *name, const char *vscode, const char *pscode) { program = glCreateProgram(); string err; vs = CompileGLSLShader(GL_VERTEX_SHADER, program, vscode, err); if (!vs) return string("couldn't compile vertex shader: ") + name + "\n" + err; ps = CompileGLSLShader(GL_FRAGMENT_SHADER, program, pscode, err); if (!ps) return string("couldn't compile pixel shader: ") + name + "\n" + err; glBindAttribLocation(program, 0, "apos"); glBindAttribLocation(program, 1, "anormal"); glBindAttribLocation(program, 2, "atc"); glBindAttribLocation(program, 3, "acolor"); glBindAttribLocation(program, 4, "aweights"); glBindAttribLocation(program, 5, "aindices"); glLinkProgram(program); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status != GL_TRUE) { GLSLError(program, true, NULL); throw string("linking failed for shader: ") + name; } mvp_i = glGetUniformLocation(program, "mvp"); col_i = glGetUniformLocation(program, "col"); camera_i = glGetUniformLocation(program, "camera"); light1_i = glGetUniformLocation(program, "light1"); bones_i = glGetUniformLocation(program, "bones"); glUseProgram(program); for (int i = 0; i < MAX_SAMPLERS; i++) { tex_i[i] = glGetUniformLocation(program, (string("tex") + inttoa(i)).c_str()); if (tex_i[i] >= 0) glUniform1i(tex_i[i], i); } return ""; }
string SDLInit(const char *title, int2 &screensize, bool fullscreen) { //SDL_SetMainReady(); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER /* | SDL_INIT_AUDIO*/) < 0) { return SDLError("Unable to initialize SDL"); } SDL_SetEventFilter(SDLHandleAppEvents, nullptr); DebugLog(-1, "SDL initialized..."); SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); // on demand now //extern bool sfxr_init(); //if (!sfxr_init()) // return SDLError("Unable to initialize audio"); #ifdef PLATFORM_MOBILE SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); #else //certain older Intel HD GPUs and also Nvidia Quadro 1000M don't support 3.1 ? the 1000M is supposed to support 4.2 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #ifndef WIN32 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); #endif SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); #endif //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); // set this if we're in 2D mode for speed on mobile? SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1); // because we redraw the screen each frame SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); DebugLog(-1, "SDL about to figure out display mode..."); #ifdef PLATFORM_MOBILE landscape = screensize.x() >= screensize.y(); int modes = SDL_GetNumDisplayModes(0); screensize = int2(0); for (int i = 0; i < modes; i++) { SDL_DisplayMode mode; SDL_GetDisplayMode(0, i, &mode); //printf("mode: %d %d\n", mode.w, mode.h); if (landscape ? mode.w > screensize.x() : mode.h > screensize.y()) { screensize = int2(mode.w, mode.h); } } DebugLog(-1, inttoa(screensize.x())); DebugLog(-1, inttoa(screensize.y())); DebugLog(-1, "SDL about to create window..."); _sdl_window = SDL_CreateWindow(title, 0, 0, screensize.x(), screensize.y(), SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS); DebugLog(-1, _sdl_window ? "SDL window passed..." : "SDL window FAILED..."); if (landscape) SDL_SetHint("SDL_HINT_ORIENTATIONS", "LandscapeLeft LandscapeRight"); int ax = 0, ay = 0; SDL_GetWindowSize(_sdl_window, &ax, &ay); int2 actualscreensize(ax, ay); //screenscalefactor = screensize.x / actualscreensize.x; // should be 2 on retina #ifdef __IOS__ assert(actualscreensize == screensize); screensize = actualscreensize; #else screensize = actualscreensize; // __ANDROID__ DebugLog(-1, inttoa(screensize.x())); DebugLog(-1, inttoa(screensize.y())); #endif #else _sdl_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screensize.x(), screensize.y(), SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); #endif if (!_sdl_window) return SDLError("Unable to create window"); DebugLog(-1, "SDL window opened..."); _sdl_context = SDL_GL_CreateContext(_sdl_window); DebugLog(-1, _sdl_context ? "SDL context passed..." : "SDL context FAILED..."); if (!_sdl_context) return SDLError("Unable to create OpenGL context"); DebugLog(-1, "SDL OpenGL context created..."); /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */ #ifndef __IOS__ SDL_GL_SetSwapInterval(1); // vsync on #endif SDL_JoystickEventState(SDL_ENABLE); SDL_JoystickUpdate(); for(int i = 0; i < SDL_NumJoysticks(); i++) { SDL_Joystick *joy; if (joy = SDL_JoystickOpen(i)) { DebugLog(-1, "Detected joystick: %s (%d axes, %d buttons, %d balls, %d hats)\n", SDL_JoystickName(joy), SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumBalls(joy), SDL_JoystickNumHats(joy)); }; }; starttime = SDL_GetTicks(); lastmillis = starttime - 16; // ensure first frame doesn't get a crazy delta return ""; }
string LoadMaterialFile(const char *mfile) { auto mbuf = (char *)LoadFile(mfile); auto p = mbuf; string err; string last; string vfunctions, pfunctions, vertex, pixel, vdecl, pdecl, shader; string *accum = NULL; string header; #if defined(__IOS__) || defined(ANDROID) header += "#ifdef GL_ES\nprecision highp float;\n#endif\n"; #else //#ifdef __APPLE__ header += "#version 120\n"; //#else //header += "#version 130\n"; //#endif #endif auto word = [&]() { p += strspn(p, " \t\r"); size_t len = strcspn(p, " \t\r\0"); last = string(p, len); p += len; }; auto finish = [&]() -> bool { if (!shader.empty()) { auto sh = new Shader(); err = sh->Compile(shader.c_str(), (header + vdecl + vfunctions + "void main()\n{\n" + vertex + "}\n").c_str(), (header + pdecl + pfunctions + "void main()\n{\n" + pixel + "}\n").c_str()); if (!err.empty()) return true; shadermap[shader] = sh; shader.clear(); } return false; }; for (;;) { auto start = p; auto end = p + strcspn(p, "\n\0"); bool eof = !*end; *end = 0; word(); if (!last.empty()) { if (last == "VERTEXFUNCTIONS") { if (finish()) goto out; vfunctions.clear(); accum = &vfunctions; } else if (last == "PIXELFUNCTIONS") { if (finish()) goto out; pfunctions.clear(); accum = &pfunctions; } else if (last == "VERTEX") { vertex.clear(); accum = &vertex; } else if (last == "PIXEL") { pixel.clear(); accum = &pixel; } else if (last == "SHADER") { if (finish()) goto out; word(); shader = last; vdecl.clear(); pdecl.clear(); accum = NULL; } else if (last == "UNIFORMS") { string &decl = accum == &vertex ? vdecl : pdecl; for (;;) { word(); if (last.empty()) break; else if (last == "mvp") decl += "uniform mat4 mvp;\n"; else if (last == "col") decl += "uniform vec4 col;\n"; else if (last == "camera") decl += "uniform vec3 camera;\n"; else if (last == "light1") decl += "uniform vec3 light1;\n"; else if (last == "bones") decl += "uniform vec4 bones[240];\n"; // FIXME: configurable else if (strstr(last.c_str(), "tex")) decl += "uniform sampler2D " + last + ";\n"; else { err = "unknown uniform: " + last; goto out; } } } else if (last == "INPUTS") { string decl; for (;;) { word(); if (last.empty()) break; auto pos = strstr(last.c_str(), ":"); if (!pos) { err = "input " + last + " doesn't specify number of components, e.g. anormal:3"; goto out; } int comp = atoi(pos + 1); if (comp <= 0 || comp > 4) { err = "input " + last + " can only use 1..4 components"; goto out; } last = last.substr(0, pos - last.c_str()); string d = string(" vec") + inttoa(comp) + " " + last + ";\n"; if (accum == &vertex) vdecl += "attribute" + d; else { d = "varying" + d; vdecl += d; pdecl += d; } } } else { if (!accum) { err = "GLSL code outside of FUNCTIONS/VERTEX/PIXEL block: " + string(start); goto out; } *accum += start; *accum += "\n"; } } if (eof) break; p = end + 1; } finish(); out: free(mbuf); return err; }