diff options
| author | xolatile | 2025-08-04 22:53:42 +0200 |
|---|---|---|
| committer | xolatile | 2025-08-04 22:53:42 +0200 |
| commit | d309df4ce4d8ad0ed995a8e1c4267412a7782021 (patch) | |
| tree | 999ca8d785ecc1681e5eb7538ce2e6a18d244fa5 /src/engine/rendergl.cpp | |
| parent | 29d613d9cb65a0faa7e3f80e75bea0b6d910cb9a (diff) | |
| download | xolatile-badassbug-d309df4ce4d8ad0ed995a8e1c4267412a7782021.tar.xz xolatile-badassbug-d309df4ce4d8ad0ed995a8e1c4267412a7782021.tar.zst | |
Bunch of small changes...
Diffstat (limited to 'src/engine/rendergl.cpp')
| -rw-r--r-- | src/engine/rendergl.cpp | 2997 |
1 files changed, 1424 insertions, 1573 deletions
diff --git a/src/engine/rendergl.cpp b/src/engine/rendergl.cpp index b05be7d..997d15a 100644 --- a/src/engine/rendergl.cpp +++ b/src/engine/rendergl.cpp @@ -12,140 +12,140 @@ VAR(glcompat, 1, 0, 0); PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays_ = NULL; PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements_ = NULL; -PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate_ = NULL; +PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate_ = NULL; PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate_ = NULL; -PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_ = NULL; +PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_ = NULL; PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate_ = NULL; PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate_ = NULL; -PFNGLGENBUFFERSPROC glGenBuffers_ = NULL; -PFNGLBINDBUFFERPROC glBindBuffer_ = NULL; -PFNGLMAPBUFFERPROC glMapBuffer_ = NULL; -PFNGLUNMAPBUFFERPROC glUnmapBuffer_ = NULL; -PFNGLBUFFERDATAPROC glBufferData_ = NULL; -PFNGLBUFFERSUBDATAPROC glBufferSubData_ = NULL; -PFNGLDELETEBUFFERSPROC glDeleteBuffers_ = NULL; +PFNGLGENBUFFERSPROC glGenBuffers_ = NULL; +PFNGLBINDBUFFERPROC glBindBuffer_ = NULL; +PFNGLMAPBUFFERPROC glMapBuffer_ = NULL; +PFNGLUNMAPBUFFERPROC glUnmapBuffer_ = NULL; +PFNGLBUFFERDATAPROC glBufferData_ = NULL; +PFNGLBUFFERSUBDATAPROC glBufferSubData_ = NULL; +PFNGLDELETEBUFFERSPROC glDeleteBuffers_ = NULL; PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData_ = NULL; -PFNGLGENQUERIESPROC glGenQueries_ = NULL; -PFNGLDELETEQUERIESPROC glDeleteQueries_ = NULL; -PFNGLBEGINQUERYPROC glBeginQuery_ = NULL; -PFNGLENDQUERYPROC glEndQuery_ = NULL; -PFNGLGETQUERYIVPROC glGetQueryiv_ = NULL; +PFNGLGENQUERIESPROC glGenQueries_ = NULL; +PFNGLDELETEQUERIESPROC glDeleteQueries_ = NULL; +PFNGLBEGINQUERYPROC glBeginQuery_ = NULL; +PFNGLENDQUERYPROC glEndQuery_ = NULL; +PFNGLGETQUERYIVPROC glGetQueryiv_ = NULL; PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv_ = NULL; PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv_ = NULL; -PFNGLCREATEPROGRAMPROC glCreateProgram_ = NULL; -PFNGLDELETEPROGRAMPROC glDeleteProgram_ = NULL; -PFNGLUSEPROGRAMPROC glUseProgram_ = NULL; -PFNGLCREATESHADERPROC glCreateShader_ = NULL; -PFNGLDELETESHADERPROC glDeleteShader_ = NULL; -PFNGLSHADERSOURCEPROC glShaderSource_ = NULL; -PFNGLCOMPILESHADERPROC glCompileShader_ = NULL; -PFNGLGETSHADERIVPROC glGetShaderiv_ = NULL; -PFNGLGETPROGRAMIVPROC glGetProgramiv_ = NULL; -PFNGLATTACHSHADERPROC glAttachShader_ = NULL; -PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_ = NULL; -PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_ = NULL; -PFNGLLINKPROGRAMPROC glLinkProgram_ = NULL; -PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_ = NULL; -PFNGLUNIFORM1FPROC glUniform1f_ = NULL; -PFNGLUNIFORM2FPROC glUniform2f_ = NULL; -PFNGLUNIFORM3FPROC glUniform3f_ = NULL; -PFNGLUNIFORM4FPROC glUniform4f_ = NULL; -PFNGLUNIFORM1FVPROC glUniform1fv_ = NULL; -PFNGLUNIFORM2FVPROC glUniform2fv_ = NULL; -PFNGLUNIFORM3FVPROC glUniform3fv_ = NULL; -PFNGLUNIFORM4FVPROC glUniform4fv_ = NULL; -PFNGLUNIFORM1IPROC glUniform1i_ = NULL; -PFNGLUNIFORM2IPROC glUniform2i_ = NULL; -PFNGLUNIFORM3IPROC glUniform3i_ = NULL; -PFNGLUNIFORM4IPROC glUniform4i_ = NULL; -PFNGLUNIFORM1IVPROC glUniform1iv_ = NULL; -PFNGLUNIFORM2IVPROC glUniform2iv_ = NULL; -PFNGLUNIFORM3IVPROC glUniform3iv_ = NULL; -PFNGLUNIFORM4IVPROC glUniform4iv_ = NULL; -PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_ = NULL; -PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_ = NULL; -PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_ = NULL; -PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_ = NULL; -PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_ = NULL; +PFNGLCREATEPROGRAMPROC glCreateProgram_ = NULL; +PFNGLDELETEPROGRAMPROC glDeleteProgram_ = NULL; +PFNGLUSEPROGRAMPROC glUseProgram_ = NULL; +PFNGLCREATESHADERPROC glCreateShader_ = NULL; +PFNGLDELETESHADERPROC glDeleteShader_ = NULL; +PFNGLSHADERSOURCEPROC glShaderSource_ = NULL; +PFNGLCOMPILESHADERPROC glCompileShader_ = NULL; +PFNGLGETSHADERIVPROC glGetShaderiv_ = NULL; +PFNGLGETPROGRAMIVPROC glGetProgramiv_ = NULL; +PFNGLATTACHSHADERPROC glAttachShader_ = NULL; +PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_ = NULL; +PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_ = NULL; +PFNGLLINKPROGRAMPROC glLinkProgram_ = NULL; +PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_ = NULL; +PFNGLUNIFORM1FPROC glUniform1f_ = NULL; +PFNGLUNIFORM2FPROC glUniform2f_ = NULL; +PFNGLUNIFORM3FPROC glUniform3f_ = NULL; +PFNGLUNIFORM4FPROC glUniform4f_ = NULL; +PFNGLUNIFORM1FVPROC glUniform1fv_ = NULL; +PFNGLUNIFORM2FVPROC glUniform2fv_ = NULL; +PFNGLUNIFORM3FVPROC glUniform3fv_ = NULL; +PFNGLUNIFORM4FVPROC glUniform4fv_ = NULL; +PFNGLUNIFORM1IPROC glUniform1i_ = NULL; +PFNGLUNIFORM2IPROC glUniform2i_ = NULL; +PFNGLUNIFORM3IPROC glUniform3i_ = NULL; +PFNGLUNIFORM4IPROC glUniform4i_ = NULL; +PFNGLUNIFORM1IVPROC glUniform1iv_ = NULL; +PFNGLUNIFORM2IVPROC glUniform2iv_ = NULL; +PFNGLUNIFORM3IVPROC glUniform3iv_ = NULL; +PFNGLUNIFORM4IVPROC glUniform4iv_ = NULL; +PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_ = NULL; +PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_ = NULL; +PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_ = NULL; +PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_ = NULL; +PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_ = NULL; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_ = NULL; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_ = NULL; -PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_ = NULL; -PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_ = NULL; -PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s_ = NULL; -PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv_ = NULL; -PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_ = NULL; -PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_ = NULL; -PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s_ = NULL; -PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv_ = NULL; -PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_ = NULL; -PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_ = NULL; -PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s_ = NULL; -PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv_ = NULL; -PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_ = NULL; -PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_ = NULL; -PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s_ = NULL; -PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv_ = NULL; -PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv_ = NULL; -PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv_ = NULL; -PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv_ = NULL; -PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv_ = NULL; -PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv_ = NULL; -PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv_ = NULL; -PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv_ = NULL; -PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub_ = NULL; -PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv_ = NULL; -PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv_ = NULL; -PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv_ = NULL; -PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_ = NULL; +PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_ = NULL; +PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_ = NULL; +PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s_ = NULL; +PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv_ = NULL; +PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_ = NULL; +PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_ = NULL; +PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s_ = NULL; +PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv_ = NULL; +PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_ = NULL; +PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_ = NULL; +PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s_ = NULL; +PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv_ = NULL; +PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_ = NULL; +PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_ = NULL; +PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s_ = NULL; +PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv_ = NULL; +PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv_ = NULL; +PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv_ = NULL; +PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv_ = NULL; +PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv_ = NULL; +PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv_ = NULL; +PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv_ = NULL; +PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv_ = NULL; +PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub_ = NULL; +PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv_ = NULL; +PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv_ = NULL; +PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv_ = NULL; +PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_ = NULL; PFNGLDRAWBUFFERSPROC glDrawBuffers_ = NULL; // OpenGL 3.0 -PFNGLGETSTRINGIPROC glGetStringi_ = NULL; +PFNGLGETSTRINGIPROC glGetStringi_ = NULL; PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation_ = NULL; // GL_EXT_framebuffer_object -PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_ = NULL; -PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_ = NULL; -PFNGLGENFRAMEBUFFERSPROC glGenRenderbuffers_ = NULL; -PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_ = NULL; +PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_ = NULL; +PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_ = NULL; +PFNGLGENFRAMEBUFFERSPROC glGenRenderbuffers_ = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_ = NULL; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus_ = NULL; -PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_ = NULL; -PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_ = NULL; -PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_ = NULL; -PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_ = NULL; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_ = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_ = NULL; +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_ = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_ = NULL; PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer_ = NULL; -PFNGLGENERATEMIPMAPPROC glGenerateMipmap_ = NULL; +PFNGLGENERATEMIPMAPPROC glGenerateMipmap_ = NULL; // GL_EXT_framebuffer_blit -PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer_ = NULL; +PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer_ = NULL; // GL_ARB_uniform_buffer_object -PFNGLGETUNIFORMINDICESPROC glGetUniformIndices_ = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv_ = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex_ = NULL; +PFNGLGETUNIFORMINDICESPROC glGetUniformIndices_ = NULL; +PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv_ = NULL; +PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex_ = NULL; PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv_ = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding_ = NULL; -PFNGLBINDBUFFERBASEPROC glBindBufferBase_ = NULL; -PFNGLBINDBUFFERRANGEPROC glBindBufferRange_ = NULL; +PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding_ = NULL; +PFNGLBINDBUFFERBASEPROC glBindBufferBase_ = NULL; +PFNGLBINDBUFFERRANGEPROC glBindBufferRange_ = NULL; // GL_ARB_map_buffer_range -PFNGLMAPBUFFERRANGEPROC glMapBufferRange_ = NULL; +PFNGLMAPBUFFERRANGEPROC glMapBufferRange_ = NULL; PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange_ = NULL; // GL_ARB_vertex_array_object -PFNGLBINDVERTEXARRAYPROC glBindVertexArray_ = NULL; +PFNGLBINDVERTEXARRAYPROC glBindVertexArray_ = NULL; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays_ = NULL; -PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_ = NULL; -PFNGLISVERTEXARRAYPROC glIsVertexArray_ = NULL; +PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_ = NULL; +PFNGLISVERTEXARRAYPROC glIsVertexArray_ = NULL; void *getprocaddress(const char *name) { - return SDL_GL_GetProcAddress(name); + return SDL_GL_GetProcAddress(name); } VARP(ati_skybox_bug, 0, 0, 1); @@ -161,406 +161,383 @@ VAR(rtscissor, 0, 1, 1); VAR(blurtile, 0, 1, 1); VAR(rtsharefb, 0, 1, 1); -VAR(dbgexts, 0, 0, 1); - hashset<const char *> glexts; void parseglexts() { - if(glversion >= 300) - { - GLint numexts = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &numexts); - loopi(numexts) - { - const char *ext = (const char *)glGetStringi_(GL_EXTENSIONS, i); - glexts.add(newstring(ext)); - } - } - else - { - const char *exts = (const char *)glGetString(GL_EXTENSIONS); - for(;;) - { - while(*exts == ' ') exts++; - if(!*exts) break; - const char *ext = exts; - while(*exts && *exts != ' ') exts++; - if(exts > ext) glexts.add(newstring(ext, size_t(exts-ext))); - } - } + if(glversion >= 300) + { + GLint numexts = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numexts); + loopi(numexts) + { + const char *ext = (const char *)glGetStringi_(GL_EXTENSIONS, i); + glexts.add(newstring(ext)); + } + } + else + { + const char *exts = (const char *)glGetString(GL_EXTENSIONS); + for(;;) + { + while(*exts == ' ') exts++; + if(!*exts) break; + const char *ext = exts; + while(*exts && *exts != ' ') exts++; + if(exts > ext) glexts.add(newstring(ext, size_t(exts-ext))); + } + } } bool hasext(const char *ext) { - return glexts.access(ext)!=NULL; + return glexts.access(ext)!=NULL; } void gl_checkextensions() { - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - const char *version = (const char *)glGetString(GL_VERSION); - conoutf(CON_INIT, "Renderer: %s (%s)", renderer, vendor); - conoutf(CON_INIT, "Driver: %s", version); - - bool mesa = false, intel = false, ati = false, nvidia = false; - if(strstr(renderer, "Mesa") || strstr(version, "Mesa")) - { - mesa = true; - if(strstr(renderer, "Intel")) intel = true; - } - else if(strstr(vendor, "NVIDIA")) - nvidia = true; - else if(strstr(vendor, "ATI") || strstr(vendor, "Advanced Micro Devices")) - ati = true; - else if(strstr(vendor, "Intel")) - intel = true; - - uint glmajorversion, glminorversion; - if(sscanf(version, " %u.%u", &glmajorversion, &glminorversion) != 2) glversion = 100; - else glversion = glmajorversion*100 + glminorversion*10; - - if(glversion < 200) fatal("OpenGL 2.0 or greater is required!"); - - glMultiDrawArrays_ = (PFNGLMULTIDRAWARRAYSPROC) getprocaddress("glMultiDrawArrays"); - glMultiDrawElements_ = (PFNGLMULTIDRAWELEMENTSPROC) getprocaddress("glMultiDrawElements"); - - glBlendFuncSeparate_ = (PFNGLBLENDFUNCSEPARATEPROC) getprocaddress("glBlendFuncSeparate"); - glBlendEquationSeparate_ = (PFNGLBLENDEQUATIONSEPARATEPROC) getprocaddress("glBlendEquationSeparate"); - glStencilOpSeparate_ = (PFNGLSTENCILOPSEPARATEPROC) getprocaddress("glStencilOpSeparate"); - glStencilFuncSeparate_ = (PFNGLSTENCILFUNCSEPARATEPROC) getprocaddress("glStencilFuncSeparate"); - glStencilMaskSeparate_ = (PFNGLSTENCILMASKSEPARATEPROC) getprocaddress("glStencilMaskSeparate"); - - glGenBuffers_ = (PFNGLGENBUFFERSPROC) getprocaddress("glGenBuffers"); - glBindBuffer_ = (PFNGLBINDBUFFERPROC) getprocaddress("glBindBuffer"); - glMapBuffer_ = (PFNGLMAPBUFFERPROC) getprocaddress("glMapBuffer"); - glUnmapBuffer_ = (PFNGLUNMAPBUFFERPROC) getprocaddress("glUnmapBuffer"); - glBufferData_ = (PFNGLBUFFERDATAPROC) getprocaddress("glBufferData"); - glBufferSubData_ = (PFNGLBUFFERSUBDATAPROC) getprocaddress("glBufferSubData"); - glDeleteBuffers_ = (PFNGLDELETEBUFFERSPROC) getprocaddress("glDeleteBuffers"); - glGetBufferSubData_ = (PFNGLGETBUFFERSUBDATAPROC) getprocaddress("glGetBufferSubData"); - - glGetQueryiv_ = (PFNGLGETQUERYIVPROC) getprocaddress("glGetQueryiv"); - glGenQueries_ = (PFNGLGENQUERIESPROC) getprocaddress("glGenQueries"); - glDeleteQueries_ = (PFNGLDELETEQUERIESPROC) getprocaddress("glDeleteQueries"); - glBeginQuery_ = (PFNGLBEGINQUERYPROC) getprocaddress("glBeginQuery"); - glEndQuery_ = (PFNGLENDQUERYPROC) getprocaddress("glEndQuery"); - glGetQueryObjectiv_ = (PFNGLGETQUERYOBJECTIVPROC) getprocaddress("glGetQueryObjectiv"); - glGetQueryObjectuiv_ = (PFNGLGETQUERYOBJECTUIVPROC) getprocaddress("glGetQueryObjectuiv"); - - glCreateProgram_ = (PFNGLCREATEPROGRAMPROC) getprocaddress("glCreateProgram"); - glDeleteProgram_ = (PFNGLDELETEPROGRAMPROC) getprocaddress("glDeleteProgram"); - glUseProgram_ = (PFNGLUSEPROGRAMPROC) getprocaddress("glUseProgram"); - glCreateShader_ = (PFNGLCREATESHADERPROC) getprocaddress("glCreateShader"); - glDeleteShader_ = (PFNGLDELETESHADERPROC) getprocaddress("glDeleteShader"); - glShaderSource_ = (PFNGLSHADERSOURCEPROC) getprocaddress("glShaderSource"); - glCompileShader_ = (PFNGLCOMPILESHADERPROC) getprocaddress("glCompileShader"); - glGetShaderiv_ = (PFNGLGETSHADERIVPROC) getprocaddress("glGetShaderiv"); - glGetProgramiv_ = (PFNGLGETPROGRAMIVPROC) getprocaddress("glGetProgramiv"); - glAttachShader_ = (PFNGLATTACHSHADERPROC) getprocaddress("glAttachShader"); - glGetProgramInfoLog_ = (PFNGLGETPROGRAMINFOLOGPROC) getprocaddress("glGetProgramInfoLog"); - glGetShaderInfoLog_ = (PFNGLGETSHADERINFOLOGPROC) getprocaddress("glGetShaderInfoLog"); - glLinkProgram_ = (PFNGLLINKPROGRAMPROC) getprocaddress("glLinkProgram"); - glGetUniformLocation_ = (PFNGLGETUNIFORMLOCATIONPROC) getprocaddress("glGetUniformLocation"); - glUniform1f_ = (PFNGLUNIFORM1FPROC) getprocaddress("glUniform1f"); - glUniform2f_ = (PFNGLUNIFORM2FPROC) getprocaddress("glUniform2f"); - glUniform3f_ = (PFNGLUNIFORM3FPROC) getprocaddress("glUniform3f"); - glUniform4f_ = (PFNGLUNIFORM4FPROC) getprocaddress("glUniform4f"); - glUniform1fv_ = (PFNGLUNIFORM1FVPROC) getprocaddress("glUniform1fv"); - glUniform2fv_ = (PFNGLUNIFORM2FVPROC) getprocaddress("glUniform2fv"); - glUniform3fv_ = (PFNGLUNIFORM3FVPROC) getprocaddress("glUniform3fv"); - glUniform4fv_ = (PFNGLUNIFORM4FVPROC) getprocaddress("glUniform4fv"); - glUniform1i_ = (PFNGLUNIFORM1IPROC) getprocaddress("glUniform1i"); - glUniform2i_ = (PFNGLUNIFORM2IPROC) getprocaddress("glUniform2i"); - glUniform3i_ = (PFNGLUNIFORM3IPROC) getprocaddress("glUniform3i"); - glUniform4i_ = (PFNGLUNIFORM4IPROC) getprocaddress("glUniform4i"); - glUniform1iv_ = (PFNGLUNIFORM1IVPROC) getprocaddress("glUniform1iv"); - glUniform2iv_ = (PFNGLUNIFORM2IVPROC) getprocaddress("glUniform2iv"); - glUniform3iv_ = (PFNGLUNIFORM3IVPROC) getprocaddress("glUniform3iv"); - glUniform4iv_ = (PFNGLUNIFORM4IVPROC) getprocaddress("glUniform4iv"); - glUniformMatrix2fv_ = (PFNGLUNIFORMMATRIX2FVPROC) getprocaddress("glUniformMatrix2fv"); - glUniformMatrix3fv_ = (PFNGLUNIFORMMATRIX3FVPROC) getprocaddress("glUniformMatrix3fv"); - glUniformMatrix4fv_ = (PFNGLUNIFORMMATRIX4FVPROC) getprocaddress("glUniformMatrix4fv"); - glBindAttribLocation_ = (PFNGLBINDATTRIBLOCATIONPROC) getprocaddress("glBindAttribLocation"); - glGetActiveUniform_ = (PFNGLGETACTIVEUNIFORMPROC) getprocaddress("glGetActiveUniform"); - glEnableVertexAttribArray_ = (PFNGLENABLEVERTEXATTRIBARRAYPROC) getprocaddress("glEnableVertexAttribArray"); - glDisableVertexAttribArray_ = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) getprocaddress("glDisableVertexAttribArray"); - - glVertexAttrib1f_ = (PFNGLVERTEXATTRIB1FPROC) getprocaddress("glVertexAttrib1f"); - glVertexAttrib1fv_ = (PFNGLVERTEXATTRIB1FVPROC) getprocaddress("glVertexAttrib1fv"); - glVertexAttrib1s_ = (PFNGLVERTEXATTRIB1SPROC) getprocaddress("glVertexAttrib1s"); - glVertexAttrib1sv_ = (PFNGLVERTEXATTRIB1SVPROC) getprocaddress("glVertexAttrib1sv"); - glVertexAttrib2f_ = (PFNGLVERTEXATTRIB2FPROC) getprocaddress("glVertexAttrib2f"); - glVertexAttrib2fv_ = (PFNGLVERTEXATTRIB2FVPROC) getprocaddress("glVertexAttrib2fv"); - glVertexAttrib2s_ = (PFNGLVERTEXATTRIB2SPROC) getprocaddress("glVertexAttrib2s"); - glVertexAttrib2sv_ = (PFNGLVERTEXATTRIB2SVPROC) getprocaddress("glVertexAttrib2sv"); - glVertexAttrib3f_ = (PFNGLVERTEXATTRIB3FPROC) getprocaddress("glVertexAttrib3f"); - glVertexAttrib3fv_ = (PFNGLVERTEXATTRIB3FVPROC) getprocaddress("glVertexAttrib3fv"); - glVertexAttrib3s_ = (PFNGLVERTEXATTRIB3SPROC) getprocaddress("glVertexAttrib3s"); - glVertexAttrib3sv_ = (PFNGLVERTEXATTRIB3SVPROC) getprocaddress("glVertexAttrib3sv"); - glVertexAttrib4f_ = (PFNGLVERTEXATTRIB4FPROC) getprocaddress("glVertexAttrib4f"); - glVertexAttrib4fv_ = (PFNGLVERTEXATTRIB4FVPROC) getprocaddress("glVertexAttrib4fv"); - glVertexAttrib4s_ = (PFNGLVERTEXATTRIB4SPROC) getprocaddress("glVertexAttrib4s"); - glVertexAttrib4sv_ = (PFNGLVERTEXATTRIB4SVPROC) getprocaddress("glVertexAttrib4sv"); - glVertexAttrib4bv_ = (PFNGLVERTEXATTRIB4BVPROC) getprocaddress("glVertexAttrib4bv"); - glVertexAttrib4iv_ = (PFNGLVERTEXATTRIB4IVPROC) getprocaddress("glVertexAttrib4iv"); - glVertexAttrib4ubv_ = (PFNGLVERTEXATTRIB4UBVPROC) getprocaddress("glVertexAttrib4ubv"); - glVertexAttrib4uiv_ = (PFNGLVERTEXATTRIB4UIVPROC) getprocaddress("glVertexAttrib4uiv"); - glVertexAttrib4usv_ = (PFNGLVERTEXATTRIB4USVPROC) getprocaddress("glVertexAttrib4usv"); - glVertexAttrib4Nbv_ = (PFNGLVERTEXATTRIB4NBVPROC) getprocaddress("glVertexAttrib4Nbv"); - glVertexAttrib4Niv_ = (PFNGLVERTEXATTRIB4NIVPROC) getprocaddress("glVertexAttrib4Niv"); - glVertexAttrib4Nub_ = (PFNGLVERTEXATTRIB4NUBPROC) getprocaddress("glVertexAttrib4Nub"); - glVertexAttrib4Nubv_ = (PFNGLVERTEXATTRIB4NUBVPROC) getprocaddress("glVertexAttrib4Nubv"); - glVertexAttrib4Nuiv_ = (PFNGLVERTEXATTRIB4NUIVPROC) getprocaddress("glVertexAttrib4Nuiv"); - glVertexAttrib4Nusv_ = (PFNGLVERTEXATTRIB4NUSVPROC) getprocaddress("glVertexAttrib4Nusv"); - glVertexAttribPointer_ = (PFNGLVERTEXATTRIBPOINTERPROC) getprocaddress("glVertexAttribPointer"); - - glDrawBuffers_ = (PFNGLDRAWBUFFERSPROC) getprocaddress("glDrawBuffers"); - - if(glversion >= 300) - { - glGetStringi_ = (PFNGLGETSTRINGIPROC) getprocaddress("glGetStringi"); - glBindFragDataLocation_ = (PFNGLBINDFRAGDATALOCATIONPROC)getprocaddress("glBindFragDataLocation"); - } - - const char *glslstr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); - uint glslmajorversion, glslminorversion; - if(glslstr && sscanf(glslstr, " %u.%u", &glslmajorversion, &glslminorversion) == 2) glslversion = glslmajorversion*100 + glslminorversion; - - if(glslversion < 120) fatal("GLSL 1.20 or greater is required!"); - - parseglexts(); - - GLint val; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val); - hwtexsize = val; - glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &val); - hwcubetexsize = val; - - if(glversion >= 300 || hasext("GL_ARB_texture_float") || hasext("GL_ATI_texture_float")) - { - hasTF = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_texture_float extension."); - shadowmap = 1; - extern int smoothshadowmappeel; - smoothshadowmappeel = 1; - } - - if(glversion >= 300 || hasext("GL_ARB_texture_rg")) - { - hasTRG = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_texture_rg extension."); - } - - if(glversion >= 300 || hasext("GL_ARB_framebuffer_object")) - { - glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbuffer"); - glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffers"); - glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffers"); - glRenderbufferStorage_ = (PFNGLRENDERBUFFERSTORAGEPROC) getprocaddress("glRenderbufferStorage"); - glCheckFramebufferStatus_ = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) getprocaddress("glCheckFramebufferStatus"); - glBindFramebuffer_ = (PFNGLBINDFRAMEBUFFERPROC) getprocaddress("glBindFramebuffer"); - glDeleteFramebuffers_ = (PFNGLDELETEFRAMEBUFFERSPROC) getprocaddress("glDeleteFramebuffers"); - glGenFramebuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenFramebuffers"); - glFramebufferTexture2D_ = (PFNGLFRAMEBUFFERTEXTURE2DPROC) getprocaddress("glFramebufferTexture2D"); - glFramebufferRenderbuffer_ = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)getprocaddress("glFramebufferRenderbuffer"); - glGenerateMipmap_ = (PFNGLGENERATEMIPMAPPROC) getprocaddress("glGenerateMipmap"); - glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebuffer"); - hasAFBO = hasFBO = hasFBB = hasDS = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_framebuffer_object extension."); - } - else if(hasext("GL_EXT_framebuffer_object")) - { - glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbufferEXT"); - glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffersEXT"); - glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffersEXT"); - glRenderbufferStorage_ = (PFNGLRENDERBUFFERSTORAGEPROC) getprocaddress("glRenderbufferStorageEXT"); - glCheckFramebufferStatus_ = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) getprocaddress("glCheckFramebufferStatusEXT"); - glBindFramebuffer_ = (PFNGLBINDFRAMEBUFFERPROC) getprocaddress("glBindFramebufferEXT"); - glDeleteFramebuffers_ = (PFNGLDELETEFRAMEBUFFERSPROC) getprocaddress("glDeleteFramebuffersEXT"); - glGenFramebuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenFramebuffersEXT"); - glFramebufferTexture2D_ = (PFNGLFRAMEBUFFERTEXTURE2DPROC) getprocaddress("glFramebufferTexture2DEXT"); - glFramebufferRenderbuffer_ = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)getprocaddress("glFramebufferRenderbufferEXT"); - glGenerateMipmap_ = (PFNGLGENERATEMIPMAPPROC) getprocaddress("glGenerateMipmapEXT"); - hasFBO = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_framebuffer_object extension."); - - if(hasext("GL_EXT_framebuffer_blit")) - { - glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebufferEXT"); - hasFBB = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_framebuffer_blit extension."); - } - - if(hasext("GL_EXT_packed_depth_stencil") || hasext("GL_NV_packed_depth_stencil")) - { - hasDS = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_packed_depth_stencil extension."); - } - } - else fatal("Framebuffer object support is required!"); - - extern int fpdepthfx; - if(ati) - { - //conoutf(CON_WARN, "WARNING: ATI cards may show garbage in skybox. (use \"/ati_skybox_bug 1\" to fix)"); - - minimizetcusage = 1; - if(hasTF && hasTRG) fpdepthfx = 1; - // On Catalyst 10.2, issuing an occlusion query on the first draw using a given cubemap texture causes a nasty crash - ati_cubemap_bug = 1; - } - else if(nvidia) - { - reservevpparams = 10; - rtsharefb = 0; // work-around for strange driver stalls involving when using many FBOs - extern int filltjoints; - if(glversion < 300 && !hasext("GL_EXT_gpu_shader4")) filltjoints = 0; // DX9 or less NV cards seem to not cause many sparklies - - if(hasTF && hasTRG) fpdepthfx = 1; - } - else - { - reservevpparams = 20; - - if(mesa) mesa_swap_bug = 1; - } - - if(glversion >= 300 || hasext("GL_ARB_map_buffer_range")) - { - glMapBufferRange_ = (PFNGLMAPBUFFERRANGEPROC) getprocaddress("glMapBufferRange"); - glFlushMappedBufferRange_ = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)getprocaddress("glFlushMappedBufferRange"); - hasMBR = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_map_buffer_range."); - } - - if(glversion >= 310 || hasext("GL_ARB_uniform_buffer_object")) - { - glGetUniformIndices_ = (PFNGLGETUNIFORMINDICESPROC) getprocaddress("glGetUniformIndices"); - glGetActiveUniformsiv_ = (PFNGLGETACTIVEUNIFORMSIVPROC) getprocaddress("glGetActiveUniformsiv"); - glGetUniformBlockIndex_ = (PFNGLGETUNIFORMBLOCKINDEXPROC) getprocaddress("glGetUniformBlockIndex"); - glGetActiveUniformBlockiv_ = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)getprocaddress("glGetActiveUniformBlockiv"); - glUniformBlockBinding_ = (PFNGLUNIFORMBLOCKBINDINGPROC) getprocaddress("glUniformBlockBinding"); - glBindBufferBase_ = (PFNGLBINDBUFFERBASEPROC) getprocaddress("glBindBufferBase"); - glBindBufferRange_ = (PFNGLBINDBUFFERRANGEPROC) getprocaddress("glBindBufferRange"); - - useubo = 1; - hasUBO = true; - if(glversion < 310 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_uniform_buffer_object extension."); - } - - if(glversion >= 300 || hasext("GL_ARB_vertex_array_object")) - { - glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArray"); - glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArrays"); - glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArrays"); - glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArray"); - hasVAO = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_vertex_array_object extension."); - } - else if(hasext("GL_APPLE_vertex_array_object")) - { - glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArrayAPPLE"); - glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArraysAPPLE"); - glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArraysAPPLE"); - glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArrayAPPLE"); - hasVAO = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_APPLE_vertex_array_object extension."); - } - - if(glversion >= 330 || hasext("GL_ARB_texture_swizzle") || hasext("GL_EXT_texture_swizzle")) - { - hasTSW = true; - if(glversion < 330 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_texture_swizzle extension."); - } - - if(hasext("GL_EXT_texture_compression_s3tc")) - { - hasS3TC = true; -#ifdef __APPLE__ - usetexcompress = 1; -#else - if(!mesa) usetexcompress = 2; -#endif - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_texture_compression_s3tc extension."); - } - else if(hasext("GL_EXT_texture_compression_dxt1") && hasext("GL_ANGLE_texture_compression_dxt3") && hasext("GL_ANGLE_texture_compression_dxt5")) - { - hasS3TC = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_texture_compression_dxt1 extension."); - } - if(hasext("GL_3DFX_texture_compression_FXT1")) - { - hasFXT1 = true; - if(mesa) usetexcompress = max(usetexcompress, 1); - if(dbgexts) conoutf(CON_INIT, "Using GL_3DFX_texture_compression_FXT1."); - } - if(hasext("GL_EXT_texture_compression_latc")) - { - hasLATC = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_texture_compression_latc extension."); - } - if(glversion >= 300 || hasext("GL_ARB_texture_compression_rgtc") || hasext("GL_EXT_texture_compression_rgtc")) - { - hasRGTC = true; - if(glversion < 300 && dbgexts) conoutf(CON_INIT, "Using GL_ARB_texture_compression_rgtc extension."); - } - - if(hasext("GL_EXT_texture_filter_anisotropic")) - { - GLint val; - glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &val); - hwmaxaniso = val; - hasAF = true; - if(dbgexts) conoutf(CON_INIT, "Using GL_EXT_texture_filter_anisotropic extension."); - } - - if(glversion >= 300 || hasext("GL_EXT_gpu_shader4")) - { - // on DX10 or above class cards (i.e. GF8 or RadeonHD) enable expensive features - extern int glare, maxdynlights, depthfxsize, blurdepthfx, texcompress; - waterfallrefract = 1; - glare = 1; - maxdynlights = MAXDYNLIGHTS; - depthfxsize = 10; - blurdepthfx = 0; - texcompress = max(texcompress, 1024 + 1); - } + const char *vendor = (const char *)glGetString(GL_VENDOR); + const char *renderer = (const char *)glGetString(GL_RENDERER); + const char *version = (const char *)glGetString(GL_VERSION); + conoutf(CON_INIT, "Renderer: %s (%s)", renderer, vendor); + conoutf(CON_INIT, "Driver: %s", version); + + bool mesa = false, intel = false, ati = false, nvidia = false; + if(strstr(renderer, "Mesa") || strstr(version, "Mesa")) + { + mesa = true; + if(strstr(renderer, "Intel")) intel = true; + } + else if(strstr(vendor, "NVIDIA")) + nvidia = true; + else if(strstr(vendor, "ATI") || strstr(vendor, "Advanced Micro Devices")) + ati = true; + else if(strstr(vendor, "Intel")) + intel = true; + + uint glmajorversion, glminorversion; + if(sscanf(version, " %u.%u", &glmajorversion, &glminorversion) != 2) glversion = 100; + else glversion = glmajorversion*100 + glminorversion*10; + + if(glversion < 200) fatal("OpenGL 2.0 or greater is required!"); + + glMultiDrawArrays_ = (PFNGLMULTIDRAWARRAYSPROC) getprocaddress("glMultiDrawArrays"); + glMultiDrawElements_ = (PFNGLMULTIDRAWELEMENTSPROC) getprocaddress("glMultiDrawElements"); + + glBlendFuncSeparate_ = (PFNGLBLENDFUNCSEPARATEPROC) getprocaddress("glBlendFuncSeparate"); + glBlendEquationSeparate_ = (PFNGLBLENDEQUATIONSEPARATEPROC) getprocaddress("glBlendEquationSeparate"); + glStencilOpSeparate_ = (PFNGLSTENCILOPSEPARATEPROC) getprocaddress("glStencilOpSeparate"); + glStencilFuncSeparate_ = (PFNGLSTENCILFUNCSEPARATEPROC) getprocaddress("glStencilFuncSeparate"); + glStencilMaskSeparate_ = (PFNGLSTENCILMASKSEPARATEPROC) getprocaddress("glStencilMaskSeparate"); + + glGenBuffers_ = (PFNGLGENBUFFERSPROC) getprocaddress("glGenBuffers"); + glBindBuffer_ = (PFNGLBINDBUFFERPROC) getprocaddress("glBindBuffer"); + glMapBuffer_ = (PFNGLMAPBUFFERPROC) getprocaddress("glMapBuffer"); + glUnmapBuffer_ = (PFNGLUNMAPBUFFERPROC) getprocaddress("glUnmapBuffer"); + glBufferData_ = (PFNGLBUFFERDATAPROC) getprocaddress("glBufferData"); + glBufferSubData_ = (PFNGLBUFFERSUBDATAPROC) getprocaddress("glBufferSubData"); + glDeleteBuffers_ = (PFNGLDELETEBUFFERSPROC) getprocaddress("glDeleteBuffers"); + glGetBufferSubData_ = (PFNGLGETBUFFERSUBDATAPROC) getprocaddress("glGetBufferSubData"); + + glGetQueryiv_ = (PFNGLGETQUERYIVPROC) getprocaddress("glGetQueryiv"); + glGenQueries_ = (PFNGLGENQUERIESPROC) getprocaddress("glGenQueries"); + glDeleteQueries_ = (PFNGLDELETEQUERIESPROC) getprocaddress("glDeleteQueries"); + glBeginQuery_ = (PFNGLBEGINQUERYPROC) getprocaddress("glBeginQuery"); + glEndQuery_ = (PFNGLENDQUERYPROC) getprocaddress("glEndQuery"); + glGetQueryObjectiv_ = (PFNGLGETQUERYOBJECTIVPROC) getprocaddress("glGetQueryObjectiv"); + glGetQueryObjectuiv_ = (PFNGLGETQUERYOBJECTUIVPROC) getprocaddress("glGetQueryObjectuiv"); + + glCreateProgram_ = (PFNGLCREATEPROGRAMPROC) getprocaddress("glCreateProgram"); + glDeleteProgram_ = (PFNGLDELETEPROGRAMPROC) getprocaddress("glDeleteProgram"); + glUseProgram_ = (PFNGLUSEPROGRAMPROC) getprocaddress("glUseProgram"); + glCreateShader_ = (PFNGLCREATESHADERPROC) getprocaddress("glCreateShader"); + glDeleteShader_ = (PFNGLDELETESHADERPROC) getprocaddress("glDeleteShader"); + glShaderSource_ = (PFNGLSHADERSOURCEPROC) getprocaddress("glShaderSource"); + glCompileShader_ = (PFNGLCOMPILESHADERPROC) getprocaddress("glCompileShader"); + glGetShaderiv_ = (PFNGLGETSHADERIVPROC) getprocaddress("glGetShaderiv"); + glGetProgramiv_ = (PFNGLGETPROGRAMIVPROC) getprocaddress("glGetProgramiv"); + glAttachShader_ = (PFNGLATTACHSHADERPROC) getprocaddress("glAttachShader"); + glGetProgramInfoLog_ = (PFNGLGETPROGRAMINFOLOGPROC) getprocaddress("glGetProgramInfoLog"); + glGetShaderInfoLog_ = (PFNGLGETSHADERINFOLOGPROC) getprocaddress("glGetShaderInfoLog"); + glLinkProgram_ = (PFNGLLINKPROGRAMPROC) getprocaddress("glLinkProgram"); + glGetUniformLocation_ = (PFNGLGETUNIFORMLOCATIONPROC) getprocaddress("glGetUniformLocation"); + glUniform1f_ = (PFNGLUNIFORM1FPROC) getprocaddress("glUniform1f"); + glUniform2f_ = (PFNGLUNIFORM2FPROC) getprocaddress("glUniform2f"); + glUniform3f_ = (PFNGLUNIFORM3FPROC) getprocaddress("glUniform3f"); + glUniform4f_ = (PFNGLUNIFORM4FPROC) getprocaddress("glUniform4f"); + glUniform1fv_ = (PFNGLUNIFORM1FVPROC) getprocaddress("glUniform1fv"); + glUniform2fv_ = (PFNGLUNIFORM2FVPROC) getprocaddress("glUniform2fv"); + glUniform3fv_ = (PFNGLUNIFORM3FVPROC) getprocaddress("glUniform3fv"); + glUniform4fv_ = (PFNGLUNIFORM4FVPROC) getprocaddress("glUniform4fv"); + glUniform1i_ = (PFNGLUNIFORM1IPROC) getprocaddress("glUniform1i"); + glUniform2i_ = (PFNGLUNIFORM2IPROC) getprocaddress("glUniform2i"); + glUniform3i_ = (PFNGLUNIFORM3IPROC) getprocaddress("glUniform3i"); + glUniform4i_ = (PFNGLUNIFORM4IPROC) getprocaddress("glUniform4i"); + glUniform1iv_ = (PFNGLUNIFORM1IVPROC) getprocaddress("glUniform1iv"); + glUniform2iv_ = (PFNGLUNIFORM2IVPROC) getprocaddress("glUniform2iv"); + glUniform3iv_ = (PFNGLUNIFORM3IVPROC) getprocaddress("glUniform3iv"); + glUniform4iv_ = (PFNGLUNIFORM4IVPROC) getprocaddress("glUniform4iv"); + glUniformMatrix2fv_ = (PFNGLUNIFORMMATRIX2FVPROC) getprocaddress("glUniformMatrix2fv"); + glUniformMatrix3fv_ = (PFNGLUNIFORMMATRIX3FVPROC) getprocaddress("glUniformMatrix3fv"); + glUniformMatrix4fv_ = (PFNGLUNIFORMMATRIX4FVPROC) getprocaddress("glUniformMatrix4fv"); + glBindAttribLocation_ = (PFNGLBINDATTRIBLOCATIONPROC) getprocaddress("glBindAttribLocation"); + glGetActiveUniform_ = (PFNGLGETACTIVEUNIFORMPROC) getprocaddress("glGetActiveUniform"); + glEnableVertexAttribArray_ = (PFNGLENABLEVERTEXATTRIBARRAYPROC) getprocaddress("glEnableVertexAttribArray"); + glDisableVertexAttribArray_ = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) getprocaddress("glDisableVertexAttribArray"); + + glVertexAttrib1f_ = (PFNGLVERTEXATTRIB1FPROC) getprocaddress("glVertexAttrib1f"); + glVertexAttrib1fv_ = (PFNGLVERTEXATTRIB1FVPROC) getprocaddress("glVertexAttrib1fv"); + glVertexAttrib1s_ = (PFNGLVERTEXATTRIB1SPROC) getprocaddress("glVertexAttrib1s"); + glVertexAttrib1sv_ = (PFNGLVERTEXATTRIB1SVPROC) getprocaddress("glVertexAttrib1sv"); + glVertexAttrib2f_ = (PFNGLVERTEXATTRIB2FPROC) getprocaddress("glVertexAttrib2f"); + glVertexAttrib2fv_ = (PFNGLVERTEXATTRIB2FVPROC) getprocaddress("glVertexAttrib2fv"); + glVertexAttrib2s_ = (PFNGLVERTEXATTRIB2SPROC) getprocaddress("glVertexAttrib2s"); + glVertexAttrib2sv_ = (PFNGLVERTEXATTRIB2SVPROC) getprocaddress("glVertexAttrib2sv"); + glVertexAttrib3f_ = (PFNGLVERTEXATTRIB3FPROC) getprocaddress("glVertexAttrib3f"); + glVertexAttrib3fv_ = (PFNGLVERTEXATTRIB3FVPROC) getprocaddress("glVertexAttrib3fv"); + glVertexAttrib3s_ = (PFNGLVERTEXATTRIB3SPROC) getprocaddress("glVertexAttrib3s"); + glVertexAttrib3sv_ = (PFNGLVERTEXATTRIB3SVPROC) getprocaddress("glVertexAttrib3sv"); + glVertexAttrib4f_ = (PFNGLVERTEXATTRIB4FPROC) getprocaddress("glVertexAttrib4f"); + glVertexAttrib4fv_ = (PFNGLVERTEXATTRIB4FVPROC) getprocaddress("glVertexAttrib4fv"); + glVertexAttrib4s_ = (PFNGLVERTEXATTRIB4SPROC) getprocaddress("glVertexAttrib4s"); + glVertexAttrib4sv_ = (PFNGLVERTEXATTRIB4SVPROC) getprocaddress("glVertexAttrib4sv"); + glVertexAttrib4bv_ = (PFNGLVERTEXATTRIB4BVPROC) getprocaddress("glVertexAttrib4bv"); + glVertexAttrib4iv_ = (PFNGLVERTEXATTRIB4IVPROC) getprocaddress("glVertexAttrib4iv"); + glVertexAttrib4ubv_ = (PFNGLVERTEXATTRIB4UBVPROC) getprocaddress("glVertexAttrib4ubv"); + glVertexAttrib4uiv_ = (PFNGLVERTEXATTRIB4UIVPROC) getprocaddress("glVertexAttrib4uiv"); + glVertexAttrib4usv_ = (PFNGLVERTEXATTRIB4USVPROC) getprocaddress("glVertexAttrib4usv"); + glVertexAttrib4Nbv_ = (PFNGLVERTEXATTRIB4NBVPROC) getprocaddress("glVertexAttrib4Nbv"); + glVertexAttrib4Niv_ = (PFNGLVERTEXATTRIB4NIVPROC) getprocaddress("glVertexAttrib4Niv"); + glVertexAttrib4Nub_ = (PFNGLVERTEXATTRIB4NUBPROC) getprocaddress("glVertexAttrib4Nub"); + glVertexAttrib4Nubv_ = (PFNGLVERTEXATTRIB4NUBVPROC) getprocaddress("glVertexAttrib4Nubv"); + glVertexAttrib4Nuiv_ = (PFNGLVERTEXATTRIB4NUIVPROC) getprocaddress("glVertexAttrib4Nuiv"); + glVertexAttrib4Nusv_ = (PFNGLVERTEXATTRIB4NUSVPROC) getprocaddress("glVertexAttrib4Nusv"); + glVertexAttribPointer_ = (PFNGLVERTEXATTRIBPOINTERPROC) getprocaddress("glVertexAttribPointer"); + + glDrawBuffers_ = (PFNGLDRAWBUFFERSPROC) getprocaddress("glDrawBuffers"); + + if(glversion >= 300) + { + glGetStringi_ = (PFNGLGETSTRINGIPROC) getprocaddress("glGetStringi"); + glBindFragDataLocation_ = (PFNGLBINDFRAGDATALOCATIONPROC)getprocaddress("glBindFragDataLocation"); + } + + const char *glslstr = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + uint glslmajorversion, glslminorversion; + if(glslstr && sscanf(glslstr, " %u.%u", &glslmajorversion, &glslminorversion) == 2) glslversion = glslmajorversion*100 + glslminorversion; + + if(glslversion < 120) fatal("GLSL 1.20 or greater is required!"); + + parseglexts(); + + GLint val; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val); + hwtexsize = val; + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &val); + hwcubetexsize = val; + + if(glversion >= 300 || hasext("GL_ARB_texture_float") || hasext("GL_ATI_texture_float")) + { + hasTF = true; + shadowmap = 1; + extern int smoothshadowmappeel; + smoothshadowmappeel = 1; + } + + if(glversion >= 300 || hasext("GL_ARB_texture_rg")) + { + hasTRG = true; + } + + if(glversion >= 300 || hasext("GL_ARB_framebuffer_object")) + { + glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbuffer"); + glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffers"); + glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffers"); + glRenderbufferStorage_ = (PFNGLRENDERBUFFERSTORAGEPROC) getprocaddress("glRenderbufferStorage"); + glCheckFramebufferStatus_ = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) getprocaddress("glCheckFramebufferStatus"); + glBindFramebuffer_ = (PFNGLBINDFRAMEBUFFERPROC) getprocaddress("glBindFramebuffer"); + glDeleteFramebuffers_ = (PFNGLDELETEFRAMEBUFFERSPROC) getprocaddress("glDeleteFramebuffers"); + glGenFramebuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenFramebuffers"); + glFramebufferTexture2D_ = (PFNGLFRAMEBUFFERTEXTURE2DPROC) getprocaddress("glFramebufferTexture2D"); + glFramebufferRenderbuffer_ = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)getprocaddress("glFramebufferRenderbuffer"); + glGenerateMipmap_ = (PFNGLGENERATEMIPMAPPROC) getprocaddress("glGenerateMipmap"); + glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebuffer"); + hasAFBO = hasFBO = hasFBB = hasDS = true; + } + else if(hasext("GL_EXT_framebuffer_object")) + { + glBindRenderbuffer_ = (PFNGLBINDRENDERBUFFERPROC) getprocaddress("glBindRenderbufferEXT"); + glDeleteRenderbuffers_ = (PFNGLDELETERENDERBUFFERSPROC) getprocaddress("glDeleteRenderbuffersEXT"); + glGenRenderbuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenRenderbuffersEXT"); + glRenderbufferStorage_ = (PFNGLRENDERBUFFERSTORAGEPROC) getprocaddress("glRenderbufferStorageEXT"); + glCheckFramebufferStatus_ = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) getprocaddress("glCheckFramebufferStatusEXT"); + glBindFramebuffer_ = (PFNGLBINDFRAMEBUFFERPROC) getprocaddress("glBindFramebufferEXT"); + glDeleteFramebuffers_ = (PFNGLDELETEFRAMEBUFFERSPROC) getprocaddress("glDeleteFramebuffersEXT"); + glGenFramebuffers_ = (PFNGLGENFRAMEBUFFERSPROC) getprocaddress("glGenFramebuffersEXT"); + glFramebufferTexture2D_ = (PFNGLFRAMEBUFFERTEXTURE2DPROC) getprocaddress("glFramebufferTexture2DEXT"); + glFramebufferRenderbuffer_ = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)getprocaddress("glFramebufferRenderbufferEXT"); + glGenerateMipmap_ = (PFNGLGENERATEMIPMAPPROC) getprocaddress("glGenerateMipmapEXT"); + hasFBO = true; + + if(hasext("GL_EXT_framebuffer_blit")) + { + glBlitFramebuffer_ = (PFNGLBLITFRAMEBUFFERPROC) getprocaddress("glBlitFramebufferEXT"); + hasFBB = true; + } + + if(hasext("GL_EXT_packed_depth_stencil") || hasext("GL_NV_packed_depth_stencil")) + { + hasDS = true; + } + } + else fatal("Framebuffer object support is required!"); + + extern int fpdepthfx; + if(ati) + { + //conoutf(CON_WARN, "WARNING: ATI cards may show garbage in skybox. (use \"/ati_skybox_bug 1\" to fix)"); + + minimizetcusage = 1; + if(hasTF && hasTRG) fpdepthfx = 1; + // On Catalyst 10.2, issuing an occlusion query on the first draw using a given cubemap texture causes a nasty crash + ati_cubemap_bug = 1; + } + else if(nvidia) + { + reservevpparams = 10; + rtsharefb = 0; // work-around for strange driver stalls involving when using many FBOs + extern int filltjoints; + if(glversion < 300 && !hasext("GL_EXT_gpu_shader4")) filltjoints = 0; // DX9 or less NV cards seem to not cause many sparklies + + if(hasTF && hasTRG) fpdepthfx = 1; + } + else + { + reservevpparams = 20; + + if(mesa) mesa_swap_bug = 1; + } + + if(glversion >= 300 || hasext("GL_ARB_map_buffer_range")) + { + glMapBufferRange_ = (PFNGLMAPBUFFERRANGEPROC) getprocaddress("glMapBufferRange"); + glFlushMappedBufferRange_ = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)getprocaddress("glFlushMappedBufferRange"); + hasMBR = true; + } + + if(glversion >= 310 || hasext("GL_ARB_uniform_buffer_object")) + { + glGetUniformIndices_ = (PFNGLGETUNIFORMINDICESPROC) getprocaddress("glGetUniformIndices"); + glGetActiveUniformsiv_ = (PFNGLGETACTIVEUNIFORMSIVPROC) getprocaddress("glGetActiveUniformsiv"); + glGetUniformBlockIndex_ = (PFNGLGETUNIFORMBLOCKINDEXPROC) getprocaddress("glGetUniformBlockIndex"); + glGetActiveUniformBlockiv_ = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)getprocaddress("glGetActiveUniformBlockiv"); + glUniformBlockBinding_ = (PFNGLUNIFORMBLOCKBINDINGPROC) getprocaddress("glUniformBlockBinding"); + glBindBufferBase_ = (PFNGLBINDBUFFERBASEPROC) getprocaddress("glBindBufferBase"); + glBindBufferRange_ = (PFNGLBINDBUFFERRANGEPROC) getprocaddress("glBindBufferRange"); + + useubo = 1; + hasUBO = true; + } + + if(glversion >= 300 || hasext("GL_ARB_vertex_array_object")) + { + glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArray"); + glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArrays"); + glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArrays"); + glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArray"); + hasVAO = true; + } + else if(hasext("GL_APPLE_vertex_array_object")) + { + glBindVertexArray_ = (PFNGLBINDVERTEXARRAYPROC) getprocaddress("glBindVertexArrayAPPLE"); + glDeleteVertexArrays_ = (PFNGLDELETEVERTEXARRAYSPROC)getprocaddress("glDeleteVertexArraysAPPLE"); + glGenVertexArrays_ = (PFNGLGENVERTEXARRAYSPROC) getprocaddress("glGenVertexArraysAPPLE"); + glIsVertexArray_ = (PFNGLISVERTEXARRAYPROC) getprocaddress("glIsVertexArrayAPPLE"); + hasVAO = true; + } + + if(glversion >= 330 || hasext("GL_ARB_texture_swizzle") || hasext("GL_EXT_texture_swizzle")) + { + hasTSW = true; + } + + if(hasext("GL_EXT_texture_compression_s3tc")) + { + hasS3TC = true; + if(!mesa) usetexcompress = 2; + } + else if(hasext("GL_EXT_texture_compression_dxt1") && hasext("GL_ANGLE_texture_compression_dxt3") && hasext("GL_ANGLE_texture_compression_dxt5")) + { + hasS3TC = true; + } + if(hasext("GL_3DFX_texture_compression_FXT1")) + { + hasFXT1 = true; + if(mesa) usetexcompress = max(usetexcompress, 1); + } + if(hasext("GL_EXT_texture_compression_latc")) + { + hasLATC = true; + } + if(glversion >= 300 || hasext("GL_ARB_texture_compression_rgtc") || hasext("GL_EXT_texture_compression_rgtc")) + { + hasRGTC = true; + } + + if(hasext("GL_EXT_texture_filter_anisotropic")) + { + GLint val; + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &val); + hwmaxaniso = val; + hasAF = true; + } + + if(glversion >= 300 || hasext("GL_EXT_gpu_shader4")) + { + // on DX10 or above class cards (i.e. GF8 or RadeonHD) enable expensive features + extern int glare, maxdynlights, depthfxsize, blurdepthfx, texcompress; + waterfallrefract = 1; + glare = 1; + maxdynlights = MAXDYNLIGHTS; + depthfxsize = 10; + blurdepthfx = 0; + texcompress = max(texcompress, 1024 + 1); + } } void glext(char *ext) { - intret(hasext(ext) ? 1 : 0); + intret(hasext(ext) ? 1 : 0); } COMMAND(glext, "s"); void gl_resize() { - glViewport(0, 0, screenw, screenh); + glViewport(0, 0, screenw, screenh); } void gl_init() { - glClearColor(0, 0, 0, 0); - glClearDepth(1); - glDepthFunc(GL_LESS); - glDisable(GL_DEPTH_TEST); + glClearColor(0, 0, 0, 0); + glClearDepth(1); + glDepthFunc(GL_LESS); + glDisable(GL_DEPTH_TEST); - glEnable(GL_LINE_SMOOTH); - //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glEnable(GL_LINE_SMOOTH); + //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glFrontFace(GL_CW); - glCullFace(GL_BACK); - glDisable(GL_CULL_FACE); + glFrontFace(GL_CW); + glCullFace(GL_BACK); + glDisable(GL_CULL_FACE); - gle::setup(); + gle::setup(); - setupshaders(); + setupshaders(); - setuptexcompress(); + setuptexcompress(); - gl_resize(); + gl_resize(); } VAR(wireframe, 0, 0, 1); @@ -570,64 +547,64 @@ ICOMMAND(getcampitch, "", (), floatret(camera1->pitch)); ICOMMAND(getcamroll, "", (), floatret(camera1->roll)); ICOMMAND(getcampos, "", (), { - defformatstring(pos, "%s %s %s", floatstr(camera1->o.x), floatstr(camera1->o.y), floatstr(camera1->o.z)); - result(pos); + defformatstring(pos, "%s %s %s", floatstr(camera1->o.x), floatstr(camera1->o.y), floatstr(camera1->o.z)); + result(pos); }); vec worldpos, camdir, camright, camup; void setcammatrix() { - // move from RH to Z-up LH quake style worldspace - cammatrix = viewmatrix; - cammatrix.rotate_around_y(camera1->roll*RAD); - cammatrix.rotate_around_x(camera1->pitch*-RAD); - cammatrix.rotate_around_z(camera1->yaw*-RAD); - cammatrix.translate(vec(camera1->o).neg()); + // move from RH to Z-up LH quake style worldspace + cammatrix = viewmatrix; + cammatrix.rotate_around_y(camera1->roll*RAD); + cammatrix.rotate_around_x(camera1->pitch*-RAD); + cammatrix.rotate_around_z(camera1->yaw*-RAD); + cammatrix.translate(vec(camera1->o).neg()); - cammatrix.transposedtransformnormal(vec(viewmatrix.b), camdir); - cammatrix.transposedtransformnormal(vec(viewmatrix.a).neg(), camright); - cammatrix.transposedtransformnormal(vec(viewmatrix.c), camup); + cammatrix.transposedtransformnormal(vec(viewmatrix.b), camdir); + cammatrix.transposedtransformnormal(vec(viewmatrix.a).neg(), camright); + cammatrix.transposedtransformnormal(vec(viewmatrix.c), camup); - if(!drawtex) - { - if(raycubepos(camera1->o, camdir, worldpos, 0, RAY_CLIPMAT|RAY_SKIPFIRST) == -1) - worldpos = vec(camdir).mul(2*worldsize).add(camera1->o); // if nothing is hit, just far away in the view direction - } + if(!drawtex) + { + if(raycubepos(camera1->o, camdir, worldpos, 0, RAY_CLIPMAT|RAY_SKIPFIRST) == -1) + worldpos = vec(camdir).mul(2*worldsize).add(camera1->o); // if nothing is hit, just far away in the view direction + } } void setcamprojmatrix(bool init = true, bool flush = false) { - if(init) - { - setcammatrix(); - } + if(init) + { + setcammatrix(); + } - camprojmatrix.muld(projmatrix, cammatrix); + camprojmatrix.muld(projmatrix, cammatrix); - if(init) - { - invcammatrix.invert(cammatrix); - invcamprojmatrix.invert(camprojmatrix); - } + if(init) + { + invcammatrix.invert(cammatrix); + invcamprojmatrix.invert(camprojmatrix); + } - GLOBALPARAM(camprojmatrix, camprojmatrix); + GLOBALPARAM(camprojmatrix, camprojmatrix); - if(fogging) - { - vec fogplane(cammatrix.c); - fogplane.x /= projmatrix.a.x; - fogplane.y /= projmatrix.b.y; - fogplane.z /= projmatrix.c.w; - GLOBALPARAMF(fogplane, fogplane.x, fogplane.y, 0, fogplane.z); - } - else - { - vec2 lineardepthscale = projmatrix.lineardepthscale(); - GLOBALPARAMF(fogplane, 0, 0, lineardepthscale.x, lineardepthscale.y); - } + if(fogging) + { + vec fogplane(cammatrix.c); + fogplane.x /= projmatrix.a.x; + fogplane.y /= projmatrix.b.y; + fogplane.z /= projmatrix.c.w; + GLOBALPARAMF(fogplane, fogplane.x, fogplane.y, 0, fogplane.z); + } + else + { + vec2 lineardepthscale = projmatrix.lineardepthscale(); + GLOBALPARAMF(fogplane, 0, 0, lineardepthscale.x, lineardepthscale.y); + } - if(flush && Shader::lastshader) Shader::lastshader->flushparams(); + if(flush && Shader::lastshader) Shader::lastshader->flushparams(); } matrix4 hudmatrix, hudmatrixstack[64]; @@ -635,47 +612,47 @@ int hudmatrixpos = 0; void resethudmatrix() { - hudmatrixpos = 0; - GLOBALPARAM(hudmatrix, hudmatrix); + hudmatrixpos = 0; + GLOBALPARAM(hudmatrix, hudmatrix); } void pushhudmatrix() { - if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) hudmatrixstack[hudmatrixpos] = hudmatrix; - ++hudmatrixpos; + if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) hudmatrixstack[hudmatrixpos] = hudmatrix; + ++hudmatrixpos; } void flushhudmatrix(bool flushparams) { - GLOBALPARAM(hudmatrix, hudmatrix); - if(flushparams && Shader::lastshader) Shader::lastshader->flushparams(); + GLOBALPARAM(hudmatrix, hudmatrix); + if(flushparams && Shader::lastshader) Shader::lastshader->flushparams(); } void pophudmatrix(bool flush, bool flushparams) { - --hudmatrixpos; - if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) - { - hudmatrix = hudmatrixstack[hudmatrixpos]; - if(flush) flushhudmatrix(flushparams); - } + --hudmatrixpos; + if(hudmatrixpos >= 0 && hudmatrixpos < int(sizeof(hudmatrixstack)/sizeof(hudmatrixstack[0]))) + { + hudmatrix = hudmatrixstack[hudmatrixpos]; + if(flush) flushhudmatrix(flushparams); + } } void pushhudscale(float sx, float sy) { - if(!sy) sy = sx; - pushhudmatrix(); - hudmatrix.scale(sx, sy, 1); - flushhudmatrix(); + if(!sy) sy = sx; + pushhudmatrix(); + hudmatrix.scale(sx, sy, 1); + flushhudmatrix(); } void pushhudtranslate(float tx, float ty, float sx, float sy) { - if(!sy) sy = sx; - pushhudmatrix(); - hudmatrix.translate(tx, ty, 0); - if(sy) hudmatrix.scale(sx, sy, 1); - flushhudmatrix(); + if(!sy) sy = sx; + pushhudmatrix(); + hudmatrix.translate(tx, ty, 0); + if(sy) hudmatrix.scale(sx, sy, 1); + flushhudmatrix(); } float curfov = 100, curavatarfov = 65, fovy, aspect; @@ -694,21 +671,21 @@ VAR(zoom, -1, 0, 1); void disablezoom() { - zoom = 0; - zoomprogress = 0; + zoom = 0; + zoomprogress = 0; } void computezoom() { - if(!zoom) { zoomprogress = 0; curfov = fov; curavatarfov = avatarfov; return; } - if(zoom > 0) zoomprogress = zoominvel ? min(zoomprogress + float(elapsedtime) / zoominvel, 1.0f) : 1; - else - { - zoomprogress = zoomoutvel ? max(zoomprogress - float(elapsedtime) / zoomoutvel, 0.0f) : 0; - if(zoomprogress <= 0) zoom = 0; - } - curfov = zoomfov*zoomprogress + fov*(1 - zoomprogress); - curavatarfov = avatarzoomfov*zoomprogress + avatarfov*(1 - zoomprogress); + if(!zoom) { zoomprogress = 0; curfov = fov; curavatarfov = avatarfov; return; } + if(zoom > 0) zoomprogress = zoominvel ? min(zoomprogress + float(elapsedtime) / zoominvel, 1.0f) : 1; + else + { + zoomprogress = zoomoutvel ? max(zoomprogress - float(elapsedtime) / zoomoutvel, 0.0f) : 0; + if(zoomprogress <= 0) zoom = 0; + } + curfov = zoomfov*zoomprogress + fov*(1 - zoomprogress); + curavatarfov = avatarzoomfov*zoomprogress + avatarfov*(1 - zoomprogress); } FVARP(zoomsens, 1e-3f, 1, 1000); @@ -729,105 +706,105 @@ bool isthirdperson() { return player!=camera1 || detachedcamera || reflecting; } void fixcamerarange() { - const float MAXPITCH = 90.0f; - if(camera1->pitch>MAXPITCH) camera1->pitch = MAXPITCH; - if(camera1->pitch<-MAXPITCH) camera1->pitch = -MAXPITCH; - while(camera1->yaw<0.0f) camera1->yaw += 360.0f; - while(camera1->yaw>=360.0f) camera1->yaw -= 360.0f; + const float MAXPITCH = 90.0f; + if(camera1->pitch>MAXPITCH) camera1->pitch = MAXPITCH; + if(camera1->pitch<-MAXPITCH) camera1->pitch = -MAXPITCH; + while(camera1->yaw<0.0f) camera1->yaw += 360.0f; + while(camera1->yaw>=360.0f) camera1->yaw -= 360.0f; } void mousemove(int dx, int dy) { - if(!game::allowmouselook()) return; - float cursens = sensitivity, curaccel = mouseaccel; - if(zoom) - { - if(zoomautosens) - { - cursens = float(sensitivity*zoomfov)/fov; - curaccel = float(mouseaccel*zoomfov)/fov; - } - else - { - cursens = zoomsens; - curaccel = zoomaccel; - } - } - if(curaccel && curtime && (dx || dy)) cursens += curaccel * sqrtf(dx*dx + dy*dy)/curtime; - cursens /= 33.0f*sensitivityscale; - camera1->yaw += dx*cursens; - camera1->pitch -= dy*cursens*(invmouse ? -1 : 1); - fixcamerarange(); - if(camera1!=player && !detachedcamera) - { - player->yaw = camera1->yaw; - player->pitch = camera1->pitch; - } - speedmodifier += abs(dx)-abs(dy); + if(!game::allowmouselook()) return; + float cursens = sensitivity, curaccel = mouseaccel; + if(zoom) + { + if(zoomautosens) + { + cursens = float(sensitivity*zoomfov)/fov; + curaccel = float(mouseaccel*zoomfov)/fov; + } + else + { + cursens = zoomsens; + curaccel = zoomaccel; + } + } + if(curaccel && curtime && (dx || dy)) cursens += curaccel * sqrtf(dx*dx + dy*dy)/curtime; + cursens /= 33.0f*sensitivityscale; + camera1->yaw += dx*cursens; + camera1->pitch -= dy*cursens*(invmouse ? -1 : 1); + fixcamerarange(); + if(camera1!=player && !detachedcamera) + { + player->yaw = camera1->yaw; + player->pitch = camera1->pitch; + } + speedmodifier += abs(dx)-abs(dy); } void recomputecamera() { - game::setupcamera(); - computezoom(); - - bool allowthirdperson = game::allowthirdperson(); - bool shoulddetach = (allowthirdperson && thirdperson > 1) || game::detachcamera(); - if((!allowthirdperson || !thirdperson) && !shoulddetach) - { - camera1 = player; - detachedcamera = false; - } - else - { - static physent tempcamera; - camera1 = &tempcamera; - if(detachedcamera && shoulddetach) camera1->o = player->o; - else - { - *camera1 = *player; - detachedcamera = shoulddetach; - } - camera1->reset(); - camera1->type = ENT_CAMERA; - camera1->move = -1; - camera1->eyeheight = camera1->aboveeye = camera1->radius = camera1->xradius = camera1->yradius = 2; - - matrix3 orient; - orient.identity(); - orient.rotate_around_z(camera1->yaw*RAD); - orient.rotate_around_x(camera1->pitch*RAD); - orient.rotate_around_y(camera1->roll*-RAD); - vec dir = vec(orient.b).neg(), side = vec(orient.a).neg(), up = orient.c; - - if(game::collidecamera()) - { - movecamera(camera1, dir, thirdpersondistance, 1); - movecamera(camera1, dir, clamp(thirdpersondistance - camera1->o.dist(player->o), 0.0f, 1.0f), 0.1f); - if(thirdpersonup) - { - vec pos = camera1->o; - float dist = fabs(thirdpersonup); - if(thirdpersonup < 0) up.neg(); - movecamera(camera1, up, dist, 1); - movecamera(camera1, up, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f); - } - if(thirdpersonside) - { - vec pos = camera1->o; - float dist = fabs(thirdpersonside); - if(thirdpersonside < 0) side.neg(); - movecamera(camera1, side, dist, 1); - movecamera(camera1, side, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f); - } - } - else - { - camera1->o.add(vec(dir).mul(thirdpersondistance)); - if(thirdpersonup) camera1->o.add(vec(up).mul(thirdpersonup)); - if(thirdpersonside) camera1->o.add(vec(side).mul(thirdpersonside)); - } - } + game::setupcamera(); + computezoom(); + + bool allowthirdperson = game::allowthirdperson(); + bool shoulddetach = (allowthirdperson && thirdperson > 1) || game::detachcamera(); + if((!allowthirdperson || !thirdperson) && !shoulddetach) + { + camera1 = player; + detachedcamera = false; + } + else + { + static physent tempcamera; + camera1 = &tempcamera; + if(detachedcamera && shoulddetach) camera1->o = player->o; + else + { + *camera1 = *player; + detachedcamera = shoulddetach; + } + camera1->reset(); + camera1->type = ENT_CAMERA; + camera1->move = -1; + camera1->eyeheight = camera1->aboveeye = camera1->radius = camera1->xradius = camera1->yradius = 2; + + matrix3 orient; + orient.identity(); + orient.rotate_around_z(camera1->yaw*RAD); + orient.rotate_around_x(camera1->pitch*RAD); + orient.rotate_around_y(camera1->roll*-RAD); + vec dir = vec(orient.b).neg(), side = vec(orient.a).neg(), up = orient.c; + + if(game::collidecamera()) + { + movecamera(camera1, dir, thirdpersondistance, 1); + movecamera(camera1, dir, clamp(thirdpersondistance - camera1->o.dist(player->o), 0.0f, 1.0f), 0.1f); + if(thirdpersonup) + { + vec pos = camera1->o; + float dist = fabs(thirdpersonup); + if(thirdpersonup < 0) up.neg(); + movecamera(camera1, up, dist, 1); + movecamera(camera1, up, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f); + } + if(thirdpersonside) + { + vec pos = camera1->o; + float dist = fabs(thirdpersonside); + if(thirdpersonside < 0) side.neg(); + movecamera(camera1, side, dist, 1); + movecamera(camera1, side, clamp(dist - camera1->o.dist(pos), 0.0f, 1.0f), 0.1f); + } + } + else + { + camera1->o.add(vec(dir).mul(thirdpersondistance)); + if(thirdpersonup) camera1->o.add(vec(up).mul(thirdpersonup)); + if(thirdpersonside) camera1->o.add(vec(side).mul(thirdpersonside)); + } + } } extern const matrix4 viewmatrix(vec(-1, 0, 0), vec(0, 0, 1), vec(0, -1, 0)); @@ -837,18 +814,18 @@ FVAR(nearplane, 0.01f, 0.54f, 2.0f); vec calcavatarpos(const vec &pos, float dist) { - vec eyepos; - cammatrix.transform(pos, eyepos); - GLdouble ydist = nearplane * tan(curavatarfov/2*RAD), xdist = ydist * aspect; - vec4 scrpos; - scrpos.x = eyepos.x*nearplane/xdist; - scrpos.y = eyepos.y*nearplane/ydist; - scrpos.z = (eyepos.z*(farplane + nearplane) - 2*nearplane*farplane) / (farplane - nearplane); - scrpos.w = -eyepos.z; + vec eyepos; + cammatrix.transform(pos, eyepos); + GLdouble ydist = nearplane * tan(curavatarfov/2*RAD), xdist = ydist * aspect; + vec4 scrpos; + scrpos.x = eyepos.x*nearplane/xdist; + scrpos.y = eyepos.y*nearplane/ydist; + scrpos.z = (eyepos.z*(farplane + nearplane) - 2*nearplane*farplane) / (farplane - nearplane); + scrpos.w = -eyepos.z; - vec worldpos = invcamprojmatrix.perspectivetransform(scrpos); - vec dir = vec(worldpos).sub(camera1->o).rescale(dist); - return dir.add(camera1->o); + vec worldpos = invcamprojmatrix.perspectivetransform(scrpos); + vec dir = vec(worldpos).sub(camera1->o).rescale(dist); + return dir.add(camera1->o); } VAR(reflectclip, 0, 6, 64); @@ -858,17 +835,17 @@ matrix4 clipmatrix, noclipmatrix; void renderavatar() { - if(isthirdperson()) return; + if(isthirdperson()) return; - matrix4 oldprojmatrix = projmatrix; - projmatrix.perspective(curavatarfov, aspect, nearplane, farplane); - projmatrix.scalez(avatardepth); - setcamprojmatrix(false); + matrix4 oldprojmatrix = projmatrix; + projmatrix.perspective(curavatarfov, aspect, nearplane, farplane); + projmatrix.scalez(avatardepth); + setcamprojmatrix(false); - game::renderavatar(); + game::renderavatar(); - projmatrix = oldprojmatrix; - setcamprojmatrix(false); + projmatrix = oldprojmatrix; + setcamprojmatrix(false); } FVAR(polygonoffsetfactor, -1e4f, -3.0f, 1e4f); @@ -879,67 +856,67 @@ matrix4 nooffsetmatrix; void enablepolygonoffset(GLenum type) { - if(!depthoffset) - { - glPolygonOffset(polygonoffsetfactor, polygonoffsetunits); - glEnable(type); - return; - } + if(!depthoffset) + { + glPolygonOffset(polygonoffsetfactor, polygonoffsetunits); + glEnable(type); + return; + } - bool clipped = reflectz < 1e15f && reflectclip; + bool clipped = reflectz < 1e15f && reflectclip; - nooffsetmatrix = projmatrix; - projmatrix.d.z += depthoffset * (clipped ? noclipmatrix.c.z : projmatrix.c.z); - setcamprojmatrix(false, true); + nooffsetmatrix = projmatrix; + projmatrix.d.z += depthoffset * (clipped ? noclipmatrix.c.z : projmatrix.c.z); + setcamprojmatrix(false, true); } void disablepolygonoffset(GLenum type) { - if(!depthoffset) - { - glDisable(type); - return; - } + if(!depthoffset) + { + glDisable(type); + return; + } - projmatrix = nooffsetmatrix; - setcamprojmatrix(false, true); + projmatrix = nooffsetmatrix; + setcamprojmatrix(false, true); } void calcspherescissor(const vec ¢er, float size, float &sx1, float &sy1, float &sx2, float &sy2) { - vec worldpos(center), e; - if(reflecting) worldpos.z = 2*reflectz - worldpos.z; - cammatrix.transform(worldpos, e); - if(e.z > 2*size) { sx1 = sy1 = 1; sx2 = sy2 = -1; return; } - float zzrr = e.z*e.z - size*size, - dx = e.x*e.x + zzrr, dy = e.y*e.y + zzrr, - focaldist = 1.0f/tan(fovy*0.5f*RAD); - sx1 = sy1 = -1; - sx2 = sy2 = 1; - #define CHECKPLANE(c, dir, focaldist, low, high) \ - do { \ - float nzc = (cz*cz + 1) / (cz dir drt) - cz, \ - pz = (d##c)/(nzc*e.c - e.z); \ - if(pz > 0) \ - { \ - float c = (focaldist)*nzc, \ - pc = pz*nzc; \ - if(pc < e.c) low = c; \ - else if(pc > e.c) high = c; \ - } \ - } while(0) - if(dx > 0) - { - float cz = e.x/e.z, drt = sqrtf(dx)/size; - CHECKPLANE(x, -, focaldist/aspect, sx1, sx2); - CHECKPLANE(x, +, focaldist/aspect, sx1, sx2); - } - if(dy > 0) - { - float cz = e.y/e.z, drt = sqrtf(dy)/size; - CHECKPLANE(y, -, focaldist, sy1, sy2); - CHECKPLANE(y, +, focaldist, sy1, sy2); - } + vec worldpos(center), e; + if(reflecting) worldpos.z = 2*reflectz - worldpos.z; + cammatrix.transform(worldpos, e); + if(e.z > 2*size) { sx1 = sy1 = 1; sx2 = sy2 = -1; return; } + float zzrr = e.z*e.z - size*size, + dx = e.x*e.x + zzrr, dy = e.y*e.y + zzrr, + focaldist = 1.0f/tan(fovy*0.5f*RAD); + sx1 = sy1 = -1; + sx2 = sy2 = 1; + #define CHECKPLANE(c, dir, focaldist, low, high) \ + do { \ + float nzc = (cz*cz + 1) / (cz dir drt) - cz, \ + pz = (d##c)/(nzc*e.c - e.z); \ + if(pz > 0) \ + { \ + float c = (focaldist)*nzc, \ + pc = pz*nzc; \ + if(pc < e.c) low = c; \ + else if(pc > e.c) high = c; \ + } \ + } while(0) + if(dx > 0) + { + float cz = e.x/e.z, drt = sqrtf(dx)/size; + CHECKPLANE(x, -, focaldist/aspect, sx1, sx2); + CHECKPLANE(x, +, focaldist/aspect, sx1, sx2); + } + if(dy > 0) + { + float cz = e.y/e.z, drt = sqrtf(dy)/size; + CHECKPLANE(y, -, focaldist, sy1, sy2); + CHECKPLANE(y, +, focaldist, sy1, sy2); + } } static int scissoring = 0; @@ -947,191 +924,191 @@ static GLint oldscissor[4]; int pushscissor(float sx1, float sy1, float sx2, float sy2) { - scissoring = 0; + scissoring = 0; - if(sx1 <= -1 && sy1 <= -1 && sx2 >= 1 && sy2 >= 1) return 0; + if(sx1 <= -1 && sy1 <= -1 && sx2 >= 1 && sy2 >= 1) return 0; - sx1 = max(sx1, -1.0f); - sy1 = max(sy1, -1.0f); - sx2 = min(sx2, 1.0f); - sy2 = min(sy2, 1.0f); + sx1 = max(sx1, -1.0f); + sy1 = max(sy1, -1.0f); + sx2 = min(sx2, 1.0f); + sy2 = min(sy2, 1.0f); - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - int sx = viewport[0] + int(floor((sx1+1)*0.5f*viewport[2])), - sy = viewport[1] + int(floor((sy1+1)*0.5f*viewport[3])), - sw = viewport[0] + int(ceil((sx2+1)*0.5f*viewport[2])) - sx, - sh = viewport[1] + int(ceil((sy2+1)*0.5f*viewport[3])) - sy; - if(sw <= 0 || sh <= 0) return 0; + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + int sx = viewport[0] + int(floor((sx1+1)*0.5f*viewport[2])), + sy = viewport[1] + int(floor((sy1+1)*0.5f*viewport[3])), + sw = viewport[0] + int(ceil((sx2+1)*0.5f*viewport[2])) - sx, + sh = viewport[1] + int(ceil((sy2+1)*0.5f*viewport[3])) - sy; + if(sw <= 0 || sh <= 0) return 0; - if(glIsEnabled(GL_SCISSOR_TEST)) - { - glGetIntegerv(GL_SCISSOR_BOX, oldscissor); - sw += sx; - sh += sy; - sx = max(sx, int(oldscissor[0])); - sy = max(sy, int(oldscissor[1])); - sw = min(sw, int(oldscissor[0] + oldscissor[2])) - sx; - sh = min(sh, int(oldscissor[1] + oldscissor[3])) - sy; - if(sw <= 0 || sh <= 0) return 0; - scissoring = 2; - } - else scissoring = 1; + if(glIsEnabled(GL_SCISSOR_TEST)) + { + glGetIntegerv(GL_SCISSOR_BOX, oldscissor); + sw += sx; + sh += sy; + sx = max(sx, int(oldscissor[0])); + sy = max(sy, int(oldscissor[1])); + sw = min(sw, int(oldscissor[0] + oldscissor[2])) - sx; + sh = min(sh, int(oldscissor[1] + oldscissor[3])) - sy; + if(sw <= 0 || sh <= 0) return 0; + scissoring = 2; + } + else scissoring = 1; - glScissor(sx, sy, sw, sh); - if(scissoring<=1) glEnable(GL_SCISSOR_TEST); + glScissor(sx, sy, sw, sh); + if(scissoring<=1) glEnable(GL_SCISSOR_TEST); - return scissoring; + return scissoring; } void popscissor() { - if(scissoring>1) glScissor(oldscissor[0], oldscissor[1], oldscissor[2], oldscissor[3]); - else if(scissoring) glDisable(GL_SCISSOR_TEST); - scissoring = 0; + if(scissoring>1) glScissor(oldscissor[0], oldscissor[1], oldscissor[2], oldscissor[3]); + else if(scissoring) glDisable(GL_SCISSOR_TEST); + scissoring = 0; } static GLuint screenquadvbo = 0; static void setupscreenquad() { - if(!screenquadvbo) - { - glGenBuffers_(1, &screenquadvbo); - gle::bindvbo(screenquadvbo); - vec2 verts[4] = { vec2(1, -1), vec2(-1, -1), vec2(1, 1), vec2(-1, 1) }; - glBufferData_(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); - gle::clearvbo(); - } + if(!screenquadvbo) + { + glGenBuffers_(1, &screenquadvbo); + gle::bindvbo(screenquadvbo); + vec2 verts[4] = { vec2(1, -1), vec2(-1, -1), vec2(1, 1), vec2(-1, 1) }; + glBufferData_(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); + gle::clearvbo(); + } } static void cleanupscreenquad() { - if(screenquadvbo) { glDeleteBuffers_(1, &screenquadvbo); screenquadvbo = 0; } + if(screenquadvbo) { glDeleteBuffers_(1, &screenquadvbo); screenquadvbo = 0; } } void screenquad() { - setupscreenquad(); - gle::bindvbo(screenquadvbo); - gle::enablevertex(); - gle::vertexpointer(sizeof(vec2), (const vec2 *)0, GL_FLOAT, 2); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - gle::disablevertex(); - gle::clearvbo(); + setupscreenquad(); + gle::bindvbo(screenquadvbo); + gle::enablevertex(); + gle::vertexpointer(sizeof(vec2), (const vec2 *)0, GL_FLOAT, 2); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + gle::disablevertex(); + gle::clearvbo(); } static LocalShaderParam screentexcoord[2] = { LocalShaderParam("screentexcoord0"), LocalShaderParam("screentexcoord1") }; static inline void setscreentexcoord(int i, float w, float h, float x = 0, float y = 0) { - screentexcoord[i].setf(w*0.5f, h*0.5f, x + w*0.5f, y + fabs(h)*0.5f); + screentexcoord[i].setf(w*0.5f, h*0.5f, x + w*0.5f, y + fabs(h)*0.5f); } void screenquad(float sw, float sh) { - setscreentexcoord(0, sw, sh); - screenquad(); + setscreentexcoord(0, sw, sh); + screenquad(); } void screenquadflipped(float sw, float sh) { - setscreentexcoord(0, sw, -sh); - screenquad(); + setscreentexcoord(0, sw, -sh); + screenquad(); } void screenquad(float sw, float sh, float sw2, float sh2) { - setscreentexcoord(0, sw, sh); - setscreentexcoord(1, sw2, sh2); - screenquad(); + setscreentexcoord(0, sw, sh); + setscreentexcoord(1, sw2, sh2); + screenquad(); } void screenquadoffset(float x, float y, float w, float h) { - setscreentexcoord(0, w, h, x, y); - screenquad(); + setscreentexcoord(0, w, h, x, y); + screenquad(); } void screenquadoffset(float x, float y, float w, float h, float x2, float y2, float w2, float h2) { - setscreentexcoord(0, w, h, x, y); - setscreentexcoord(1, w2, h2, x2, y2); - screenquad(); + setscreentexcoord(0, w, h, x, y); + setscreentexcoord(1, w2, h2, x2, y2); + screenquad(); } #define HUDQUAD(x1, y1, x2, y2, sx1, sy1, sx2, sy2) { \ - gle::defvertex(2); \ - gle::deftexcoord0(); \ - gle::begin(GL_TRIANGLE_STRIP); \ - gle::attribf(x2, y1); gle::attribf(sx2, sy1); \ - gle::attribf(x1, y1); gle::attribf(sx1, sy1); \ - gle::attribf(x2, y2); gle::attribf(sx2, sy2); \ - gle::attribf(x1, y2); gle::attribf(sx1, sy2); \ - gle::end(); \ + gle::defvertex(2); \ + gle::deftexcoord0(); \ + gle::begin(GL_TRIANGLE_STRIP); \ + gle::attribf(x2, y1); gle::attribf(sx2, sy1); \ + gle::attribf(x1, y1); gle::attribf(sx1, sy1); \ + gle::attribf(x2, y2); gle::attribf(sx2, sy2); \ + gle::attribf(x1, y2); gle::attribf(sx1, sy2); \ + gle::end(); \ } void hudquad(float x, float y, float w, float h, float tx, float ty, float tw, float th) { - HUDQUAD(x, y, x+w, y+h, tx, ty, tx+tw, ty+th); + HUDQUAD(x, y, x+w, y+h, tx, ty, tx+tw, ty+th); } VARR(fog, 16, 4000, 1000024); bvec fogcolor(0x80, 0x99, 0xB3); HVARFR(fogcolour, 0, 0x8099B3, 0xFFFFFF, { - fogcolor = bvec((fogcolour>>16)&0xFF, (fogcolour>>8)&0xFF, fogcolour&0xFF); + fogcolor = bvec((fogcolour>>16)&0xFF, (fogcolour>>8)&0xFF, fogcolour&0xFF); }); static float findsurface(int fogmat, const vec &v, int &abovemat) { - fogmat &= MATF_VOLUME; - ivec o(v), co; - int csize; - do - { - cube &c = lookupcube(o, 0, co, csize); - int mat = c.material&MATF_VOLUME; - if(mat != fogmat) - { - abovemat = isliquid(mat) ? (int) c.material : (int) MAT_AIR; - return o.z; - } - o.z = co.z + csize; - } - while(o.z < worldsize); - abovemat = MAT_AIR; - return worldsize; + fogmat &= MATF_VOLUME; + ivec o(v), co; + int csize; + do + { + cube &c = lookupcube(o, 0, co, csize); + int mat = c.material&MATF_VOLUME; + if(mat != fogmat) + { + abovemat = isliquid(mat) ? (int) c.material : (int) MAT_AIR; + return o.z; + } + o.z = co.z + csize; + } + while(o.z < worldsize); + abovemat = MAT_AIR; + return worldsize; } static void blendfog(int fogmat, float blend, float logblend, float &start, float &end, vec &fogc) { - switch(fogmat&MATF_VOLUME) - { - case MAT_WATER: - { - const bvec &wcol = getwatercolor(fogmat); - int wfog = getwaterfog(fogmat); - fogc.madd(wcol.tocolor(), blend); - end += logblend*min(fog, max(wfog*4, 32)); - break; - } - - case MAT_LAVA: - { - const bvec &lcol = getlavacolor(fogmat); - int lfog = getlavafog(fogmat); - fogc.madd(lcol.tocolor(), blend); - end += logblend*min(fog, max(lfog*4, 32)); - break; - } - - default: - fogc.madd(fogcolor.tocolor(), blend); - start += logblend*(fog+64)/8; - end += logblend*fog; - break; - } + switch(fogmat&MATF_VOLUME) + { + case MAT_WATER: + { + const bvec &wcol = getwatercolor(fogmat); + int wfog = getwaterfog(fogmat); + fogc.madd(wcol.tocolor(), blend); + end += logblend*min(fog, max(wfog*4, 32)); + break; + } + + case MAT_LAVA: + { + const bvec &lcol = getlavacolor(fogmat); + int lfog = getlavafog(fogmat); + fogc.madd(lcol.tocolor(), blend); + end += logblend*min(fog, max(lfog*4, 32)); + break; + } + + default: + fogc.madd(fogcolor.tocolor(), blend); + start += logblend*(fog+64)/8; + end += logblend*fog; + break; + } } vec oldfogcolor(0, 0, 0), curfogcolor(0, 0, 0); @@ -1139,163 +1116,163 @@ float oldfogstart = 0, oldfogend = 1000000, curfogstart = 0, curfogend = 1000000 void setfogcolor(const vec &v) { - GLOBALPARAM(fogcolor, v); + GLOBALPARAM(fogcolor, v); } void zerofogcolor() { - setfogcolor(vec(0, 0, 0)); + setfogcolor(vec(0, 0, 0)); } void resetfogcolor() { - setfogcolor(curfogcolor); + setfogcolor(curfogcolor); } void pushfogcolor(const vec &v) { - oldfogcolor = curfogcolor; - curfogcolor = v; - resetfogcolor(); + oldfogcolor = curfogcolor; + curfogcolor = v; + resetfogcolor(); } void popfogcolor() { - curfogcolor = oldfogcolor; - resetfogcolor(); + curfogcolor = oldfogcolor; + resetfogcolor(); } void setfogdist(float start, float end) { - GLOBALPARAMF(fogparams, 1/(end - start), end/(end - start)); + GLOBALPARAMF(fogparams, 1/(end - start), end/(end - start)); } void clearfogdist() { - setfogdist(0, 1000000); + setfogdist(0, 1000000); } void resetfogdist() { - setfogdist(curfogstart, curfogend); + setfogdist(curfogstart, curfogend); } void pushfogdist(float start, float end) { - oldfogstart = curfogstart; - oldfogend = curfogend; - curfogstart = start; - curfogend = end; - resetfogdist(); + oldfogstart = curfogstart; + oldfogend = curfogend; + curfogstart = start; + curfogend = end; + resetfogdist(); } void popfogdist() { - curfogstart = oldfogstart; - curfogend = oldfogend; - resetfogdist(); + curfogstart = oldfogstart; + curfogend = oldfogend; + resetfogdist(); } static void resetfog() { - resetfogcolor(); - resetfogdist(); + resetfogcolor(); + resetfogdist(); - glClearColor(curfogcolor.r, curfogcolor.g, curfogcolor.b, 1.0f); + glClearColor(curfogcolor.r, curfogcolor.g, curfogcolor.b, 1.0f); } static void setfog(int fogmat, float below = 1, int abovemat = MAT_AIR) { - float logscale = 256, logblend = log(1 + (logscale - 1)*below) / log(logscale); + float logscale = 256, logblend = log(1 + (logscale - 1)*below) / log(logscale); - curfogstart = curfogend = 0; - curfogcolor = vec(0, 0, 0); - blendfog(fogmat, below, logblend, curfogstart, curfogend, curfogcolor); - if(below < 1) blendfog(abovemat, 1-below, 1-logblend, curfogstart, curfogend, curfogcolor); + curfogstart = curfogend = 0; + curfogcolor = vec(0, 0, 0); + blendfog(fogmat, below, logblend, curfogstart, curfogend, curfogcolor); + if(below < 1) blendfog(abovemat, 1-below, 1-logblend, curfogstart, curfogend, curfogcolor); - resetfog(); + resetfog(); } static void blendfogoverlay(int fogmat, float blend, vec &overlay) { - float maxc; - switch(fogmat&MATF_VOLUME) - { - case MAT_WATER: - { - const bvec &wcol = getwatercolor(fogmat); - maxc = max(wcol.r, max(wcol.g, wcol.b)); - overlay.madd(vec(wcol.r, wcol.g, wcol.b).div(min(32.0f + maxc*7.0f/8.0f, 255.0f)).max(0.4f), blend); - break; - } - - case MAT_LAVA: - { - const bvec &lcol = getlavacolor(fogmat); - maxc = max(lcol.r, max(lcol.g, lcol.b)); - overlay.madd(vec(lcol.r, lcol.g, lcol.b).div(min(32.0f + maxc*7.0f/8.0f, 255.0f)).max(0.4f), blend); - break; - } - - default: - overlay.add(blend); - break; - } + float maxc; + switch(fogmat&MATF_VOLUME) + { + case MAT_WATER: + { + const bvec &wcol = getwatercolor(fogmat); + maxc = max(wcol.r, max(wcol.g, wcol.b)); + overlay.madd(vec(wcol.r, wcol.g, wcol.b).div(min(32.0f + maxc*7.0f/8.0f, 255.0f)).max(0.4f), blend); + break; + } + + case MAT_LAVA: + { + const bvec &lcol = getlavacolor(fogmat); + maxc = max(lcol.r, max(lcol.g, lcol.b)); + overlay.madd(vec(lcol.r, lcol.g, lcol.b).div(min(32.0f + maxc*7.0f/8.0f, 255.0f)).max(0.4f), blend); + break; + } + + default: + overlay.add(blend); + break; + } } void drawfogoverlay(int fogmat, float fogblend, int abovemat) { - SETSHADER(fogoverlay); + SETSHADER(fogoverlay); - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - vec overlay(0, 0, 0); - blendfogoverlay(fogmat, fogblend, overlay); - blendfogoverlay(abovemat, 1-fogblend, overlay); + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + vec overlay(0, 0, 0); + blendfogoverlay(fogmat, fogblend, overlay); + blendfogoverlay(abovemat, 1-fogblend, overlay); - gle::color(overlay); - screenquad(); + gle::color(overlay); + screenquad(); - glDisable(GL_BLEND); + glDisable(GL_BLEND); } bool renderedgame = false; void rendergame(bool mainpass) { - game::rendergame(mainpass); - if(!shadowmapping) renderedgame = true; + game::rendergame(mainpass); + if(!shadowmapping) renderedgame = true; } VARP(skyboxglare, 0, 1, 1); void drawglare() { - glaring = true; - refracting = -1; + glaring = true; + refracting = -1; - pushfogcolor(vec(0, 0, 0)); + pushfogcolor(vec(0, 0, 0)); - glClearColor(0, 0, 0, 1); - glClear((skyboxglare && !shouldclearskyboxglare() ? 0 : GL_COLOR_BUFFER_BIT) | GL_DEPTH_BUFFER_BIT); + glClearColor(0, 0, 0, 1); + glClear((skyboxglare && !shouldclearskyboxglare() ? 0 : GL_COLOR_BUFFER_BIT) | GL_DEPTH_BUFFER_BIT); - rendergeom(); + rendergeom(); - if(skyboxglare) drawskybox(farplane, false); + if(skyboxglare) drawskybox(farplane, false); - renderreflectedmapmodels(); - rendergame(); - renderavatar(); + renderreflectedmapmodels(); + rendergame(); + renderavatar(); - renderwater(); - rendermaterials(); - renderalphageom(); - renderparticles(); + renderwater(); + rendermaterials(); + renderalphageom(); + renderparticles(); - popfogcolor(); + popfogcolor(); - refracting = 0; - glaring = false; + refracting = 0; + glaring = false; } VARP(reflectmms, 0, 1, 1); @@ -1305,201 +1282,201 @@ matrix4 noreflectmatrix; void drawreflection(float z, bool refract, int fogdepth, const bvec &col) { - reflectz = z < 0 ? 1e16f : z; - reflecting = !refract; - refracting = refract ? (z < 0 || camera1->o.z >= z ? -1 : 1) : 0; - fading = waterrefract && waterfade && z>=0; - fogging = refracting<0 && z>=0; - refractfog = fogdepth; - - if(fogging) - { - pushfogdist(camera1->o.z - z, camera1->o.z - (z - max(refractfog, 1))); - pushfogcolor(col.tocolor()); - } - else - { - vec color(0, 0, 0); - float start = 0, end = 0; - blendfog(MAT_AIR, 1, 1, start, end, color); - pushfogdist(start, end); - pushfogcolor(color); - } - - if(fading) - { - float scale = fogging ? -0.25f : 0.25f, offset = 2*fabs(scale) - scale*z; - GLOBALPARAMF(waterfadeparams, scale, offset, -scale, offset + camera1->o.z*scale); - } - - if(reflecting) - { - noreflectmatrix = cammatrix; - cammatrix.reflectz(z); - - glFrontFace(GL_CCW); - } - - if(reflectclip && z>=0) - { - float zoffset = reflectclip/4.0f, zclip; - if(refracting<0) - { - zclip = z+zoffset; - if(camera1->o.z<=zclip) zclip = z; - } - else - { - zclip = z-zoffset; - if(camera1->o.z>=zclip && camera1->o.z<=z+4.0f) zclip = z; - if(reflecting) zclip = 2*z - zclip; - } - plane clipplane; - invcammatrix.transposedtransform(plane(0, 0, refracting>0 ? 1 : -1, refracting>0 ? -zclip : zclip), clipplane); - clipmatrix.clip(clipplane, projmatrix); - noclipmatrix = projmatrix; - projmatrix = clipmatrix; - } - - setcamprojmatrix(false, true); - - renderreflectedgeom(refracting<0 && z>=0 && caustics, fogging); - - if(reflecting || refracting>0 || (refracting<0 && refractsky) || z<0) - { - if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - if(reflectclip && z>=0) - { - projmatrix = noclipmatrix; - setcamprojmatrix(false, true); - } - drawskybox(farplane, false); - if(reflectclip && z>=0) - { - projmatrix = clipmatrix; - setcamprojmatrix(false, true); - } - if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - } - else if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); - - renderdecals(); - - if(reflectmms) renderreflectedmapmodels(); - rendergame(); - - if(refracting && z>=0 && !isthirdperson() && fabs(camera1->o.z-z) <= 0.5f*(player->eyeheight + player->aboveeye)) - { - matrix4 oldprojmatrix = projmatrix, avatarproj; - avatarproj.perspective(curavatarfov, aspect, nearplane, farplane); - if(reflectclip) - { - matrix4 avatarclip; - plane clipplane; - invcammatrix.transposedtransform(plane(0, 0, refracting, reflectclipavatar/4.0f - refracting*z), clipplane); - avatarclip.clip(clipplane, avatarproj); - projmatrix = avatarclip; - } - else projmatrix = avatarproj; - setcamprojmatrix(false, true); - game::renderavatar(); - projmatrix = oldprojmatrix; - setcamprojmatrix(false, true); - } - - rendermaterials(); - renderalphageom(fogging); - renderparticles(); - - if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - if(reflectclip && z>=0) projmatrix = noclipmatrix; - - if(reflecting) - { - cammatrix = noreflectmatrix; - - glFrontFace(GL_CW); - } - - popfogdist(); - popfogcolor(); - - reflectz = 1e16f; - refracting = 0; - reflecting = fading = fogging = false; - - setcamprojmatrix(false, true); + reflectz = z < 0 ? 1e16f : z; + reflecting = !refract; + refracting = refract ? (z < 0 || camera1->o.z >= z ? -1 : 1) : 0; + fading = waterrefract && waterfade && z>=0; + fogging = refracting<0 && z>=0; + refractfog = fogdepth; + + if(fogging) + { + pushfogdist(camera1->o.z - z, camera1->o.z - (z - max(refractfog, 1))); + pushfogcolor(col.tocolor()); + } + else + { + vec color(0, 0, 0); + float start = 0, end = 0; + blendfog(MAT_AIR, 1, 1, start, end, color); + pushfogdist(start, end); + pushfogcolor(color); + } + + if(fading) + { + float scale = fogging ? -0.25f : 0.25f, offset = 2*fabs(scale) - scale*z; + GLOBALPARAMF(waterfadeparams, scale, offset, -scale, offset + camera1->o.z*scale); + } + + if(reflecting) + { + noreflectmatrix = cammatrix; + cammatrix.reflectz(z); + + glFrontFace(GL_CCW); + } + + if(reflectclip && z>=0) + { + float zoffset = reflectclip/4.0f, zclip; + if(refracting<0) + { + zclip = z+zoffset; + if(camera1->o.z<=zclip) zclip = z; + } + else + { + zclip = z-zoffset; + if(camera1->o.z>=zclip && camera1->o.z<=z+4.0f) zclip = z; + if(reflecting) zclip = 2*z - zclip; + } + plane clipplane; + invcammatrix.transposedtransform(plane(0, 0, refracting>0 ? 1 : -1, refracting>0 ? -zclip : zclip), clipplane); + clipmatrix.clip(clipplane, projmatrix); + noclipmatrix = projmatrix; + projmatrix = clipmatrix; + } + + setcamprojmatrix(false, true); + + renderreflectedgeom(refracting<0 && z>=0 && caustics, fogging); + + if(reflecting || refracting>0 || (refracting<0 && refractsky) || z<0) + { + if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + if(reflectclip && z>=0) + { + projmatrix = noclipmatrix; + setcamprojmatrix(false, true); + } + drawskybox(farplane, false); + if(reflectclip && z>=0) + { + projmatrix = clipmatrix; + setcamprojmatrix(false, true); + } + if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + } + else if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + + renderdecals(); + + if(reflectmms) renderreflectedmapmodels(); + rendergame(); + + if(refracting && z>=0 && !isthirdperson() && fabs(camera1->o.z-z) <= 0.5f*(player->eyeheight + player->aboveeye)) + { + matrix4 oldprojmatrix = projmatrix, avatarproj; + avatarproj.perspective(curavatarfov, aspect, nearplane, farplane); + if(reflectclip) + { + matrix4 avatarclip; + plane clipplane; + invcammatrix.transposedtransform(plane(0, 0, refracting, reflectclipavatar/4.0f - refracting*z), clipplane); + avatarclip.clip(clipplane, avatarproj); + projmatrix = avatarclip; + } + else projmatrix = avatarproj; + setcamprojmatrix(false, true); + game::renderavatar(); + projmatrix = oldprojmatrix; + setcamprojmatrix(false, true); + } + + rendermaterials(); + renderalphageom(fogging); + renderparticles(); + + if(fading) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + if(reflectclip && z>=0) projmatrix = noclipmatrix; + + if(reflecting) + { + cammatrix = noreflectmatrix; + + glFrontFace(GL_CW); + } + + popfogdist(); + popfogcolor(); + + reflectz = 1e16f; + refracting = 0; + reflecting = fading = fogging = false; + + setcamprojmatrix(false, true); } int drawtex = 0; void drawcubemap(int size, const vec &o, float yaw, float pitch, const cubemapside &side, bool onlysky) { - drawtex = DRAWTEX_ENVMAP; + drawtex = DRAWTEX_ENVMAP; - physent *oldcamera = camera1; - static physent cmcamera; - cmcamera = *player; - cmcamera.reset(); - cmcamera.type = ENT_CAMERA; - cmcamera.o = o; - cmcamera.yaw = yaw; - cmcamera.pitch = pitch; - cmcamera.roll = 0; - camera1 = &cmcamera; + physent *oldcamera = camera1; + static physent cmcamera; + cmcamera = *player; + cmcamera.reset(); + cmcamera.type = ENT_CAMERA; + cmcamera.o = o; + cmcamera.yaw = yaw; + cmcamera.pitch = pitch; + cmcamera.roll = 0; + camera1 = &cmcamera; - int fogmat = lookupmaterial(o)&(MATF_VOLUME|MATF_INDEX); + int fogmat = lookupmaterial(o)&(MATF_VOLUME|MATF_INDEX); - setfog(fogmat); + setfog(fogmat); - int farplane = worldsize*2; + int farplane = worldsize*2; - projmatrix.perspective(90.0f, 1.0f, nearplane, farplane); - if(!side.flipx || !side.flipy) projmatrix.scalexy(!side.flipx ? -1 : 1, !side.flipy ? -1 : 1); - if(side.swapxy) - { - swap(projmatrix.a.x, projmatrix.a.y); - swap(projmatrix.b.x, projmatrix.b.y); - swap(projmatrix.c.x, projmatrix.c.y); - swap(projmatrix.d.x, projmatrix.d.y); - } - setcamprojmatrix(); + projmatrix.perspective(90.0f, 1.0f, nearplane, farplane); + if(!side.flipx || !side.flipy) projmatrix.scalexy(!side.flipx ? -1 : 1, !side.flipy ? -1 : 1); + if(side.swapxy) + { + swap(projmatrix.a.x, projmatrix.a.y); + swap(projmatrix.b.x, projmatrix.b.y); + swap(projmatrix.c.x, projmatrix.c.y); + swap(projmatrix.d.x, projmatrix.d.y); + } + setcamprojmatrix(); - xtravertsva = xtraverts = glde = gbatches = 0; + xtravertsva = xtraverts = glde = gbatches = 0; - visiblecubes(); + visiblecubes(); - if(onlysky) drawskybox(farplane, false, true); - else - { - glClear(GL_DEPTH_BUFFER_BIT); + if(onlysky) drawskybox(farplane, false, true); + else + { + glClear(GL_DEPTH_BUFFER_BIT); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); - if(limitsky()) drawskybox(farplane, true); + if(limitsky()) drawskybox(farplane, true); - rendergeom(); + rendergeom(); - if(!limitsky()) drawskybox(farplane, false); + if(!limitsky()) drawskybox(farplane, false); -// queryreflections(); +// queryreflections(); - rendermapmodels(); - renderalphageom(); + rendermapmodels(); + renderalphageom(); -// drawreflections(); +// drawreflections(); -// renderwater(); -// rendermaterials(); +// renderwater(); +// rendermaterials(); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - } + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + } - camera1 = oldcamera; - drawtex = 0; + camera1 = oldcamera; + drawtex = 0; } VAR(modelpreviewfov, 10, 20, 100); @@ -1507,254 +1484,197 @@ VAR(modelpreviewpitch, -90, -15, 90); namespace modelpreview { - physent *oldcamera; - physent camera; + physent *oldcamera; + physent camera; - float oldaspect, oldfovy, oldfov; - int oldfarplane; - matrix4 oldprojmatrix; + float oldaspect, oldfovy, oldfov; + int oldfarplane; + matrix4 oldprojmatrix; - void start(int x, int y, int w, int h, bool background) - { - drawtex = DRAWTEX_MODELPREVIEW; + void start(int x, int y, int w, int h, bool background) + { + drawtex = DRAWTEX_MODELPREVIEW; - glViewport(x, y, w, h); - glScissor(x, y, w, h); - glEnable(GL_SCISSOR_TEST); + glViewport(x, y, w, h); + glScissor(x, y, w, h); + glEnable(GL_SCISSOR_TEST); - oldcamera = camera1; - camera = *camera1; - camera.reset(); - camera.type = ENT_CAMERA; - camera.o = vec(0, 0, 0); - camera.yaw = 0; - camera.pitch = modelpreviewpitch; - camera.roll = 0; - camera1 = &camera; + oldcamera = camera1; + camera = *camera1; + camera.reset(); + camera.type = ENT_CAMERA; + camera.o = vec(0, 0, 0); + camera.yaw = 0; + camera.pitch = modelpreviewpitch; + camera.roll = 0; + camera1 = &camera; - oldaspect = aspect; - oldfovy = fovy; - oldfov = curfov; - oldfarplane = farplane; - oldprojmatrix = projmatrix; + oldaspect = aspect; + oldfovy = fovy; + oldfov = curfov; + oldfarplane = farplane; + oldprojmatrix = projmatrix; - aspect = w/float(h); - fovy = modelpreviewfov; - curfov = 2*atan2(tan(fovy/2*RAD), 1/aspect)/RAD; - farplane = 1024; + aspect = w/float(h); + fovy = modelpreviewfov; + curfov = 2*atan2(tan(fovy/2*RAD), 1/aspect)/RAD; + farplane = 1024; - clearfogdist(); - zerofogcolor(); - glClearColor(0, 0, 0, 1); + clearfogdist(); + zerofogcolor(); + glClearColor(0, 0, 0, 1); - glClear((background ? GL_COLOR_BUFFER_BIT : 0) | GL_DEPTH_BUFFER_BIT); + glClear((background ? GL_COLOR_BUFFER_BIT : 0) | GL_DEPTH_BUFFER_BIT); - projmatrix.perspective(fovy, aspect, nearplane, farplane); - setcamprojmatrix(); + projmatrix.perspective(fovy, aspect, nearplane, farplane); + setcamprojmatrix(); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - } + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + } - void end() - { - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); + void end() + { + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); - resetfogdist(); - resetfogcolor(); - glClearColor(curfogcolor.r, curfogcolor.g, curfogcolor.b, 1); + resetfogdist(); + resetfogcolor(); + glClearColor(curfogcolor.r, curfogcolor.g, curfogcolor.b, 1); - aspect = oldaspect; - fovy = oldfovy; - curfov = oldfov; - farplane = oldfarplane; + aspect = oldaspect; + fovy = oldfovy; + curfov = oldfov; + farplane = oldfarplane; - camera1 = oldcamera; - drawtex = 0; + camera1 = oldcamera; + drawtex = 0; - glDisable(GL_SCISSOR_TEST); - glViewport(0, 0, screenw, screenh); + glDisable(GL_SCISSOR_TEST); + glViewport(0, 0, screenw, screenh); - projmatrix = oldprojmatrix; - setcamprojmatrix(); - } + projmatrix = oldprojmatrix; + setcamprojmatrix(); + } } vec calcmodelpreviewpos(const vec &radius, float &yaw) { - yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f); - float dist = 1.15f*max(radius.magnitude2()/aspect, radius.magnitude())/sinf(fovy/2*RAD); - return vec(0, dist, 0).rotate_around_x(camera1->pitch*RAD); + yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f); + float dist = 1.15f*max(radius.magnitude2()/aspect, radius.magnitude())/sinf(fovy/2*RAD); + return vec(0, dist, 0).rotate_around_x(camera1->pitch*RAD); } bool deferdrawtextures = false; void drawtextures() { - if(minimized) { deferdrawtextures = true; return; } - deferdrawtextures = false; - genenvmaps(); -} - -GLuint motiontex = 0; -int motionw = 0, motionh = 0, lastmotion = 0; - -void cleanupmotionblur() -{ - if(motiontex) { glDeleteTextures(1, &motiontex); motiontex = 0; } - motionw = motionh = 0; - lastmotion = 0; -} - -VARFP(motionblur, 0, 0, 1, { if(!motionblur) cleanupmotionblur(); }); -VARP(motionblurmillis, 1, 5, 1000); -FVARP(motionblurscale, 0, 0.5f, 1); - -void addmotionblur() -{ - if(!motionblur || max(screenw, screenh) > hwtexsize) return; - - if(game::ispaused()) { lastmotion = 0; return; } - - if(!motiontex || motionw != screenw || motionh != screenh) - { - if(!motiontex) glGenTextures(1, &motiontex); - motionw = screenw; - motionh = screenh; - lastmotion = 0; - createtexture(motiontex, motionw, motionh, NULL, 3, 0, GL_RGB); - } - - glBindTexture(GL_TEXTURE_2D, motiontex); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - SETSHADER(screenrect); - - gle::colorf(1, 1, 1, lastmotion ? pow(motionblurscale, max(float(lastmillis - lastmotion)/motionblurmillis, 1.0f)) : 0); - screenquad(1, 1); - - glDisable(GL_BLEND); - - if(lastmillis - lastmotion >= motionblurmillis) - { - lastmotion = lastmillis - lastmillis%motionblurmillis; - - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenw, screenh); - } -} - -bool dopostfx = false; - -void invalidatepostfx() -{ - dopostfx = false; + if(minimized) { deferdrawtextures = true; return; } + deferdrawtextures = false; + genenvmaps(); } int xtraverts, xtravertsva; void gl_drawframe() { - if(deferdrawtextures) drawtextures(); + if(deferdrawtextures) drawtextures(); - updatedynlights(); + updatedynlights(); - int w = screenw, h = screenh; - aspect = forceaspect ? forceaspect : w/float(h); - fovy = 2*atan2(tan(curfov/2*RAD), aspect)/RAD; + int w = screenw, h = screenh; + aspect = forceaspect ? forceaspect : w/float(h); + fovy = 2*atan2(tan(curfov/2*RAD), aspect)/RAD; - int fogmat = lookupmaterial(camera1->o)&(MATF_VOLUME|MATF_INDEX), abovemat = MAT_AIR; - float fogblend = 1.0f, causticspass = 0.0f; - if(isliquid(fogmat&MATF_VOLUME)) - { - float z = findsurface(fogmat, camera1->o, abovemat) - WATER_OFFSET; - if(camera1->o.z < z + 1) fogblend = min(z + 1 - camera1->o.z, 1.0f); - else fogmat = abovemat; - if(caustics && (fogmat&MATF_VOLUME)==MAT_WATER && camera1->o.z < z) - causticspass = min(z - camera1->o.z, 1.0f); - } - else fogmat = MAT_AIR; - setfog(fogmat, fogblend, abovemat); - if(fogmat!=MAT_AIR) - { - float blend = abovemat==MAT_AIR ? fogblend : 1.0f; - fovy += blend*sinf(lastmillis/1000.0)*2.0f; - aspect += blend*sinf(lastmillis/1000.0+M_PI)*0.1f; - } + int fogmat = lookupmaterial(camera1->o)&(MATF_VOLUME|MATF_INDEX), abovemat = MAT_AIR; + float fogblend = 1.0f, causticspass = 0.0f; + if(isliquid(fogmat&MATF_VOLUME)) + { + float z = findsurface(fogmat, camera1->o, abovemat) - WATER_OFFSET; + if(camera1->o.z < z + 1) fogblend = min(z + 1 - camera1->o.z, 1.0f); + else fogmat = abovemat; + if(caustics && (fogmat&MATF_VOLUME)==MAT_WATER && camera1->o.z < z) + causticspass = min(z - camera1->o.z, 1.0f); + } + else fogmat = MAT_AIR; + setfog(fogmat, fogblend, abovemat); + if(fogmat!=MAT_AIR) + { + float blend = abovemat==MAT_AIR ? fogblend : 1.0f; + fovy += blend*sinf(lastmillis/1000.0)*2.0f; + aspect += blend*sinf(lastmillis/1000.0+M_PI)*0.1f; + } - farplane = worldsize*2; + farplane = worldsize*2; - projmatrix.perspective(fovy, aspect, nearplane, farplane); - setcamprojmatrix(); + projmatrix.perspective(fovy, aspect, nearplane, farplane); + setcamprojmatrix(); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); - xtravertsva = xtraverts = glde = gbatches = 0; + xtravertsva = xtraverts = glde = gbatches = 0; - visiblecubes(); + visiblecubes(); - glClear(GL_DEPTH_BUFFER_BIT|(wireframe && editmode ? GL_COLOR_BUFFER_BIT : 0)); + glClear(GL_DEPTH_BUFFER_BIT|(wireframe && editmode ? GL_COLOR_BUFFER_BIT : 0)); - if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - if(limitsky()) drawskybox(farplane, true); + if(limitsky()) drawskybox(farplane, true); - rendergeom(causticspass); + rendergeom(causticspass); - extern int outline; - if(!wireframe && editmode && outline) renderoutline(); + extern int outline; + if(!wireframe && editmode && outline) renderoutline(); - queryreflections(); + queryreflections(); - if(!limitsky()) drawskybox(farplane, false); + if(!limitsky()) drawskybox(farplane, false); - renderdecals(true); + renderdecals(true); - rendermapmodels(); - rendergame(true); - renderavatar(); + rendermapmodels(); + rendergame(true); + renderavatar(); - if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - drawglaretex(); - drawdepthfxtex(); - drawreflections(); + drawglaretex(); + drawdepthfxtex(); + drawreflections(); - if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - renderwater(); + renderwater(); - rendermaterials(); - renderalphageom(); + rendermaterials(); + renderalphageom(); - if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if(wireframe && editmode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - renderparticles(true); + renderparticles(true); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); - addmotionblur(); - addglare(); - if(isliquid(fogmat&MATF_VOLUME)) drawfogoverlay(fogmat, fogblend, abovemat); - renderpostfx(); + addglare(); + if(isliquid(fogmat&MATF_VOLUME)) drawfogoverlay(fogmat, fogblend, abovemat); + renderpostfx(); - gl_drawhud(); + gl_drawhud(); - renderedgame = false; + renderedgame = false; } void gl_drawmainmenu() { - xtravertsva = xtraverts = glde = gbatches = 0; + xtravertsva = xtraverts = glde = gbatches = 0; - renderbackground(NULL, NULL, NULL, NULL, true, true); - renderpostfx(); + renderbackground(NULL, NULL, NULL, NULL, true, true); + renderpostfx(); - gl_drawhud(); + gl_drawhud(); } VARNP(damagecompass, usedamagecompass, 0, 1, 1); @@ -1768,99 +1688,58 @@ float damagedirs[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; void damagecompass(int n, const vec &loc) { - if(!usedamagecompass || minimized) return; - vec delta(loc); - delta.sub(camera1->o); - float yaw = 0, pitch; - if(delta.magnitude() > 4) - { - vectoyawpitch(delta, yaw, pitch); - yaw -= camera1->yaw; - } - if(yaw >= 360) yaw = fmod(yaw, 360); - else if(yaw < 0) yaw = 360 - fmod(-yaw, 360); - int dir = (int(yaw+22.5f)%360)/45; - damagedirs[dir] += max(n, damagecompassmin)/float(damagecompassmax); - if(damagedirs[dir]>1) damagedirs[dir] = 1; + if(!usedamagecompass || minimized) return; + vec delta(loc); + delta.sub(camera1->o); + float yaw = 0, pitch; + if(delta.magnitude() > 4) + { + vectoyawpitch(delta, yaw, pitch); + yaw -= camera1->yaw; + } + if(yaw >= 360) yaw = fmod(yaw, 360); + else if(yaw < 0) yaw = 360 - fmod(-yaw, 360); + int dir = (int(yaw+22.5f)%360)/45; + damagedirs[dir] += max(n, damagecompassmin)/float(damagecompassmax); + if(damagedirs[dir]>1) damagedirs[dir] = 1; } void drawdamagecompass(int w, int h) { - hudnotextureshader->set(); - - int dirs = 0; - float size = damagecompasssize/100.0f*min(h, w)/2.0f; - loopi(8) if(damagedirs[i]>0) - { - if(!dirs) - { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gle::colorf(1, 0, 0, damagecompassalpha/100.0f); - gle::defvertex(); - gle::begin(GL_TRIANGLES); - } - dirs++; - - float logscale = 32, - scale = log(1 + (logscale - 1)*damagedirs[i]) / log(logscale), - offset = -size/2.0f-min(h, w)/4.0f; - matrix4x3 m; - m.identity(); - m.settranslation(w/2, h/2, 0); - m.rotate_around_z(i*45*RAD); - m.translate(0, offset, 0); - m.scale(size*scale); - - gle::attrib(m.transform(vec2(1, 1))); - gle::attrib(m.transform(vec2(-1, 1))); - gle::attrib(m.transform(vec2(0, 0))); - - // fade in log space so short blips don't disappear too quickly - scale -= float(curtime)/damagecompassfade; - damagedirs[i] = scale > 0 ? (pow(logscale, scale) - 1) / (logscale - 1) : 0; - } - if(dirs) gle::end(); -} - -int damageblendmillis = 0; - -VARFP(damagescreen, 0, 1, 1, { if(!damagescreen) damageblendmillis = 0; }); -VARP(damagescreenfactor, 1, 7, 100); -VARP(damagescreenalpha, 1, 45, 100); -VARP(damagescreenfade, 0, 125, 1000); -VARP(damagescreenmin, 1, 10, 1000); -VARP(damagescreenmax, 1, 100, 1000); - -void damageblend(int n) -{ - if(!damagescreen || minimized) return; - if(lastmillis > damageblendmillis) damageblendmillis = lastmillis; - damageblendmillis += clamp(n, damagescreenmin, damagescreenmax)*damagescreenfactor; -} - -void drawdamagescreen(int w, int h) -{ - if(lastmillis >= damageblendmillis) return; - - hudshader->set(); - - static Texture *damagetex = NULL; - if(!damagetex) damagetex = textureload("packages/hud/damage.png", 3); - - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, damagetex->id); - float fade = damagescreenalpha/100.0f; - if(damageblendmillis - lastmillis < damagescreenfade) - fade *= float(damageblendmillis - lastmillis)/damagescreenfade; - gle::colorf(fade, fade, fade, fade); - - hudquad(0, 0, w, h); -} - -void cleardamagescreen() -{ - damageblendmillis = 0; - loopi(8) damagedirs[i] = 0; + hudnotextureshader->set(); + + int dirs = 0; + float size = damagecompasssize/100.0f*min(h, w)/2.0f; + loopi(8) if(damagedirs[i]>0) + { + if(!dirs) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gle::colorf(1, 0, 0, damagecompassalpha/100.0f); + gle::defvertex(); + gle::begin(GL_TRIANGLES); + } + dirs++; + + float logscale = 32, + scale = log(1 + (logscale - 1)*damagedirs[i]) / log(logscale), + offset = -size/2.0f-min(h, w)/4.0f; + matrix4x3 m; + m.identity(); + m.settranslation(w/2, h/2, 0); + m.rotate_around_z(i*45*RAD); + m.translate(0, offset, 0); + m.scale(size*scale); + + gle::attrib(m.transform(vec2(1, 1))); + gle::attrib(m.transform(vec2(-1, 1))); + gle::attrib(m.transform(vec2(0, 0))); + + // fade in log space so short blips don't disappear too quickly + scale -= float(curtime)/damagecompassfade; + damagedirs[i] = scale > 0 ? (pow(logscale, scale) - 1) / (logscale - 1) : 0; + } + if(dirs) gle::end(); } VAR(hidestats, 0, 0, 1); @@ -1876,14 +1755,14 @@ static Texture *crosshairs[MAXCROSSHAIRS] = { NULL, NULL, NULL, NULL }; void loadcrosshair(const char *name, int i) { - if(i < 0 || i >= MAXCROSSHAIRS) return; + if(i < 0 || i >= MAXCROSSHAIRS) return; crosshairs[i] = name ? textureload(name, 3, true) : notexture; - if(crosshairs[i] == notexture) - { - name = game::defaultcrosshair(i); - if(!name) name = "data/crosshair.png"; - crosshairs[i] = textureload(name, 3, true); - } + if(crosshairs[i] == notexture) + { + name = game::defaultcrosshair(i); + if(!name) name = "data/crosshair.png"; + crosshairs[i] = textureload(name, 3, true); + } } void loadcrosshair_(const char *name, int *i) @@ -1895,68 +1774,62 @@ COMMANDN(loadcrosshair, loadcrosshair_, "si"); ICOMMAND(getcrosshair, "i", (int *i), { - const char *name = ""; - if(*i >= 0 && *i < MAXCROSSHAIRS) - { - name = crosshairs[*i] ? crosshairs[*i]->name : game::defaultcrosshair(*i); - if(!name) name = "data/crosshair.png"; - } - result(name); + const char *name = ""; + if(*i >= 0 && *i < MAXCROSSHAIRS) + { + name = crosshairs[*i] ? crosshairs[*i]->name : game::defaultcrosshair(*i); + if(!name) name = "data/crosshair.png"; + } + result(name); }); void writecrosshairs(stream *f) { - loopi(MAXCROSSHAIRS) if(crosshairs[i] && crosshairs[i]!=notexture) - f->printf("loadcrosshair %s %d\n", escapestring(crosshairs[i]->name), i); - f->printf("\n"); + loopi(MAXCROSSHAIRS) if(crosshairs[i] && crosshairs[i]!=notexture) + f->printf("loadcrosshair %s %d\n", escapestring(crosshairs[i]->name), i); + f->printf("\n"); } void drawcrosshair(int w, int h) { - bool windowhit = g3d_windowhit(true, false); - if(!windowhit && (hidehud || mainmenu)) return; //(hidehud || player->state==CS_SPECTATOR || player->state==CS_DEAD)) return; - - vec color(1, 1, 1); - float cx = 0.5f, cy = 0.5f, chsize; - Texture *crosshair; - if(windowhit) - { - static Texture *cursor = NULL; - if(!cursor) cursor = textureload("data/guicursor.png", 3, true); - crosshair = cursor; - chsize = cursorsize*w/900.0f; - g3d_cursorpos(cx, cy); - } - else - { - int index = game::selectcrosshair(color); - if(index < 0) return; - if(!crosshairfx) index = 0; - if(!crosshairfx || !crosshaircolors) color = vec(1, 1, 1); - crosshair = crosshairs[index]; - if(!crosshair) - { - loadcrosshair(NULL, index); - crosshair = crosshairs[index]; - } - chsize = crosshairsize*w/900.0f; - } - if(crosshair->type&Texture::ALPHA) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - else glBlendFunc(GL_ONE, GL_ONE); - float x = cx*w - (windowhit ? 0 : chsize/2.0f); - float y = cy*h - (windowhit ? 0 : chsize/2.0f); - glBindTexture(GL_TEXTURE_2D, crosshair->id); - - hudshader->set(); - gle::color(color); - hudquad(x, y, chsize, chsize); -} - -VARP(wallclock, 0, 0, 1); -VARP(wallclock24, 0, 0, 1); -VARP(wallclocksecs, 0, 0, 1); - -static time_t walltime = 0; + bool windowhit = g3d_windowhit(true, false); + if(!windowhit && (hidehud || mainmenu)) return; //(hidehud || player->state==CS_SPECTATOR || player->state==CS_DEAD)) return; + + vec color(1, 1, 1); + float cx = 0.5f, cy = 0.5f, chsize; + Texture *crosshair; + if(windowhit) + { + static Texture *cursor = NULL; + if(!cursor) cursor = textureload("data/guicursor.png", 3, true); + crosshair = cursor; + chsize = cursorsize*w/900.0f; + g3d_cursorpos(cx, cy); + } + else + { + int index = game::selectcrosshair(color); + if(index < 0) return; + if(!crosshairfx) index = 0; + if(!crosshairfx || !crosshaircolors) color = vec(1, 1, 1); + crosshair = crosshairs[index]; + if(!crosshair) + { + loadcrosshair(NULL, index); + crosshair = crosshairs[index]; + } + chsize = crosshairsize*w/900.0f; + } + if(crosshair->type&Texture::ALPHA) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else glBlendFunc(GL_ONE, GL_ONE); + float x = cx*w - (windowhit ? 0 : chsize/2.0f); + float y = cy*h - (windowhit ? 0 : chsize/2.0f); + glBindTexture(GL_TEXTURE_2D, crosshair->id); + + hudshader->set(); + gle::color(color); + hudquad(x, y, chsize, chsize); +} VARP(showfps, 0, 1, 1); VARP(showfpsrange, 0, 0, 1); @@ -1967,187 +1840,165 @@ FVARP(conscale, 1e-3f, 0.33f, 1e3f); void gl_drawhud() { - g3d_render(); - - int w = screenw, h = screenh; - if(forceaspect) w = int(ceil(h*forceaspect)); - - if(editmode && !hidehud && !mainmenu) - { - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - - renderblendbrush(); - - rendereditcursor(); - - glDepthMask(GL_TRUE); - glDisable(GL_DEPTH_TEST); - } - - gettextres(w, h); - - hudmatrix.ortho(0, w, h, 0, -1, 1); - resethudmatrix(); - - gle::colorf(1, 1, 1); - - glEnable(GL_BLEND); - - if(!mainmenu) - { - drawdamagescreen(w, h); - drawdamagecompass(w, h); - } - - hudshader->set(); - - int conw = int(w/conscale), conh = int(h/conscale), abovehud = conh - FONTH, limitgui = abovehud; - if(!hidehud && !mainmenu) - { - if(!hidestats) - { - pushhudmatrix(); - hudmatrix.scale(conscale, conscale, 1); - flushhudmatrix(); - - int roffset = 0; - if(showfps) - { - static int lastfps = 0, prevfps[3] = { 0, 0, 0 }, curfps[3] = { 0, 0, 0 }; - if(totalmillis - lastfps >= statrate) - { - memcpy(prevfps, curfps, sizeof(prevfps)); - lastfps = totalmillis - (totalmillis%statrate); - } - int nextfps[3]; - getfps(nextfps[0], nextfps[1], nextfps[2]); - loopi(3) if(prevfps[i]==curfps[i]) curfps[i] = nextfps[i]; - if(showfpsrange) draw_textf("fps %d+%d-%d", conw-7*FONTH, conh-FONTH*3/2, curfps[0], curfps[1], curfps[2]); - else draw_textf("fps %d", conw-5*FONTH, conh-FONTH*3/2, curfps[0]); - roffset += FONTH; - } - - if(wallclock) - { - if(!walltime) { walltime = time(NULL); walltime -= totalmillis/1000; if(!walltime) walltime++; } - time_t walloffset = walltime + totalmillis/1000; - struct tm *localvals = localtime(&walloffset); - static string buf; - if(localvals && strftime(buf, sizeof(buf), wallclocksecs ? (wallclock24 ? "%H:%M:%S" : "%I:%M:%S%p") : (wallclock24 ? "%H:%M" : "%I:%M%p"), localvals)) - { - // hack because not all platforms (windows) support %P lowercase option - // also strip leading 0 from 12 hour time - char *dst = buf; - const char *src = &buf[!wallclock24 && buf[0]=='0' ? 1 : 0]; - while(*src) *dst++ = tolower(*src++); - *dst++ = '\0'; - draw_text(buf, conw-5*FONTH, conh-FONTH*3/2-roffset); - roffset += FONTH; - } - } - - if(editmode || showeditstats) - { - static int laststats = 0, prevstats[8] = { 0, 0, 0, 0, 0, 0, 0 }, curstats[8] = { 0, 0, 0, 0, 0, 0, 0 }; - if(totalmillis - laststats >= statrate) - { - memcpy(prevstats, curstats, sizeof(prevstats)); - laststats = totalmillis - (totalmillis%statrate); - } - int nextstats[8] = - { - vtris*100/max(wtris, 1), - vverts*100/max(wverts, 1), - xtraverts/1024, - xtravertsva/1024, - glde, - gbatches, - getnumqueries(), - rplanes - }; - loopi(8) if(prevstats[i]==curstats[i]) curstats[i] = nextstats[i]; - - abovehud -= 2*FONTH; - draw_textf("wtr:%dk(%d%%) wvt:%dk(%d%%) evt:%dk eva:%dk", FONTH/2, abovehud, wtris/1024, curstats[0], wverts/1024, curstats[1], curstats[2], curstats[3]); - draw_textf("ond:%d va:%d gl:%d(%d) oq:%d lm:%d rp:%d", FONTH/2, abovehud+FONTH, allocnodes*8, allocva, curstats[4], curstats[5], curstats[6], lightmaps.length(), curstats[7]); - limitgui = abovehud; - } - - if(editmode) - { - abovehud -= FONTH; - draw_textf("cube %s%d%s", FONTH/2, abovehud, selchildcount<0 ? "1/" : "", abs(selchildcount), showmat && selchildmat > 0 ? getmaterialdesc(selchildmat, ": ") : ""); - - if(char *editinfo = execidentstr("edithud")) - { - if(editinfo[0]) - { - int tw, th; - text_bounds(editinfo, tw, th); - th += FONTH-1; th -= th%FONTH; - abovehud -= max(th, FONTH); - draw_text(editinfo, FONTH/2, abovehud); - } - DELETEA(editinfo); - } - } - else if(char *gameinfo = execidentstr("gamehud")) - { - if(gameinfo[0]) - { - int tw, th; - text_bounds(gameinfo, tw, th); - th += FONTH-1; th -= th%FONTH; - roffset += max(th, FONTH); - draw_text(gameinfo, conw-max(5*FONTH, 2*FONTH+tw), conh-FONTH/2-roffset); - } - DELETEA(gameinfo); - } - - pophudmatrix(); - } - - if(hidestats || (!editmode && !showeditstats)) - { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - game::gameplayhud(w, h); - limitgui = abovehud = min(abovehud, int(conh*game::abovegameplayhud(w, h))); - } - - rendertexturepanel(w, h); - } - - glDisable(GL_BLEND); - - g3d_limitscale((2*limitgui - conh) / float(conh)); - g3d_render2d(); - - glEnable(GL_BLEND); - - hudmatrix.ortho(0, w, h, 0, -1, 1); - resethudmatrix(); - - pushhudmatrix(); - hudmatrix.scale(conscale, conscale, 1); - flushhudmatrix(); - abovehud -= rendercommand(FONTH/2, abovehud - FONTH/2, conw-FONTH); - extern int fullconsole; - if(!hidehud || fullconsole) renderconsole(conw, conh, abovehud - FONTH/2); - pophudmatrix(); - - drawcrosshair(w, h); - - glDisable(GL_BLEND); + g3d_render(); + + int w = screenw, h = screenh; + if(forceaspect) w = int(ceil(h*forceaspect)); + + if(editmode && !hidehud && !mainmenu) + { + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + + renderblendbrush(); + + rendereditcursor(); + + glDepthMask(GL_TRUE); + glDisable(GL_DEPTH_TEST); + } + + gettextres(w, h); + + hudmatrix.ortho(0, w, h, 0, -1, 1); + resethudmatrix(); + + gle::colorf(1, 1, 1); + + glEnable(GL_BLEND); + + if(!mainmenu) + { + drawdamagecompass(w, h); + } + + hudshader->set(); + + int conw = int(w/conscale), conh = int(h/conscale), abovehud = conh - FONTH, limitgui = abovehud; + if(!hidehud && !mainmenu) + { + if(!hidestats) + { + pushhudmatrix(); + hudmatrix.scale(conscale, conscale, 1); + flushhudmatrix(); + + int roffset = 0; + if(showfps) + { + static int lastfps = 0, prevfps[3] = { 0, 0, 0 }, curfps[3] = { 0, 0, 0 }; + if(totalmillis - lastfps >= statrate) + { + memcpy(prevfps, curfps, sizeof(prevfps)); + lastfps = totalmillis - (totalmillis%statrate); + } + int nextfps[3]; + getfps(nextfps[0], nextfps[1], nextfps[2]); + loopi(3) if(prevfps[i]==curfps[i]) curfps[i] = nextfps[i]; + if(showfpsrange) draw_textf("fps %d+%d-%d", conw-7*FONTH, conh-FONTH*3/2, curfps[0], curfps[1], curfps[2]); + else draw_textf("fps %d", conw-5*FONTH, conh-FONTH*3/2, curfps[0]); + roffset += FONTH; + } + + if(editmode || showeditstats) + { + static int laststats = 0, prevstats[8] = { 0, 0, 0, 0, 0, 0, 0 }, curstats[8] = { 0, 0, 0, 0, 0, 0, 0 }; + if(totalmillis - laststats >= statrate) + { + memcpy(prevstats, curstats, sizeof(prevstats)); + laststats = totalmillis - (totalmillis%statrate); + } + int nextstats[8] = + { + vtris*100/max(wtris, 1), + vverts*100/max(wverts, 1), + xtraverts/1024, + xtravertsva/1024, + glde, + gbatches, + getnumqueries(), + rplanes + }; + loopi(8) if(prevstats[i]==curstats[i]) curstats[i] = nextstats[i]; + + abovehud -= 2*FONTH; + draw_textf("wtr:%dk(%d%%) wvt:%dk(%d%%) evt:%dk eva:%dk", FONTH/2, abovehud, wtris/1024, curstats[0], wverts/1024, curstats[1], curstats[2], curstats[3]); + draw_textf("ond:%d va:%d gl:%d(%d) oq:%d lm:%d rp:%d", FONTH/2, abovehud+FONTH, allocnodes*8, allocva, curstats[4], curstats[5], curstats[6], lightmaps.length(), curstats[7]); + limitgui = abovehud; + } + + if(editmode) + { + abovehud -= FONTH; + draw_textf("cube %s%d%s", FONTH/2, abovehud, selchildcount<0 ? "1/" : "", abs(selchildcount), showmat && selchildmat > 0 ? getmaterialdesc(selchildmat, ": ") : ""); + + if(char *editinfo = execidentstr("edithud")) + { + if(editinfo[0]) + { + int tw, th; + text_bounds(editinfo, tw, th); + th += FONTH-1; th -= th%FONTH; + abovehud -= max(th, FONTH); + draw_text(editinfo, FONTH/2, abovehud); + } + DELETEA(editinfo); + } + } + else if(char *gameinfo = execidentstr("gamehud")) + { + if(gameinfo[0]) + { + int tw, th; + text_bounds(gameinfo, tw, th); + th += FONTH-1; th -= th%FONTH; + roffset += max(th, FONTH); + draw_text(gameinfo, conw-max(5*FONTH, 2*FONTH+tw), conh-FONTH/2-roffset); + } + DELETEA(gameinfo); + } + + pophudmatrix(); + } + + if(hidestats || (!editmode && !showeditstats)) + { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + game::gameplayhud(w, h); + limitgui = abovehud = min(abovehud, int(conh*game::abovegameplayhud(w, h))); + } + + rendertexturepanel(w, h); + } + + glDisable(GL_BLEND); + + g3d_limitscale((2*limitgui - conh) / float(conh)); + g3d_render2d(); + + glEnable(GL_BLEND); + + hudmatrix.ortho(0, w, h, 0, -1, 1); + resethudmatrix(); + + pushhudmatrix(); + hudmatrix.scale(conscale, conscale, 1); + flushhudmatrix(); + abovehud -= rendercommand(FONTH/2, abovehud - FONTH/2, conw-FONTH); + extern int fullconsole; + if(!hidehud || fullconsole) renderconsole(conw, conh, abovehud - FONTH/2); + pophudmatrix(); + + drawcrosshair(w, h); + + glDisable(GL_BLEND); } void cleanupgl() { - cleanupmotionblur(); - - cleanupscreenquad(); + cleanupscreenquad(); - gle::cleanup(); + gle::cleanup(); } |
