From 737f5c35c460051be736c2f8055d3377a212cf77 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 9 Aug 2020 20:45:29 -0400 Subject: [PATCH] Merge r_opengl.c/h --- src/hardware/r_opengl/r_opengl.c | 2547 ++++++++---------------------- src/hardware/r_opengl/r_opengl.h | 24 +- 2 files changed, 635 insertions(+), 1936 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 4a0ee35f5..461966224 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1,29 +1,12 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2019 by Sonic Team Junior. +// Copyright (C) 1998-2020 by Sonic Team Junior. // -<<<<<<< HEAD // This program is free software distributed under the // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. -======= -// Copyright (C) 1998-2020 by Sonic Team Junior. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// ->>>>>>> srb2/next //----------------------------------------------------------------------------- -/// \file +/// \file r_opengl.c /// \brief OpenGL API for Sonic Robo Blast 2 #if defined (_WIN32) @@ -40,11 +23,6 @@ #include #include "r_opengl.h" #include "r_vbo.h" -<<<<<<< HEAD - -#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) -======= ->>>>>>> srb2/next #if defined (HWRENDER) && !defined (NOROPENGL) @@ -63,11 +41,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -<<<<<<< HEAD -#define NOTEXTURE_NUM 0 -======= static GLuint NOTEXTURE_NUM = 0; ->>>>>>> srb2/next #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) @@ -82,17 +56,10 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; -<<<<<<< HEAD -======= -#if 0 -static GLuint pal_col = 0; -static FRGBAFloat const_pal_col; -#endif ->>>>>>> srb2/next static FBITFIELD CurrentPolyFlags; -static FTextureInfo *gr_cachetail = NULL; -static FTextureInfo *gr_cachehead = NULL; +static FTextureInfo *gl_cachetail = NULL; +static FTextureInfo *gl_cachehead = NULL; RGBA_t myPaletteData[256]; GLint screen_width = 0; // used by Draw2DLine() @@ -104,37 +71,30 @@ static GLboolean MipMap = GL_FALSE; static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; -static boolean model_lighting = true; +static boolean model_lighting = false; const GLubyte *gl_version = NULL; const GLubyte *gl_renderer = NULL; const GLubyte *gl_extensions = NULL; //Hurdler: 04/10/2000: added for the kick ass coronas as Boris wanted;-) -<<<<<<< HEAD static GLfloat modelMatrix[16]; static GLfloat projMatrix[16]; -static GLint viewport[4]; - -#ifdef USE_PALETTED_TEXTURE - PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; - GLubyte palette_tex[256*3]; -#endif -======= -static GLfloat modelMatrix[16]; -static GLfloat projMatrix[16]; -static GLint viewport[4]; ->>>>>>> srb2/next +static GLint viewport[4]; // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // flush all of the stored textures, leaving them unavailable at times such as between levels -// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that Intel GPUs +// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // can know when the textures aren't there, as textures are always considered resident in their virtual memory static GLuint screentexture = 0; static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; static GLuint finalScreenTexture = 0; +// Lactozilla: Set shader programs and uniforms +static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); +static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); + // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { 0.000000f, 0.003922f, 0.007843f, 0.011765f, 0.015686f, 0.019608f, 0.023529f, 0.027451f, @@ -171,16 +131,6 @@ static const GLfloat byte2float[256] = { 0.972549f, 0.976471f, 0.980392f, 0.984314f, 0.988235f, 0.992157f, 0.996078f, 1.000000f }; -<<<<<<< HEAD -======= -float byteasfloat(UINT8 fbyte) -{ - return (float)(byte2float[fbyte]*2.0f); -} - -static I_Error_t I_Error_GL = NULL; - ->>>>>>> srb2/next // -----------------+ // GL_DBG_Printf : Output debug messages to debug log if DEBUG_TO_FILE is defined, // : else do nothing @@ -210,6 +160,56 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #endif } +// -----------------+ +// GL_MSG_Warning : Raises a warning. +// : +// Returns : +// -----------------+ + +static void GL_MSG_Warning(const char *format, ...) +{ + char str[4096] = ""; + va_list arglist; + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + +#ifdef HAVE_SDL + CONS_Alert(CONS_WARNING, "%s", str); +#endif +#ifdef DEBUG_TO_FILE + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + fwrite(str, strlen(str), 1, gllogstream); +#endif +} + +// -----------------+ +// GL_MSG_Error : Raises an error. +// : +// Returns : +// -----------------+ + +static void GL_MSG_Error(const char *format, ...) +{ + char str[4096] = ""; + va_list arglist; + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + +#ifdef HAVE_SDL + CONS_Alert(CONS_ERROR, "%s", str); +#endif +#ifdef DEBUG_TO_FILE + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + fwrite(str, strlen(str), 1, gllogstream); +#endif +} + #ifdef STATIC_OPENGL /* 1.0 functions */ /* Miscellaneous */ @@ -224,12 +224,9 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #define pglEnable glEnable #define pglDisable glDisable #define pglGetFloatv glGetFloatv -<<<<<<< HEAD -======= //glGetIntegerv //glGetString #define pglHint glHint ->>>>>>> srb2/next /* Depth Buffer */ #define pglClearDepth glClearDepth @@ -243,11 +240,7 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #define pglPushMatrix glPushMatrix #define pglPopMatrix glPopMatrix #define pglLoadIdentity glLoadIdentity -<<<<<<< HEAD -#define pglMultMatrixd glMultMatrixd -======= #define pglMultMatrixf glMultMatrixf ->>>>>>> srb2/next #define pglRotatef glRotatef #define pglScalef glScalef #define pglTranslatef glTranslatef @@ -257,22 +250,11 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #define pglVertexPointer glVertexPointer #define pglNormalPointer glNormalPointer #define pglTexCoordPointer glTexCoordPointer -<<<<<<< HEAD -======= #define pglColorPointer glColorPointer ->>>>>>> srb2/next #define pglDrawArrays glDrawArrays #define pglDrawElements glDrawElements #define pglEnableClientState glEnableClientState #define pglDisableClientState glDisableClientState -<<<<<<< HEAD -#define pglClientActiveTexture glClientActiveTexture -#define pglGenBuffers glGenBuffers -#define pglBindBuffer glBindBuffer -#define pglBufferData glBufferData -#define pglDeleteBuffers glDeleteBuffers -======= ->>>>>>> srb2/next /* Lighting */ #define pglShadeModel glShadeModel @@ -289,10 +271,7 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) #define pglTexEnvi glTexEnvi #define pglTexParameteri glTexParameteri #define pglTexImage2D glTexImage2D - -/* Fog */ -#define pglFogf glFogf -#define pglFogfv glFogfv +#define pglTexSubImage2D glTexSubImage2D /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object @@ -327,11 +306,6 @@ typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; typedef void (APIENTRY * PFNglGetFloatv) (GLenum pname, GLfloat *params); static PFNglGetFloatv pglGetFloatv; -<<<<<<< HEAD -======= -//glGetIntegerv -//glGetString ->>>>>>> srb2/next /* Depth Buffer */ typedef void (APIENTRY * PFNglClearDepth) (GLclampd depth); @@ -372,11 +346,8 @@ typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const static PFNglNormalPointer pglNormalPointer; typedef void (APIENTRY * PFNglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static PFNglTexCoordPointer pglTexCoordPointer; -<<<<<<< HEAD -======= typedef void (APIENTRY * PFNglColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); static PFNglColorPointer pglColorPointer; ->>>>>>> srb2/next typedef void (APIENTRY * PFNglDrawArrays) (GLenum mode, GLint first, GLsizei count); static PFNglDrawArrays pglDrawArrays; typedef void (APIENTRY * PFNglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); @@ -385,17 +356,6 @@ typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); static PFNglEnableClientState pglEnableClientState; typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap); static PFNglDisableClientState pglDisableClientState; -<<<<<<< HEAD -typedef void (APIENTRY * PFNglGenBuffers) (GLsizei n, GLuint *buffers); -static PFNglGenBuffers pglGenBuffers; -typedef void (APIENTRY * PFNglBindBuffer) (GLenum target, GLuint buffer); -static PFNglBindBuffer pglBindBuffer; -typedef void (APIENTRY * PFNglBufferData) (GLenum target, GLsizei size, const GLvoid *data, GLenum usage); -static PFNglBufferData pglBufferData; -typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); -static PFNglDeleteBuffers pglDeleteBuffers; -======= ->>>>>>> srb2/next /* Lighting */ typedef void (APIENTRY * PFNglShadeModel) (GLenum mode); @@ -422,12 +382,8 @@ typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint static PFNglTexParameteri pglTexParameteri; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; - -/* Fog */ -typedef void (APIENTRY * PFNglFogf) (GLenum pname, GLfloat param); -static PFNglFogf pglFogf; -typedef void (APIENTRY * PFNglFogfv) (GLenum pname, const GLfloat *params); -static PFNglFogfv pglFogfv; +typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static PFNglTexSubImage2D pglTexSubImage2D; /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object @@ -457,11 +413,6 @@ static PFNglMultiTexCoord2fv pglMultiTexCoord2fv; typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum); static PFNglClientActiveTexture pglClientActiveTexture; -<<<<<<< HEAD -// sky dome needs this -typedef void (APIENTRY *PFNglColorPointer) (GLint, GLenum, GLsizei, const GLvoid*); -static PFNglColorPointer pglColorPointer; -======= /* 1.5 functions for buffers */ typedef void (APIENTRY * PFNglGenBuffers) (GLsizei n, GLuint *buffers); static PFNglGenBuffers pglGenBuffers; @@ -472,7 +423,6 @@ static PFNglBufferData pglBufferData; typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); static PFNglDeleteBuffers pglDeleteBuffers; ->>>>>>> srb2/next /* 1.2 Parms */ /* GL_CLAMP_TO_EDGE_EXT */ @@ -494,8 +444,6 @@ static PFNglDeleteBuffers pglDeleteBuffers; #define GL_TEXTURE1 0x84C1 #endif -<<<<<<< HEAD -======= /* 1.5 Parms */ #ifndef GL_ARRAY_BUFFER #define GL_ARRAY_BUFFER 0x8892 @@ -504,7 +452,6 @@ static PFNglDeleteBuffers pglDeleteBuffers; #define GL_STATIC_DRAW 0x88E4 #endif ->>>>>>> srb2/next boolean SetupGLfunc(void) { #ifndef STATIC_OPENGL @@ -512,7 +459,7 @@ boolean SetupGLfunc(void) func = GetGLFunc(#proc); \ if (!func) \ { \ - GL_DBG_Printf("failed to get OpenGL function: %s\n", #proc); \ + GL_MSG_Warning("failed to get OpenGL function: %s", #proc); \ } \ GETOPENGLFUNC(pglClearColor, glClearColor) @@ -530,7 +477,6 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglGetIntegerv, glGetIntegerv) GETOPENGLFUNC(pglGetString, glGetString) -<<<<<<< HEAD GETOPENGLFUNC(pglClearDepth, glClearDepth) GETOPENGLFUNC(pglDepthFunc, glDepthFunc) GETOPENGLFUNC(pglDepthMask, glDepthMask) @@ -551,38 +497,13 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) -======= - GETOPENGLFUNC(pglClearDepth , glClearDepth) - GETOPENGLFUNC(pglDepthFunc , glDepthFunc) - GETOPENGLFUNC(pglDepthMask , glDepthMask) - GETOPENGLFUNC(pglDepthRange , glDepthRange) - - GETOPENGLFUNC(pglMatrixMode , glMatrixMode) - GETOPENGLFUNC(pglViewport , glViewport) - GETOPENGLFUNC(pglPushMatrix , glPushMatrix) - GETOPENGLFUNC(pglPopMatrix , glPopMatrix) - GETOPENGLFUNC(pglLoadIdentity , glLoadIdentity) - GETOPENGLFUNC(pglMultMatrixf , glMultMatrixf) - GETOPENGLFUNC(pglRotatef , glRotatef) - GETOPENGLFUNC(pglScalef , glScalef) - GETOPENGLFUNC(pglTranslatef , glTranslatef) - - GETOPENGLFUNC(pglColor4ubv, glColor4ubv) - GETOPENGLFUNC(pglVertexPointer, glVertexPointer) - GETOPENGLFUNC(pglNormalPointer, glNormalPointer) - GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) GETOPENGLFUNC(pglColorPointer, glColorPointer) ->>>>>>> srb2/next GETOPENGLFUNC(pglDrawArrays, glDrawArrays) GETOPENGLFUNC(pglDrawElements, glDrawElements) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) -<<<<<<< HEAD GETOPENGLFUNC(pglShadeModel, glShadeModel) -======= - GETOPENGLFUNC(pglShadeModel , glShadeModel) ->>>>>>> srb2/next GETOPENGLFUNC(pglLightfv, glLightfv) GETOPENGLFUNC(pglLightModelfv, glLightModelfv) GETOPENGLFUNC(pglMaterialfv, glMaterialfv) @@ -594,29 +515,24 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi, glTexEnvi) GETOPENGLFUNC(pglTexParameteri, glTexParameteri) GETOPENGLFUNC(pglTexImage2D, glTexImage2D) + GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D) - GETOPENGLFUNC(pglFogf, glFogf) - GETOPENGLFUNC(pglFogfv, glFogfv) - -<<<<<<< HEAD GETOPENGLFUNC(pglGenTextures, glGenTextures) GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) GETOPENGLFUNC(pglBindTexture, glBindTexture) -======= - GETOPENGLFUNC(pglGenTextures , glGenTextures) - GETOPENGLFUNC(pglDeleteTextures , glDeleteTextures) - GETOPENGLFUNC(pglBindTexture , glBindTexture) ->>>>>>> srb2/next GETOPENGLFUNC(pglCopyTexImage2D, glCopyTexImage2D) GETOPENGLFUNC(pglCopyTexSubImage2D, glCopyTexSubImage2D) #undef GETOPENGLFUNC + #endif return true; } -<<<<<<< HEAD +static boolean gl_allowshaders = false; +static boolean gl_shadersenabled = false; + #ifdef GL_SHADERS typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); @@ -666,14 +582,9 @@ static PFNglGetUniformLocation pglGetUniformLocation; // 18032019 static char *gl_customvertexshaders[MAXSHADERS]; static char *gl_customfragmentshaders[MAXSHADERS]; - -static boolean gl_allowshaders = false; -static boolean gl_shadersenabled = false; static GLuint gl_currentshaderprogram = 0; static boolean gl_shaderprogramchanged = true; -static boolean gl_batching = false;// are we currently collecting batches? - // 13062019 typedef enum { @@ -699,6 +610,9 @@ typedef struct gl_shaderprogram_s } gl_shaderprogram_t; static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; +// Shader info +static INT32 shader_leveltime = 0; + // ======================== // Fragment shader macros // ======================== @@ -764,6 +678,29 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; "gl_FragColor = final_color;\n" \ "}\0" +// same as above but multiplies results with the lighting value from the +// accompanying vertex shader (stored in gl_Color) +#define GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color *= gl_Color;\n" \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + // // Water surface shader // @@ -861,6 +798,9 @@ static const char *fragment_shaders[] = { "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" "}\0", + // Model fragment shader + diffuse lighting from above + GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER, + NULL, }; @@ -881,6 +821,20 @@ static const char *fragment_shaders[] = { "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ "}\0" +// replicates the way fixed function lighting is used by the model lighting option, +// stores the lighting result to gl_Color +// (ambient lighting of 0.75 and diffuse lighting from above) +#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \ + "void main()\n" \ + "{\n" \ + "float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \ + "float light = 0.75 + max(nDotVP, 0.0);\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_FrontColor = vec4(light, light, light, 1.0);\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "}\0" + static const char *vertex_shaders[] = { // Default vertex shader GLSL_DEFAULT_VERTEX_SHADER, @@ -906,6 +860,9 @@ static const char *vertex_shaders[] = { // Sky vertex shader GLSL_DEFAULT_VERTEX_SHADER, + // Model vertex shader + diffuse lighting from above + GLSL_MODEL_LIGHTING_VERTEX_SHADER, + NULL, }; @@ -913,22 +870,16 @@ static const char *vertex_shaders[] = { void SetupGLFunc4(void) { -======= -// This has to be done after the context is created so the version number can be obtained -// This is stupid -- even some of the oldest usable OpenGL hardware today supports 1.3-level featureset. -boolean SetupGLFunc13(void) -{ ->>>>>>> srb2/next pglActiveTexture = GetGLFunc("glActiveTexture"); pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); pglClientActiveTexture = GetGLFunc("glClientActiveTexture"); pglMultiTexCoord2fv = GetGLFunc("glMultiTexCoord2fv"); -<<<<<<< HEAD + + /* 1.5 funcs */ pglGenBuffers = GetGLFunc("glGenBuffers"); pglBindBuffer = GetGLFunc("glBindBuffer"); pglBufferData = GetGLFunc("glBufferData"); pglDeleteBuffers = GetGLFunc("glDeleteBuffers"); - pglColorPointer = GetGLFunc("glColorPointer"); #ifdef GL_SHADERS pglCreateShader = GetGLFunc("glCreateShader"); @@ -963,7 +914,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) #ifdef GL_SHADERS GLuint gl_vertShader, gl_fragShader; GLint i, result; - + if (!pglUseProgram) return false; gl_customvertexshaders[0] = NULL; @@ -987,12 +938,19 @@ EXPORT boolean HWRAPI(LoadShaders) (void) if (i >= MAXSHADERPROGRAMS) break; + shader = &gl_shaderprograms[i]; + shader->program = 0; + shader->custom = custom; + // // Load and compile vertex shader // gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) - I_Error("Hardware driver: Error creating vertex shader %d", i); + { + GL_MSG_Error("LoadShaders: Error creating vertex shader %d\n", i); + continue; + } pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); pglCompileShader(gl_vertShader); @@ -1009,7 +967,8 @@ EXPORT boolean HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); - I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog); + GL_MSG_Error("LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); + continue; } // @@ -1017,7 +976,10 @@ EXPORT boolean HWRAPI(LoadShaders) (void) // gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) - I_Error("Hardware driver: Error creating fragment shader %d", i); + { + GL_MSG_Error("LoadShaders: Error creating fragment shader %d\n", i); + continue; + } pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); pglCompileShader(gl_fragShader); @@ -1034,25 +996,31 @@ EXPORT boolean HWRAPI(LoadShaders) (void) infoLog = malloc(logLength); pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); - I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog); + GL_MSG_Error("LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); + continue; } - shader = &gl_shaderprograms[i]; shader->program = pglCreateProgram(); - shader->custom = custom; pglAttachShader(shader->program, gl_vertShader); pglAttachShader(shader->program, gl_fragShader); pglLinkProgram(shader->program); // check link status pglGetProgramiv(shader->program, GL_LINK_STATUS, &result); - if (result != GL_TRUE) - I_Error("Hardware driver: Error linking shader program %d", i); // delete the shader objects pglDeleteShader(gl_vertShader); pglDeleteShader(gl_fragShader); + // couldn't link? + if (result != GL_TRUE) + { + shader->program = 0; + shader->custom = false; + GL_MSG_Error("LoadShaders: Error linking shader program %d\n", i); + continue; + } + // 13062019 #define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform); @@ -1073,6 +1041,28 @@ EXPORT boolean HWRAPI(LoadShaders) (void) return true; } +// +// Shader info +// Those are given to the uniforms. +// + +EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value) +{ +#ifdef GL_SHADERS + switch (info) + { + case HWD_SHADERINFO_LEVELTIME: + shader_leveltime = value; + break; + default: + break; + } +#else + (void)info; + (void)value; +#endif +} + // // Custom shader loading // @@ -1095,14 +1085,19 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo strncpy(gl_customvertexshaders[number], shader, size); gl_customvertexshaders[number][size] = 0; } +#else + (void)number; + (void)shader; + (void)size; + (void)fragment; #endif } -EXPORT void HWRAPI(InitCustomShaders) (void) +EXPORT boolean HWRAPI(InitCustomShaders) (void) { #ifdef GL_SHADERS KillShaders(); - LoadShaders(); + return LoadShaders(); #endif } @@ -1111,16 +1106,23 @@ EXPORT void HWRAPI(SetShader) (int shader) #ifdef GL_SHADERS if (gl_allowshaders) { - gl_shadersenabled = true; + // If using model lighting, set the appropriate shader. + // However don't override a custom shader. + // Should use an enum or something... + if (shader == 4 && model_lighting && !gl_shaderprograms[4].custom) + shader = 8; if ((GLuint)shader != gl_currentshaderprogram) { gl_currentshaderprogram = shader; gl_shaderprogramchanged = true; } + gl_shadersenabled = true; + return; } - else +#else + (void)shader; #endif - gl_shadersenabled = false; + gl_shadersenabled = false; } EXPORT void HWRAPI(UnSetShader) (void) @@ -1128,7 +1130,6 @@ EXPORT void HWRAPI(UnSetShader) (void) #ifdef GL_SHADERS gl_shadersenabled = false; gl_currentshaderprogram = 0; - gl_shaderprogramchanged = true;// not sure if this is needed if (!pglUseProgram) return; pglUseProgram(0); #endif @@ -1137,16 +1138,6 @@ EXPORT void HWRAPI(UnSetShader) (void) EXPORT void HWRAPI(KillShaders) (void) { // unused......................... -======= - - /* 1.5 funcs */ - pglGenBuffers = GetGLFunc("glGenBuffers"); - pglBindBuffer = GetGLFunc("glBindBuffer"); - pglBufferData = GetGLFunc("glBufferData"); - pglDeleteBuffers = GetGLFunc("glDeleteBuffers"); - - return true; ->>>>>>> srb2/next } // -----------------+ @@ -1155,7 +1146,7 @@ EXPORT void HWRAPI(KillShaders) (void) static void SetNoTexture(void) { // Disable texture. - if (tex_downloaded != NOTEXTURE_NUM && !gl_batching) + if (tex_downloaded != NOTEXTURE_NUM) { if (NOTEXTURE_NUM == 0) pglGenTextures(1, &NOTEXTURE_NUM); @@ -1176,11 +1167,7 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) const GLfloat zNear = NEAR_CLIPPING_PLANE; const GLfloat zFar = FAR_CLIPPING_PLANE; const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f); -<<<<<<< HEAD const GLfloat sine = sin(radians); -======= - const GLfloat sine = sinf(radians); ->>>>>>> srb2/next const GLfloat deltaZ = zFar - zNear; GLfloat cotangent; @@ -1194,9 +1181,6 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) m[1][1] = cotangent; m[2][2] = -(zFar + zNear) / deltaZ; m[3][2] = -2.0f * zNear * zFar / deltaZ; -<<<<<<< HEAD - pglMultMatrixf(&m[0][0]); -======= pglMultMatrixf(&m[0][0]); } @@ -1239,7 +1223,6 @@ static void GLProject(GLfloat objX, GLfloat objY, GLfloat objZ, *winX=in[0]; *winY=in[1]; *winZ=in[2]; ->>>>>>> srb2/next } // -----------------+ @@ -1247,7 +1230,7 @@ static void GLProject(GLfloat objX, GLfloat objY, GLfloat objZ, // -----------------+ void SetModelView(GLint w, GLint h) { - //GL_DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); +// GL_DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // The screen textures need to be flushed if the width or height change so that they be remade for the correct size if (screen_width != w || screen_height != h) @@ -1257,9 +1240,6 @@ void SetModelView(GLint w, GLint h) screen_height = h; pglViewport(0, 0, w, h); -#ifdef GL_ACCUM_BUFFER_BIT - pglClear(GL_ACCUM_BUFFER_BIT); -#endif pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); @@ -1268,28 +1248,24 @@ void SetModelView(GLint w, GLint h) pglLoadIdentity(); GLPerspective(fov, ASPECT_RATIO); + //pglScalef(1.0f, 320.0f/200.0f, 1.0f); // gl_scalefrustum (ORIGINAL_ASPECT) // added for new coronas' code (without depth buffer) pglGetIntegerv(GL_VIEWPORT, viewport); pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); } + // -----------------+ // SetStates : Set permanent states // -----------------+ void SetStates(void) { -<<<<<<< HEAD - pglEnable(GL_TEXTURE_2D); // two-dimensional texturing - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - pglAlphaFunc(GL_NOTEQUAL, 0.0f); -======= #ifdef GL_LIGHT_MODEL_AMBIENT GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; #endif -// DBG_Printf("SetStates()\n"); +// GL_DBG_Printf("SetStates()\n"); // Hurdler: not necessary, is it? pglShadeModel(GL_SMOOTH); // iterate vertice colors @@ -1302,11 +1278,12 @@ void SetStates(void) pglAlphaFunc(GL_NOTEQUAL, 0.0f); //pglBlendFunc(GL_ONE, GL_ZERO); // copy pixel to frame buffer (opaque) ->>>>>>> srb2/next pglEnable(GL_BLEND); // enable color blending pglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + //pglDisable(GL_DITHER); // faB: ??? (undocumented in OpenGL 1.1) + // Hurdler: yes, it is! pglEnable(GL_DEPTH_TEST); // check the depth buffer pglDepthMask(GL_TRUE); // enable writing to depth buffer pglClearDepth(1.0f); @@ -1317,12 +1294,6 @@ void SetStates(void) CurrentPolyFlags = 0xffffffff; SetBlend(0); -<<<<<<< HEAD - //tex_downloaded = (GLuint)-1; - SetNoTexture(); - - pglPolygonOffset(-1.0f, -1.0f); -======= tex_downloaded = 0; SetNoTexture(); @@ -1331,17 +1302,13 @@ void SetStates(void) //pglEnable(GL_CULL_FACE); //pglCullFace(GL_FRONT); - //glFogi(GL_FOG_MODE, GL_EXP); - //pglHint(GL_FOG_HINT, GL_FASTEST); - //pglFogfv(GL_FOG_COLOR, fogcolor); - //pglFogf(GL_FOG_DENSITY, 0.0005f); + pglDisable(GL_FOG); // Lighting for models #ifdef GL_LIGHT_MODEL_AMBIENT pglLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightDiffuse); pglEnable(GL_LIGHT0); #endif ->>>>>>> srb2/next // bp : when no t&l :) pglLoadIdentity(); @@ -1349,27 +1316,23 @@ void SetStates(void) pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } + // -----------------+ // Flush : flush OpenGL textures // : Clear list of downloaded mipmaps // -----------------+ void Flush(void) { - //GL_DBG_Printf("HWR_Flush()\n"); + //GL_DBG_Printf ("HWR_Flush()\n"); - while (gr_cachehead) + while (gl_cachehead) { -<<<<<<< HEAD - // ceci n'est pas du tout necessaire vu que tu les a charger normalement et - // donc il sont dans ta liste ! -======= ->>>>>>> srb2/next - if (gr_cachehead->downloaded) - pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); - gr_cachehead->downloaded = 0; - gr_cachehead = gr_cachehead->nextmipmap; + if (gl_cachehead->downloaded) + pglDeleteTextures(1, (GLuint *)&gl_cachehead->downloaded); + gl_cachehead->downloaded = 0; + gl_cachehead = gl_cachehead->nextmipmap; } - gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL + gl_cachetail = gl_cachehead = NULL; //Hurdler: well, gl_cachehead is already NULL tex_downloaded = 0; } @@ -1418,6 +1381,7 @@ EXPORT boolean HWRAPI(Init) (void) // -----------------+ EXPORT void HWRAPI(ClearMipMapCache) (void) { + // GL_DBG_Printf ("HWR_Flush(exe)\n"); Flush(); } @@ -1431,7 +1395,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data) { INT32 i; - //GL_DBG_Printf("ReadRect()\n"); + // GL_DBG_Printf ("ReadRect()\n"); if (dst_stride == width*3) { GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1); @@ -1479,7 +1443,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, // -----------------+ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip) { - //GL_DBG_Printf("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); + // GL_DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); pglViewport(minx, screen_height-maxy, maxx-minx, maxy-miny); NEAR_CLIPPING_PLANE = nearclip; @@ -1503,7 +1467,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat * ClearColor) { - //GL_DBG_Printf("ClearBuffer(%d)\n", alpha); + // GL_DBG_Printf ("ClearBuffer(%d)\n", alpha); GLbitfield ClearMask = 0; if (ColorMask) @@ -1538,11 +1502,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, F2DCoord * v2, RGBA_t Color) { -<<<<<<< HEAD - //GL_DBG_Printf("DrawLine(): %f %f, %f %f\n", v1->x, v1->y, v2->x, v2->y); -======= - // DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); ->>>>>>> srb2/next + // GL_DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); GLfloat p[12]; GLfloat dx, dy; GLfloat angle; @@ -1623,7 +1583,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) // Sryder: Fog // multiplies input colour by input alpha, and destination colour by input colour, then adds them pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); - pglAlphaFunc(GL_NOTEQUAL, 0.0f); + pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments break; default : // must be 0, otherwise it's an error // No blending @@ -1647,10 +1607,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) else pglDisable(GL_POLYGON_OFFSET_FILL); } -<<<<<<< HEAD -======= ->>>>>>> srb2/next if (Xor&PF_NoDepthTest) { if (PolyFlags & PF_NoDepthTest) @@ -1687,19 +1644,22 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) } else #endif - - // mix texture colour with Surface->PolyColor if (PolyFlags & PF_Modulated) + { // mix texture colour with Surface->PolyColor pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - // colour from texture is unchanged before blending + } else + { // colour from texture is unchanged before blending pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } } if (Xor & PF_Occlude) // depth test but (no) depth write { if (PolyFlags&PF_Occlude) + { pglDepthMask(1); + } else pglDepthMask(0); } @@ -1717,11 +1677,214 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) } } if (PolyFlags & PF_NoTexture) + { SetNoTexture(); + } } CurrentPolyFlags = PolyFlags; } +// -----------------+ +// UpdateTexture : Updates the texture data. +// -----------------+ +EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) +{ + // Download a mipmap + boolean updatemipmap = true; + static RGBA_t tex[2048*2048]; + const GLvoid *ptex = tex; + INT32 w, h; + GLuint texnum = 0; + + if (!pTexInfo->downloaded) + { + pglGenTextures(1, &texnum); + pTexInfo->downloaded = texnum; + updatemipmap = false; + } + else + texnum = pTexInfo->downloaded; + + //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->data); + + w = pTexInfo->width; + h = pTexInfo->height; + + if ((pTexInfo->format == GL_TEXFMT_P_8) || + (pTexInfo->format == GL_TEXFMT_AP_88)) + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && + (pTexInfo->flags & TF_CHROMAKEYED)) + { + tex[w*j+i].s.red = 0; + tex[w*j+i].s.green = 0; + tex[w*j+i].s.blue = 0; + tex[w*j+i].s.alpha = 0; + pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it + } + else + { + tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; + tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; + tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; + tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; + } + + pImgData++; + + if (pTexInfo->format == GL_TEXFMT_AP_88) + { + if (!(pTexInfo->flags & TF_CHROMAKEYED)) + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + + } + } + } + else if (pTexInfo->format == GL_TEXFMT_RGBA) + { + // corona test : passed as ARGB 8888, which is not in glide formats + // Hurdler: not used for coronas anymore, just for dynamic lighting + ptex = pTexInfo->data; + } + else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + tex[w*j+i].s.red = *pImgData; + tex[w*j+i].s.green = *pImgData; + tex[w*j+i].s.blue = *pImgData; + pImgData++; + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + } + } + else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks + { + const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; + INT32 i, j; + + for (j = 0; j < h; j++) + { + for (i = 0; i < w; i++) + { + tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't + tex[w*j+i].s.green = 255; + tex[w*j+i].s.blue = 255; + tex[w*j+i].s.alpha = *pImgData; + pImgData++; + } + } + } + else + GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->format); + + // the texture number was already generated by pglGenTextures + pglBindTexture(GL_TEXTURE_2D, texnum); + tex_downloaded = texnum; + + // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues + if (pTexInfo->flags & TF_TRANSPARENT) + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + else + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + } + + if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) + { + //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); + //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) + { + //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); + //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + else + { + if (MipMap) + { + pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + // Control the mipmap level of detail + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail + if (pTexInfo->flags & TF_TRANSPARENT) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff + else + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); + } + else + { + if (updatemipmap) + pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + else + pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); + } + } + + if (pTexInfo->flags & TF_WRAPX) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + else + Clamp2D(GL_TEXTURE_WRAP_S); + + if (pTexInfo->flags & TF_WRAPY) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + else + Clamp2D(GL_TEXTURE_WRAP_T); + + if (maximumAnisotropy) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter); +} // -----------------+ // SetTexture : The mipmap becomes the current texture source @@ -1737,312 +1900,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) { if (pTexInfo->downloaded != tex_downloaded) { - if (!gl_batching) - pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); + pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); tex_downloaded = pTexInfo->downloaded; } } else { - // Download a mipmap - static RGBA_t tex[2048*2048]; - const GLvoid *ptex = tex; - INT32 w, h; - GLuint texnum = 0; - - pglGenTextures(1, &texnum); -<<<<<<< HEAD - //GL_DBG_Printf("DownloadMipmap %d\n", (INT32)texnum, pTexInfo->grInfo.data); -======= - //DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->grInfo.data); ->>>>>>> srb2/next - - w = pTexInfo->width; - h = pTexInfo->height; - -<<<<<<< HEAD -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - // do nothing here. - // Not a problem with MiniGL since we don't use paletted texture - } - else -#endif - -======= ->>>>>>> srb2/next - if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || - (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; -<<<<<<< HEAD - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && - (pTexInfo->flags & TF_CHROMAKEYED)) - { - tex[w*j+i].s.red = 0; - tex[w*j+i].s.green = 0; - tex[w*j+i].s.blue = 0; - tex[w*j+i].s.alpha = 0; - pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it - } - else - { - tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; - tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; - tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; - tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; - } - - pImgData++; - - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) - { - if (!(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - - } - } - } - else if (pTexInfo->grInfo.format == GR_RGBA) - { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - ptex = pTexInfo->grInfo.data; - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = *pImgData; - tex[w*j+i].s.green = *pImgData; - tex[w*j+i].s.blue = *pImgData; - pImgData++; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't - tex[w*j+i].s.green = 255; - tex[w*j+i].s.blue = 255; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else - GL_DBG_Printf("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); - -======= - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - if ((*pImgData == HWR_PATCHES_CHROMAKEY_COLORINDEX) && - (pTexInfo->flags & TF_CHROMAKEYED)) - { - tex[w*j+i].s.red = 0; - tex[w*j+i].s.green = 0; - tex[w*j+i].s.blue = 0; - tex[w*j+i].s.alpha = 0; - pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it - } - else - { - tex[w*j+i].s.red = myPaletteData[*pImgData].s.red; - tex[w*j+i].s.green = myPaletteData[*pImgData].s.green; - tex[w*j+i].s.blue = myPaletteData[*pImgData].s.blue; - tex[w*j+i].s.alpha = myPaletteData[*pImgData].s.alpha; - } - - pImgData++; - - if (pTexInfo->grInfo.format == GR_TEXFMT_AP_88) - { - if (!(pTexInfo->flags & TF_CHROMAKEYED)) - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - - } - } - } - else if (pTexInfo->grInfo.format == GR_RGBA) - { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - ptex = pTexInfo->grInfo.data; - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = *pImgData; - tex[w*j+i].s.green = *pImgData; - tex[w*j+i].s.blue = *pImgData; - pImgData++; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) // Used for fade masks - { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->grInfo.data; - INT32 i, j; - - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) - { - tex[w*j+i].s.red = 255; // 255 because the fade mask is modulated with the screen texture, so alpha affects it while the colours don't - tex[w*j+i].s.green = 255; - tex[w*j+i].s.blue = 255; - tex[w*j+i].s.alpha = *pImgData; - pImgData++; - } - } - } - else - DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); - ->>>>>>> srb2/next - // the texture number was already generated by pglGenTextures - pglBindTexture(GL_TEXTURE_2D, texnum); - pTexInfo->downloaded = texnum; - tex_downloaded = texnum; - - // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues - if (pTexInfo->flags & TF_TRANSPARENT) - { - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - else - { - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - } - -<<<<<<< HEAD -#ifdef USE_PALETTED_TEXTURE - //Hurdler: not really supported and not tested recently - if (glColorTableEXT && - (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && - !(pTexInfo->flags & TF_CHROMAKEYED)) - { - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, w, h, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, pTexInfo->grInfo.data); - } - else -#endif -======= ->>>>>>> srb2/next - if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) - { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - else if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_8) - { - //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, GL_ALPHA, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); - //pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR_MIPMAP_LINEAR); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - else - { - if (MipMap) - { - pgluBuild2DMipmaps(GL_TEXTURE_2D, textureformatGL, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - // Control the mipmap level of detail - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0); // the lower the number, the higer the detail - if (pTexInfo->flags & TF_TRANSPARENT) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 0); // No mippmaps on transparent stuff - else - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 5); - } - else - pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); - } - - if (pTexInfo->flags & TF_WRAPX) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - else - Clamp2D(GL_TEXTURE_WRAP_S); - - if (pTexInfo->flags & TF_WRAPY) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - else - Clamp2D(GL_TEXTURE_WRAP_T); - - if (maximumAnisotropy) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter); - + UpdateTexture(pTexInfo); pTexInfo->nextmipmap = NULL; - if (gr_cachetail) + if (gl_cachetail) { // insertion at the tail - gr_cachetail->nextmipmap = pTexInfo; - gr_cachetail = pTexInfo; + gl_cachetail->nextmipmap = pTexInfo; + gl_cachetail = pTexInfo; } else // initialization of the linked list - gr_cachetail = gr_cachehead = pTexInfo; + gl_cachetail = gl_cachehead = pTexInfo; } -<<<<<<< HEAD } -static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) +static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) { #ifdef GL_SHADERS if (gl_shadersenabled && pglUseProgram) @@ -2050,751 +1926,124 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat * gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; if (shader->program) { - boolean custom = (gl_shaderprograms[gl_currentshaderprogram].custom); - // 13062019 - // Check for fog - //if (changed) + if (gl_shaderprogramchanged) { - if (!custom) - { - if (gl_shaderprogramchanged) - { - pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); - gl_shaderprogramchanged = false; - } - } - else // always load custom shaders - { - if (gl_shaderprogramchanged) - { - pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); - gl_shaderprogramchanged = false; - } - } - } - - // set uniforms - { - #define UNIFORM_1(uniform, a, function) \ - if (uniform != -1) \ - function (uniform, a); - - #define UNIFORM_2(uniform, a, b, function) \ - if (uniform != -1) \ - function (uniform, a, b); - - #define UNIFORM_3(uniform, a, b, c, function) \ - if (uniform != -1) \ - function (uniform, a, b, c); - - #define UNIFORM_4(uniform, a, b, c, d, function) \ - if (uniform != -1) \ - function (uniform, a, b, c, d); - - // polygon - UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); - UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); - UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); - UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); - UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)leveltime) / TICRATE, pglUniform1f); - - #undef UNIFORM_1 - #undef UNIFORM_2 - #undef UNIFORM_3 - #undef UNIFORM_4 + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + gl_shaderprogramchanged = false; } + Shader_SetUniforms(Surface, poly, tint, fade); + return shader; } else pglUseProgram(0); } +#else + (void)Surface; + (void)poly; + (void)tint; + (void)fade; #endif -======= ->>>>>>> srb2/next + return NULL; } -// unfinished draw call batching - -// Note: could use realloc in the array reallocation code - -typedef struct +static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) { - FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused - unsigned int vertsIndex;// location of verts in unsortedVertexArray - FUINT numVerts; - FBITFIELD polyFlags; - GLuint texNum; - GLuint shader; -} PolygonArrayEntry; - -FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu -UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion -// NOTE have this alloced as 3x finalVertexArray size -int finalVertexArrayAllocSize = 65536; -//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed -//int colorArrayAllocSize = 65536; -// not gonna use this for now, just sort by color and change state when it changes -// later maybe when using vertex attributes if it's needed - -PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed -int polygonArraySize = 0; -unsigned int* polygonIndexArray = NULL;// contains sorting pointers for polygonArray -int polygonArrayAllocSize = 65536; - -FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon -int unsortedVertexArraySize = 0; -int unsortedVertexArrayAllocSize = 65536; - -EXPORT void HWRAPI(StartBatching) (void) -{ - //CONS_Printf("StartBatching begin\n"); - // init arrays if that has not been done yet - if (!finalVertexArray) +#ifdef GL_SHADERS + if (gl_shadersenabled) { - finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); - finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); - polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); - polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); - unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); + gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; + if (!shader->program) + return; + + #define UNIFORM_1(uniform, a, function) \ + if (uniform != -1) \ + function (uniform, a); + + #define UNIFORM_2(uniform, a, b, function) \ + if (uniform != -1) \ + function (uniform, a, b); + + #define UNIFORM_3(uniform, a, b, c, function) \ + if (uniform != -1) \ + function (uniform, a, b, c); + + #define UNIFORM_4(uniform, a, b, c, d, function) \ + if (uniform != -1) \ + function (uniform, a, b, c, d); + + // polygon + UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); + if (Surface != NULL) + { + UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); + } + UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f); + + #undef UNIFORM_1 + #undef UNIFORM_2 + #undef UNIFORM_3 + #undef UNIFORM_4 } - // drawing functions will now collect the drawing data instead of passing it to opengl - gl_batching = true; - //CONS_Printf("StartBatching end\n"); +#else + (void)Surface; + (void)poly; + (void)tint; + (void)fade; +#endif } -static int comparePolygons(const void *p1, const void *p2) +// code that is common between DrawPolygon and DrawIndexedTriangles +// the corona thing is there too, i have no idea if that stuff works with DrawIndexedTriangles and batching +static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD PolyFlags) { - PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; - PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; - int diff; - INT64 diff64; - - int shader1 = poly1->shader; - int shader2 = poly2->shader; - // make skywalls first in order - if (poly1->polyFlags & PF_NoTexture) - shader1 = -1; - if (poly2->polyFlags & PF_NoTexture) - shader2 = -1; - diff = shader1 - shader2; - if (diff != 0) return diff; - - diff = poly1->texNum - poly2->texNum; - if (diff != 0) return diff; - - diff = poly1->polyFlags - poly2->polyFlags; - if (diff != 0) return diff; - - diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; - if (diff64 < 0) return -1; else if (diff64 > 0) return 1; - diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba; - if (diff64 < 0) return -1; else if (diff64 > 0) return 1; - diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba; - if (diff64 < 0) return -1; else if (diff64 > 0) return 1; - - diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level; - if (diff != 0) return diff; - diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start; - if (diff != 0) return diff; - diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end; - return diff; -} - -static int comparePolygonsNoShaders(const void *p1, const void *p2) -{ - PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; - PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; - int diff; - INT64 diff64; - - GLuint texNum1 = poly1->texNum; - GLuint texNum2 = poly2->texNum; - if (poly1->polyFlags & PF_NoTexture) - texNum1 = 0; - if (poly2->polyFlags & PF_NoTexture) - texNum2 = 0; - diff = texNum1 - texNum2; - if (diff != 0) return diff; - - diff = poly1->polyFlags - poly2->polyFlags; - if (diff != 0) return diff; - - diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; - if (diff64 < 0) return -1; else if (diff64 > 0) return 1; - - return 0; -} - -// the parameters for this functions (numPolys etc.) are used to return rendering stats -EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCalls, int *sNumShaders, int *sNumTextures, int *sNumPolyFlags, int *sNumColors) -{ - int finalVertexWritePos = 0;// position in finalVertexArray - int finalIndexWritePos = 0;// position in finalVertexIndexArray - - int polygonReadPos = 0;// position in polygonIndexArray - - GLuint currentShader; - GLuint currentTexture; - FBITFIELD currentPolyFlags; - FSurfaceInfo currentSurfaceInfo; - - GLRGBAFloat firstPoly = {0,0,0,0}; // may be misleading but this means first PolyColor - GLRGBAFloat firstTint = {0,0,0,0}; - GLRGBAFloat firstFade = {0,0,0,0}; - - boolean needRebind = false; - - int i; - - //CONS_Printf("RenderBatches\n"); - gl_batching = false;// no longer collecting batches - if (!polygonArraySize) - { - *sNumPolys = *sNumCalls = *sNumShaders = *sNumTextures = *sNumPolyFlags = *sNumColors = 0; - return;// nothing to draw - } - // init stats vars - *sNumPolys = polygonArraySize; - *sNumCalls = *sNumVerts = 0; - *sNumShaders = *sNumTextures = *sNumPolyFlags = *sNumColors = 1; - // init polygonIndexArray - for (i = 0; i < polygonArraySize; i++) - { - polygonIndexArray[i] = i; - } - - // sort polygons - //CONS_Printf("qsort polys\n"); - //*sSortTime = I_GetTimeMicros(); - if (gl_allowshaders) - qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); - else - qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); - //*sSortTime = I_GetTimeMicros() - *sSortTime; - //CONS_Printf("sort done\n"); - // sort order - // 1. shader - // 2. texture - // 3. polyflags - // 4. colors + light level - // not sure about order of last 2, or if it even matters - - //*sDrawTime = I_GetTimeMicros(); - - currentShader = polygonArray[polygonIndexArray[0]].shader; - currentTexture = polygonArray[polygonIndexArray[0]].texNum; - currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags; - currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf; - // For now, will sort and track the colors. Vertex attributes could be used instead of uniforms - // and a color array could replace the color calls. - - // set state for first batch - //CONS_Printf("set first state\n"); - gl_currentshaderprogram = currentShader; - gl_shaderprogramchanged = true; - if (currentPolyFlags & PF_Modulated) - { - // Poly color - firstPoly.red = byte2float[currentSurfaceInfo.PolyColor.s.red]; - firstPoly.green = byte2float[currentSurfaceInfo.PolyColor.s.green]; - firstPoly.blue = byte2float[currentSurfaceInfo.PolyColor.s.blue]; - firstPoly.alpha = byte2float[currentSurfaceInfo.PolyColor.s.alpha]; - pglColor4ubv((GLubyte*)¤tSurfaceInfo.PolyColor.s); - } - // Tint color - firstTint.red = byte2float[currentSurfaceInfo.TintColor.s.red]; - firstTint.green = byte2float[currentSurfaceInfo.TintColor.s.green]; - firstTint.blue = byte2float[currentSurfaceInfo.TintColor.s.blue]; - firstTint.alpha = byte2float[currentSurfaceInfo.TintColor.s.alpha]; - // Fade color - firstFade.red = byte2float[currentSurfaceInfo.FadeColor.s.red]; - firstFade.green = byte2float[currentSurfaceInfo.FadeColor.s.green]; - firstFade.blue = byte2float[currentSurfaceInfo.FadeColor.s.blue]; - firstFade.alpha = byte2float[currentSurfaceInfo.FadeColor.s.alpha]; - - if (gl_allowshaders) - load_shaders(¤tSurfaceInfo, &firstPoly, &firstTint, &firstFade); - - if (currentPolyFlags & PF_NoTexture) - currentTexture = 0; - pglBindTexture(GL_TEXTURE_2D, currentTexture); - tex_downloaded = currentTexture; - - SetBlend(currentPolyFlags); - - //CONS_Printf("first pointers to ogl\n"); - pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].s); - - while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) - { - int firstIndex; - int lastIndex; - - boolean stopFlag = false; - boolean changeState = false; - boolean changeShader = false; - GLuint nextShader; - boolean changeTexture = false; - GLuint nextTexture; - boolean changePolyFlags = false; - FBITFIELD nextPolyFlags; - boolean changeSurfaceInfo = false; - FSurfaceInfo nextSurfaceInfo; - - //CONS_Printf("loop iter start\n"); - // new try: - // write vertices - // check for changes or end, otherwise go back to writing - // changes will affect the next vars and the change bools - // end could set flag for stopping - // execute draw call - // could check ending flag here - // change states according to next vars and change bools, updating the current vars and reseting the bools - // reset write pos - // repeat loop - - int index = polygonIndexArray[polygonReadPos++]; - int numVerts = polygonArray[index].numVerts; - // before writing, check if there is enough room - // using 'while' instead of 'if' here makes sure that there will *always* be enough room. - // probably never will this loop run more than once though - while (finalVertexWritePos + numVerts > finalVertexArrayAllocSize) - { - FOutVector* new_array; - unsigned int* new_index_array; - //CONS_Printf("final vert realloc\n"); - finalVertexArrayAllocSize *= 2; - new_array = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); - memcpy(new_array, finalVertexArray, finalVertexWritePos * sizeof(FOutVector)); - free(finalVertexArray); - finalVertexArray = new_array; - // also increase size of index array, 3x of vertex array since - // going from fans to triangles increases vertex count to 3x - new_index_array = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); - memcpy(new_index_array, finalVertexIndexArray, finalIndexWritePos * sizeof(UINT32)); - free(finalVertexIndexArray); - finalVertexIndexArray = new_index_array; - // if vertex buffers are reallocated then opengl needs to know too - needRebind = true; - } - //CONS_Printf("write verts to final\n"); - // write the vertices of the polygon - memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex], - numVerts * sizeof(FOutVector)); - // write the indexes, pointing to the fan vertexes but in triangles format - firstIndex = finalVertexWritePos; - lastIndex = finalVertexWritePos + numVerts; - finalVertexWritePos += 2; - //CONS_Printf("write final vert indices\n"); - while (finalVertexWritePos < lastIndex) - { - finalVertexIndexArray[finalIndexWritePos++] = firstIndex; - finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1; - finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++; - } - - if (polygonReadPos >= polygonArraySize) - { - stopFlag = true; - } - else - { - //CONS_Printf("state change check\n"); - // check if a state change is required, set the change bools and next vars - int nextIndex = polygonIndexArray[polygonReadPos]; - nextShader = polygonArray[nextIndex].shader; - nextTexture = polygonArray[nextIndex].texNum; - nextPolyFlags = polygonArray[nextIndex].polyFlags; - nextSurfaceInfo = polygonArray[nextIndex].surf; - if (nextPolyFlags & PF_NoTexture) - nextTexture = 0; - if (currentShader != nextShader) - { - changeState = true; - changeShader = true; - } - if (currentTexture != nextTexture) - { - changeState = true; - changeTexture = true; - } - if (currentPolyFlags != nextPolyFlags) - { - changeState = true; - changePolyFlags = true; - } - if (gl_allowshaders) - { - if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba || - currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba || - currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba || - currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level || - currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start || - currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end) - { - changeState = true; - changeSurfaceInfo = true; - } - } - else - { - if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba) - { - changeState = true; - changeSurfaceInfo = true; - } - } - } - - if (changeState || stopFlag) - { - if (needRebind) - { - //CONS_Printf("rebind\n"); - pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].s); - needRebind = false; - } - //CONS_Printf("exec draw call\n"); - // execute draw call - pglDrawElements(GL_TRIANGLES, finalIndexWritePos, GL_UNSIGNED_INT, finalVertexIndexArray); - //CONS_Printf("draw call done\n"); - // update stats - (*sNumCalls)++; - *sNumVerts += finalIndexWritePos; - // reset write positions - finalVertexWritePos = 0; - finalIndexWritePos = 0; - } - else continue; - - // if we're here then either its time to stop or time to change state - if (stopFlag) break; - - //CONS_Printf("state change\n"); - - // change state according to change bools and next vars, update current vars and reset bools - if (changeShader) - { - GLRGBAFloat poly = {0,0,0,0}; - GLRGBAFloat tint = {0,0,0,0}; - GLRGBAFloat fade = {0,0,0,0}; - gl_currentshaderprogram = nextShader; - gl_shaderprogramchanged = true; - if (nextPolyFlags & PF_Modulated) - { - // Poly color - poly.red = byte2float[nextSurfaceInfo.PolyColor.s.red]; - poly.green = byte2float[nextSurfaceInfo.PolyColor.s.green]; - poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue]; - poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha]; - } - // Tint color - tint.red = byte2float[nextSurfaceInfo.TintColor.s.red]; - tint.green = byte2float[nextSurfaceInfo.TintColor.s.green]; - tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue]; - tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha]; - // Fade color - fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red]; - fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green]; - fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue]; - fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha]; - - load_shaders(&nextSurfaceInfo, &poly, &tint, &fade); - currentShader = nextShader; - changeShader = false; - - (*sNumShaders)++; - } - if (changeTexture) - { - // texture should be already ready for use from calls to SetTexture during batch collection - pglBindTexture(GL_TEXTURE_2D, nextTexture); - tex_downloaded = nextTexture; - currentTexture = nextTexture; - changeTexture = false; - - (*sNumTextures)++; - } - if (changePolyFlags) - { - SetBlend(nextPolyFlags); - currentPolyFlags = nextPolyFlags; - changePolyFlags = false; - - (*sNumPolyFlags)++; - } - if (changeSurfaceInfo) - { - GLRGBAFloat poly = {0,0,0,0}; - GLRGBAFloat tint = {0,0,0,0}; - GLRGBAFloat fade = {0,0,0,0}; - gl_shaderprogramchanged = false; - if (nextPolyFlags & PF_Modulated) - { - // Poly color - poly.red = byte2float[nextSurfaceInfo.PolyColor.s.red]; - poly.green = byte2float[nextSurfaceInfo.PolyColor.s.green]; - poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue]; - poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha]; - pglColor4ubv((GLubyte*)&nextSurfaceInfo.PolyColor.s); - } - if (gl_allowshaders) - { - // Tint color - tint.red = byte2float[nextSurfaceInfo.TintColor.s.red]; - tint.green = byte2float[nextSurfaceInfo.TintColor.s.green]; - tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue]; - tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha]; - // Fade color - fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red]; - fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green]; - fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue]; - fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha]; - - load_shaders(&nextSurfaceInfo, &poly, &tint, &fade); - } - currentSurfaceInfo = nextSurfaceInfo; - changeSurfaceInfo = false; - - (*sNumColors)++; - } - // and that should be it? - } - // reset the arrays (set sizes to 0) - polygonArraySize = 0; - unsortedVertexArraySize = 0; - - //*sDrawTime = I_GetTimeMicros() - *sDrawTime; -} - -// -----------------+ -// DrawPolygon : Render a polygon, set the texture, set render mode -// -----------------+ -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) -{ -<<<<<<< HEAD - if (gl_batching) - { - //CONS_Printf("Batched DrawPolygon\n"); - if (!pSurf) - I_Error("Got a null FSurfaceInfo in batching");// nulls should only come in sky background pic drawing - if (polygonArraySize == polygonArrayAllocSize) - { - PolygonArrayEntry* new_array; - // ran out of space, make new array double the size - polygonArrayAllocSize *= 2; - new_array = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); - memcpy(new_array, polygonArray, polygonArraySize * sizeof(PolygonArrayEntry)); - free(polygonArray); - polygonArray = new_array; - // also need to redo the index array, dont need to copy it though - free(polygonIndexArray); - polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); - } - - while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize) - { - FOutVector* new_array; - // need more space for vertices in unsortedVertexArray - unsortedVertexArrayAllocSize *= 2; - new_array = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); - memcpy(new_array, unsortedVertexArray, unsortedVertexArraySize * sizeof(FOutVector)); - free(unsortedVertexArray); - unsortedVertexArray = new_array; - } -======= - FUINT i; - FUINT j; + static GLRGBAFloat poly = {0,0,0,0}; + static GLRGBAFloat tint = {0,0,0,0}; + static GLRGBAFloat fade = {0,0,0,0}; if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD)) PolyFlags &= ~(PF_NoDepthTest|PF_Corona); ->>>>>>> srb2/next - // add the polygon data to the arrays + SetBlend(PolyFlags); //TODO: inline (#pragma..) -<<<<<<< HEAD - polygonArray[polygonArraySize].surf = *pSurf; - polygonArray[polygonArraySize].vertsIndex = unsortedVertexArraySize; - polygonArray[polygonArraySize].numVerts = iNumPts; - polygonArray[polygonArraySize].polyFlags = PolyFlags; - polygonArray[polygonArraySize].texNum = tex_downloaded; - polygonArray[polygonArraySize].shader = gl_currentshaderprogram; - polygonArraySize++; - - memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector)); - unsortedVertexArraySize += iNumPts; - } - else + // PolyColor + if (pSurf) { - static GLRGBAFloat poly = {0,0,0,0}; - static GLRGBAFloat tint = {0,0,0,0}; - static GLRGBAFloat fade = {0,0,0,0}; - - SetBlend(PolyFlags); //TODO: inline (#pragma..) - - // PolyColor - if (pSurf) + // If Modulated, mix the surface colour to the texture + if (CurrentPolyFlags & PF_Modulated) { - // If Modulated, mix the surface colour to the texture - if (CurrentPolyFlags & PF_Modulated) - { - // Poly color - poly.red = byte2float[pSurf->PolyColor.s.red]; - poly.green = byte2float[pSurf->PolyColor.s.green]; - poly.blue = byte2float[pSurf->PolyColor.s.blue]; - poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; + // Poly color + poly.red = byte2float[pSurf->PolyColor.s.red]; + poly.green = byte2float[pSurf->PolyColor.s.green]; + poly.blue = byte2float[pSurf->PolyColor.s.blue]; + poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; - pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); - } - - // Tint color - tint.red = byte2float[pSurf->TintColor.s.red]; - tint.green = byte2float[pSurf->TintColor.s.green]; - tint.blue = byte2float[pSurf->TintColor.s.blue]; - tint.alpha = byte2float[pSurf->TintColor.s.alpha]; - - // Fade color - fade.red = byte2float[pSurf->FadeColor.s.red]; - fade.green = byte2float[pSurf->FadeColor.s.green]; - fade.blue = byte2float[pSurf->FadeColor.s.blue]; - fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; + pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); } - load_shaders(pSurf, &poly, &tint, &fade); + // Tint color + tint.red = byte2float[pSurf->TintColor.s.red]; + tint.green = byte2float[pSurf->TintColor.s.green]; + tint.blue = byte2float[pSurf->TintColor.s.blue]; + tint.alpha = byte2float[pSurf->TintColor.s.alpha]; - pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); - - if (PolyFlags & PF_RemoveYWrap) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - if (PolyFlags & PF_ForceWrapX) - Clamp2D(GL_TEXTURE_WRAP_S); - - if (PolyFlags & PF_ForceWrapY) - Clamp2D(GL_TEXTURE_WRAP_T); + // Fade color + fade.red = byte2float[pSurf->FadeColor.s.red]; + fade.green = byte2float[pSurf->FadeColor.s.green]; + fade.blue = byte2float[pSurf->FadeColor.s.blue]; + fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; } -} - -// Sky dome code, taken/backported from SRB2 - -typedef struct vbo_vertex_s -{ - float x, y, z; - float u, v; - unsigned char r, g, b, a; -} vbo_vertex_t; - -typedef struct -{ - int mode; - int vertexcount; - int vertexindex; - int use_texture; -} GLSkyLoopDef; - -typedef struct -{ - unsigned int id; - int rows, columns; - int loopcount; - GLSkyLoopDef *loops; - vbo_vertex_t *data; -} GLSkyVBO; - -static const boolean gl_ext_arb_vertex_buffer_object = true; - -#define NULL_VBO_VERTEX ((vbo_vertex_t*)NULL) -#define sky_vbo_x (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->x : &vbo->data[0].x) -#define sky_vbo_u (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->u : &vbo->data[0].u) -#define sky_vbo_r (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->r : &vbo->data[0].r) - -// The texture offset to be applied to the texture coordinates in SkyVertex(). -static int rows, columns; -static signed char yflip; -static int texw, texh; -static boolean foglayer; -static float delta = 0.0f; - -static int gl_sky_detail = 16; - -static INT32 lasttex = -1; - -#define MAP_COEFF 128.0f - -static void SkyVertex(vbo_vertex_t *vbo, int r, int c) -{ - const float radians = (float)(M_PIl / 180.0f); - const float scale = 10000.0f; - const float maxSideAngle = 60.0f; - - float topAngle = (c / (float)columns * 360.0f); - float sideAngle = (maxSideAngle * (rows - r) / rows); - float height = (float)(sin(sideAngle * radians)); - float realRadius = (float)(scale * cos(sideAngle * radians)); - float x = (float)(realRadius * cos(topAngle * radians)); - float y = (!yflip) ? scale * height : -scale * height; - float z = (float)(realRadius * sin(topAngle * radians)); - float timesRepeat = (4 * (256.0f / texw)); - if (fpclassify(timesRepeat) == FP_ZERO) - timesRepeat = 1.0f; - - if (!foglayer) - { - vbo->r = 255; - vbo->g = 255; - vbo->b = 255; - vbo->a = (r == 0 ? 0 : 255); - - // And the texture coordinates. - //vbo->u = (-timesRepeat * c / (float)columns); - vbo->u = (timesRepeat * c / (float)columns);// TEST - if (!yflip) // Flipped Y is for the lower hemisphere. - vbo->v = (r / (float)rows) + 0.5f; - else - vbo->v = 1.0f + ((rows - r) / (float)rows) + 0.5f; - } - - if (r != 4) - { - y += 300.0f; - } - - // And finally the vertex. - vbo->x = x; - vbo->y = y + delta; - vbo->z = z; -} - -static GLSkyVBO sky_vbo; - -static void gld_BuildSky(int row_count, int col_count) -{ - int c, r; - vbo_vertex_t *vertex_p; - int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2; - - GLSkyVBO *vbo = &sky_vbo; - - if ((vbo->columns != col_count) || (vbo->rows != row_count)) - { - free(vbo->loops); - free(vbo->data); - memset(vbo, 0, sizeof(&vbo)); - } -======= - // If Modulated, mix the surface colour to the texture - if ((CurrentPolyFlags & PF_Modulated) && pSurf) - pglColor4ubv((GLubyte*)&pSurf->FlatColor.s); // this test is added for new coronas' code (without depth buffer) // I think I should do a separate function for drawing coronas, so it will be a little faster if (PolyFlags & PF_Corona) // check to see if we need to draw the corona { + FUINT i; + FUINT j; + //rem: all 8 (or 8.0f) values are hard coded: it can be changed to a higher value GLfloat buf[8][8]; GLfloat cx, cy, cz; @@ -2811,18 +2060,18 @@ static void gld_BuildSky(int row_count, int col_count) // I dont know if this is slow or not GLProject(cx, cy, cz, &px, &py, &pz); - //DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); + //GL_DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); if ((pz < 0.0l) || - (px < -8.0l) || - (py < viewport[1]-8.0l) || - (px > viewport[2]+8.0l) || - (py > viewport[1]+viewport[3]+8.0l)) + (px < -8.0l) || + (py < viewport[1]-8.0l) || + (px > viewport[2]+8.0l) || + (py > viewport[1]+viewport[3]+8.0l)) return; // the damned slow glReadPixels functions :( pglReadPixels((INT32)px-4, (INT32)py, 8, 8, GL_DEPTH_COMPONENT, GL_FLOAT, buf); - //DBG_Printf("DepthBuffer: %f %f\n", buf[0][0], buf[3][3]); + //GL_DBG_Printf("DepthBuffer: %f %f\n", buf[0][0], buf[3][3]); for (i = 0; i < 8; i++) for (j = 0; j < 8; j++) @@ -2835,147 +2084,57 @@ static void gld_BuildSky(int row_count, int col_count) if (py > viewport[1]+viewport[3]-4) scalef -= (GLfloat)(8*(4-(viewport[1]+viewport[3]-py))); scalef /= 64; - //DBG_Printf("Scale factor: %f\n", scalef); + //GL_DBG_Printf("Scale factor: %f\n", scalef); if (scalef < 0.05f) return; // GLubyte c[4]; - c[0] = pSurf->FlatColor.s.red; - c[1] = pSurf->FlatColor.s.green; - c[2] = pSurf->FlatColor.s.blue; + c[0] = pSurf->PolyColor.s.red; + c[1] = pSurf->PolyColor.s.green; + c[2] = pSurf->PolyColor.s.blue; - alpha = byte2float[pSurf->FlatColor.s.alpha]; + alpha = byte2float[pSurf->PolyColor.s.alpha]; alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) c[3] = (unsigned char)(alpha * 255); pglColor4ubv(c); } - pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); ->>>>>>> srb2/next - - if (!vbo->data) - { - memset(vbo, 0, sizeof(&vbo)); - vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0])); - // create vertex array - vbo->data = malloc(vertex_count * sizeof(vbo->data[0])); - } - - vbo->columns = col_count; - vbo->rows = row_count; - - vertex_p = &vbo->data[0]; - vbo->loopcount = 0; - - for (yflip = 0; yflip < 2; yflip++) - { - vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; - vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; - vbo->loops[vbo->loopcount].vertexcount = col_count; - vbo->loops[vbo->loopcount].use_texture = false; - vbo->loopcount++; - - delta = 0.0f; - foglayer = true; - for (c = 0; c < col_count; c++) - { - SkyVertex(vertex_p, 1, c); - vertex_p->r = 255; - vertex_p->g = 255; - vertex_p->b = 255; - vertex_p->a = 255; - vertex_p++; - } - foglayer = false; - -<<<<<<< HEAD - delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF; - - for (r = 0; r < row_count; r++) - { - vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP; - vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; - vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2; - vbo->loops[vbo->loopcount].use_texture = true; - vbo->loopcount++; - - for (c = 0; c <= col_count; c++) - { - SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0)); - SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0)); - } - } - } + Shader_Load(pSurf, &poly, &tint, &fade); } -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void RenderDome(INT32 skytexture) +// -----------------+ +// DrawPolygon : Render a polygon, set the texture, set render mode +// -----------------+ +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) { - int i, j; - int vbosize; - GLSkyVBO *vbo = &sky_vbo; + PreparePolygon(pSurf, pOutVerts, PolyFlags); - rows = 4; - columns = 4 * gl_sky_detail; + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); + pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); - vbosize = 2 * rows * (columns * 2 + 2) + columns * 2; + if (PolyFlags & PF_RemoveYWrap) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - // Build the sky dome! Yes! - if (lasttex != skytexture) - { - // delete VBO when already exists - if (gl_ext_arb_vertex_buffer_object) - { - if (vbo->id) - pglDeleteBuffers(1, &vbo->id); - } + if (PolyFlags & PF_ForceWrapX) + Clamp2D(GL_TEXTURE_WRAP_S); - lasttex = skytexture; - gld_BuildSky(rows, columns); + if (PolyFlags & PF_ForceWrapY) + Clamp2D(GL_TEXTURE_WRAP_T); +} - if (gl_ext_arb_vertex_buffer_object) - { - // generate a new VBO and get the associated ID - pglGenBuffers(1, &vbo->id); +EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray) +{ + PreparePolygon(pSurf, pOutVerts, PolyFlags); - // bind VBO in order to use - pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); + pglDrawElements(GL_TRIANGLES, iNumPts, GL_UNSIGNED_INT, IndexArray); - // upload data to VBO - pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW); - } - } + // the DrawPolygon variant of this has some code about polyflags and wrapping here but havent noticed any problems from omitting it? +} - // bind VBO in order to use - if (gl_ext_arb_vertex_buffer_object) - pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); - - // activate and specify pointers to arrays - pglVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u); - pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r); - - // activate color arrays - pglEnableClientState(GL_COLOR_ARRAY); - - // set transforms - pglScalef(1.0f, (float)texh / 230.0f, 1.0f); - pglRotatef(270.0f, 0.0f, 1.0f, 0.0f); - - for (j = 0; j < 2; j++) - { - for (i = 0; i < vbo->loopcount; i++) - { - GLSkyLoopDef *loop = &vbo->loops[i]; -======= typedef struct vbo_vertex_s { float x, y, z; @@ -3238,53 +2397,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) model_lighting = Value; break; - case HWD_SET_FOG_COLOR: - { - GLfloat fogcolor[4]; ->>>>>>> srb2/next - - if (j == 0 ? loop->use_texture : !loop->use_texture) - continue; - - pglDrawArrays(loop->mode, loop->vertexindex, loop->vertexcount); - } -<<<<<<< HEAD - } -======= - - case HWD_SET_FOG_DENSITY: - pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f)); - break; ->>>>>>> srb2/next - - pglScalef(1.0f, 1.0f, 1.0f); - pglColor4ubv(white); - - // bind with 0, so, switch back to normal pointer operation - if (gl_ext_arb_vertex_buffer_object) - pglBindBuffer(GL_ARRAY_BUFFER, 0); - - // deactivate color array - pglDisableClientState(GL_COLOR_ARRAY); -} - -EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform) -{ - SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); - SetTransform(&transform); - texw = texture_width; - texh = texture_height; - RenderDome(tex); - SetBlend(0); -} - -// ========================================================================== -// -// ========================================================================== -EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) -{ - switch (IdState) - { case HWD_SET_SHADERS: switch (Value) { @@ -3295,11 +2407,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) gl_allowshaders = false; break; } -<<<<<<< HEAD -======= - else - pglDisable(GL_FOG); ->>>>>>> srb2/next break; case HWD_SET_TEXTUREFILTERMODE: @@ -3366,44 +2473,6 @@ static size_t lerpTinyBufferSize = 0; // Static temporary buffer for doing frame interpolation // 'size' is the vertex size static void AllocLerpBuffer(size_t size) -<<<<<<< HEAD -{ - if (lerpBufferSize >= size) - return; - - if (vertBuffer != NULL) - free(vertBuffer); - - if (normBuffer != NULL) - free(normBuffer); - - lerpBufferSize = size; - vertBuffer = malloc(lerpBufferSize); - normBuffer = malloc(lerpBufferSize); -} - -// Static temporary buffer for doing frame interpolation -// 'size' is the vertex size -static void AllocLerpTinyBuffer(size_t size) -{ - if (lerpTinyBufferSize >= size) - return; - - if (vertTinyBuffer != NULL) - free(vertTinyBuffer); - - if (normTinyBuffer != NULL) - free(normTinyBuffer); - - lerpTinyBufferSize = size; - vertTinyBuffer = malloc(lerpTinyBufferSize); - normTinyBuffer = malloc(lerpTinyBufferSize / 2); -} - -#ifndef GL_STATIC_DRAW -#define GL_STATIC_DRAW 0x88E4 -#endif -======= { if (lerpBufferSize >= size) return; @@ -3592,184 +2661,9 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) } } -#define BUFFER_OFFSET(i) ((char*)NULL + (i)) +#define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) -{ - GLfloat ambient[4]; - GLfloat diffuse[4]; - - float pol = 0.0f; - float scalex, scaley, scalez; - - boolean useTinyFrames; - - int i; - - // Because Otherwise, scaling the screen negatively vertically breaks the lighting - GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; - - // Affect input model scaling - scale *= 0.5f; - scalex = scale; - scaley = scale; - scalez = scale; ->>>>>>> srb2/next - -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif - -static void CreateModelVBO(mesh_t *mesh, mdlframe_t *frame) -{ - int bufferSize = sizeof(vbo64_t)*mesh->numTriangles * 3; - vbo64_t *buffer = (vbo64_t*)malloc(bufferSize); - vbo64_t *bufPtr = buffer; - - float *vertPtr = frame->vertices; - float *normPtr = frame->normals; - float *tanPtr = frame->tangents; - float *uvPtr = mesh->uvs; - float *lightPtr = mesh->lightuvs; - char *colorPtr = frame->colors; - - int i; - for (i = 0; i < mesh->numTriangles * 3; i++) - { - bufPtr->x = *vertPtr++; - bufPtr->y = *vertPtr++; - bufPtr->z = *vertPtr++; - - bufPtr->nx = *normPtr++; - bufPtr->ny = *normPtr++; - bufPtr->nz = *normPtr++; - - bufPtr->s0 = *uvPtr++; - bufPtr->t0 = *uvPtr++; - - if (tanPtr != NULL) - { - bufPtr->tan0 = *tanPtr++; - bufPtr->tan1 = *tanPtr++; - bufPtr->tan2 = *tanPtr++; - } - - if (lightPtr != NULL) - { - bufPtr->s1 = *lightPtr++; - bufPtr->t1 = *lightPtr++; - } - - if (colorPtr) - { - bufPtr->r = *colorPtr++; - bufPtr->g = *colorPtr++; - bufPtr->b = *colorPtr++; - bufPtr->a = *colorPtr++; - } - else - { - bufPtr->r = 255; - bufPtr->g = 255; - bufPtr->b = 255; - bufPtr->a = 255; - } - - bufPtr++; - } - - pglGenBuffers(1, &frame->vboID); - pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); - pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); - free(buffer); - - // Don't leave the array buffer bound to the model, - // since this is called mid-frame - pglBindBuffer(GL_ARRAY_BUFFER, 0); -} - -static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) -{ - int bufferSize = sizeof(vbotiny_t)*mesh->numTriangles * 3; - vbotiny_t *buffer = (vbotiny_t*)malloc(bufferSize); - vbotiny_t *bufPtr = buffer; - - short *vertPtr = frame->vertices; - char *normPtr = frame->normals; - float *uvPtr = mesh->uvs; - char *tanPtr = frame->tangents; - - int i; - for (i = 0; i < mesh->numVertices; i++) - { - bufPtr->x = *vertPtr++; - bufPtr->y = *vertPtr++; - bufPtr->z = *vertPtr++; - - bufPtr->nx = *normPtr++; - bufPtr->ny = *normPtr++; - bufPtr->nz = *normPtr++; - - bufPtr->s0 = *uvPtr++; - bufPtr->t0 = *uvPtr++; - - if (tanPtr) - { - bufPtr->tanx = *tanPtr++; - bufPtr->tany = *tanPtr++; - bufPtr->tanz = *tanPtr++; - } - - bufPtr++; - } - - pglGenBuffers(1, &frame->vboID); - pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); - pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); - free(buffer); - - // Don't leave the array buffer bound to the model, - // since this is called mid-frame - pglBindBuffer(GL_ARRAY_BUFFER, 0); -} - -EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) -{ - int i; - for (i = 0; i < model->numMeshes; i++) - { - mesh_t *mesh = &model->meshes[i]; - - if (mesh->frames) - { - int j; - for (j = 0; j < model->meshes[i].numFrames; j++) - { - mdlframe_t *frame = &mesh->frames[j]; - if (frame->vboID) - pglDeleteBuffers(1, &frame->vboID); - frame->vboID = 0; - CreateModelVBO(mesh, frame); - } - } - else if (mesh->tinyframes) - { - int j; - for (j = 0; j < model->meshes[i].numFrames; j++) - { - tinyframe_t *frame = &mesh->tinyframes[j]; - if (frame->vboID) - pglDeleteBuffers(1, &frame->vboID); - frame->vboID = 0; - CreateModelVBOTiny(mesh, frame); - } - } - } -} - -#define BUFFER_OFFSET(i) ((char*)(i)) - -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -3782,6 +2676,13 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 int i; + // Because otherwise, scaling the screen negatively vertically breaks the lighting + GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; +#ifdef GL_LIGHT_MODEL_AMBIENT + GLfloat ambient[4]; + GLfloat diffuse[4]; +#endif + // Affect input model scaling scale *= 0.5f; scalex = scale; @@ -3806,35 +2707,65 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 poly.blue = byte2float[Surface->PolyColor.s.blue]; poly.alpha = byte2float[Surface->PolyColor.s.alpha]; - if (poly.alpha < 1) - SetBlend(PF_Translucent|PF_Modulated); +#ifdef GL_LIGHT_MODEL_AMBIENT + if (model_lighting) + { + if (!gl_shadersenabled) + { + ambient[0] = poly.red; + ambient[1] = poly.green; + ambient[2] = poly.blue; + ambient[3] = poly.alpha; + + diffuse[0] = poly.red; + diffuse[1] = poly.green; + diffuse[2] = poly.blue; + diffuse[3] = poly.alpha; + + if (ambient[0] > 0.75f) + ambient[0] = 0.75f; + if (ambient[1] > 0.75f) + ambient[1] = 0.75f; + if (ambient[2] > 0.75f) + ambient[2] = 0.75f; + + pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); + + pglEnable(GL_LIGHTING); + pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + } + pglShadeModel(GL_SMOOTH); + } +#endif else - SetBlend(PF_Masked|PF_Modulated|PF_Occlude); + pglColor4ubv((GLubyte*)&Surface->PolyColor.s); - pglColor4ubv((GLubyte*)&Surface->PolyColor.s); + SetBlend((poly.alpha < 1 ? PF_Translucent : (PF_Masked|PF_Occlude))|PF_Modulated); - tint.red = byte2float[Surface->TintColor.s.red]; - tint.green = byte2float[Surface->TintColor.s.green]; - tint.blue = byte2float[Surface->TintColor.s.blue]; - tint.alpha = byte2float[Surface->TintColor.s.alpha]; + tint.red = byte2float[Surface->TintColor.s.red]; + tint.green = byte2float[Surface->TintColor.s.green]; + tint.blue = byte2float[Surface->TintColor.s.blue]; + tint.alpha = byte2float[Surface->TintColor.s.alpha]; fade.red = byte2float[Surface->FadeColor.s.red]; fade.green = byte2float[Surface->FadeColor.s.green]; fade.blue = byte2float[Surface->FadeColor.s.blue]; fade.alpha = byte2float[Surface->FadeColor.s.alpha]; - load_shaders(Surface, &poly, &tint, &fade); + Shader_Load(Surface, &poly, &tint, &fade); pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); #ifdef USE_FTRANSFORM_MIRROR - // flipped is if the object is flipped + // flipped is if the object is vertically flipped + // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically // pos->mirror is if the screen is flipped horizontally // XOR all the flips together to figure out what culling to use! { - boolean reversecull = (flipped ^ pos->flip ^ pos->mirror); + boolean reversecull = (flipped ^ hflipped ^ pos->flip ^ pos->mirror); if (reversecull) pglCullFace(GL_FRONT); else @@ -3842,54 +2773,23 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } #else // pos->flip is if the screen is flipped too - if (flipped != pos->flip) // If either are active, but not both, invert the model's culling + if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling + { pglCullFace(GL_FRONT); + } else + { pglCullFace(GL_BACK); -<<<<<<< HEAD -#endif - -======= } #endif - if (model_lighting) - { - pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); - pglShadeModel(GL_SMOOTH); - } - - if (color) - { -#ifdef GL_LIGHT_MODEL_AMBIENT - if (model_lighting) - { - pglEnable(GL_LIGHTING); - pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); - } - else -#endif - pglColor4ubv((GLubyte*)color); - - if (color[3] < 255) - SetBlend(PF_Translucent|PF_Modulated|PF_Clip); - else - SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); - } - ->>>>>>> srb2/next pglPushMatrix(); // should be the same as glLoadIdentity + //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; -<<<<<<< HEAD -#ifdef USE_FTRANSFORM_ANGLEZ - pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart -#endif - pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); -======= + if (hflipped) + scalez = -scalez; #ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart @@ -3909,7 +2809,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglRotatef(pos->rollangle, roll, 0.0f, 0.0f); pglTranslatef(-pos->centerx, -pos->centery, 0); } ->>>>>>> srb2/next pglScalef(scalex, scaley, scalez); @@ -3928,7 +2827,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { tinyframe_t *frame = &mesh->tinyframes[frameIndex % mesh->numFrames]; tinyframe_t *nextframe = NULL; -<<<<<<< HEAD if (nextFrameIndex != -1) nextframe = &mesh->tinyframes[nextFrameIndex % mesh->numFrames]; @@ -3939,6 +2837,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0)); pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3)); pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6)); + pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -3971,91 +2870,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 mdlframe_t *frame = &mesh->frames[frameIndex % mesh->numFrames]; mdlframe_t *nextframe = NULL; - if (nextFrameIndex != -1) - nextframe = &mesh->frames[nextFrameIndex % mesh->numFrames]; - - if (!nextframe || fpclassify(pol) == FP_ZERO) - { - // Zoom! Take advantage of just shoving the entire arrays to the GPU. - pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); - pglVertexPointer(3, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(0)); - pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3)); - pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6)); - - pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); -======= - - if (nextFrameIndex != -1) - nextframe = &mesh->tinyframes[nextFrameIndex % mesh->numFrames]; - - if (!nextframe || fpclassify(pol) == FP_ZERO) - { - pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); - pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0)); - pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3)); - pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6)); - - pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); ->>>>>>> srb2/next - pglBindBuffer(GL_ARRAY_BUFFER, 0); - } - else - { -<<<<<<< HEAD - float *vertPtr; - float *normPtr; - int j = 0; - - // Dangit, I soooo want to do this in a GLSL shader... - AllocLerpBuffer(mesh->numVertices * sizeof(float) * 3); - vertPtr = vertBuffer; - normPtr = normBuffer; -======= - short *vertPtr; - char *normPtr; - int j; - - // Dangit, I soooo want to do this in a GLSL shader... - AllocLerpTinyBuffer(mesh->numVertices * sizeof(short) * 3); - vertPtr = vertTinyBuffer; - normPtr = normTinyBuffer; - j = 0; ->>>>>>> srb2/next - - for (j = 0; j < mesh->numVertices * 3; j++) - { - // Interpolate -<<<<<<< HEAD - *vertPtr++ = frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j])); - *normPtr++ = frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j])); - } - - pglVertexPointer(3, GL_FLOAT, 0, vertBuffer); - pglNormalPointer(GL_FLOAT, 0, normBuffer); - pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); - pglDrawArrays(GL_TRIANGLES, 0, mesh->numVertices); - } - } - } - - pglDisableClientState(GL_NORMAL_ARRAY); - -======= - *vertPtr++ = (short)(frame->vertices[j] + (pol * (nextframe->vertices[j] - frame->vertices[j]))); - *normPtr++ = (char)(frame->normals[j] + (pol * (nextframe->normals[j] - frame->normals[j]))); - } - - pglVertexPointer(3, GL_SHORT, 0, vertTinyBuffer); - pglNormalPointer(GL_BYTE, 0, normTinyBuffer); - pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); - pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); - } - } - else - { - mdlframe_t *frame = &mesh->frames[frameIndex % mesh->numFrames]; - mdlframe_t *nextframe = NULL; - if (nextFrameIndex != -1) nextframe = &mesh->frames[nextFrameIndex % mesh->numFrames]; @@ -4106,24 +2920,26 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDisableClientState(GL_NORMAL_ARRAY); ->>>>>>> srb2/next pglPopMatrix(); // should be the same as glLoadIdentity pglDisable(GL_CULL_FACE); pglDisable(GL_NORMALIZE); + +#ifdef GL_LIGHT_MODEL_AMBIENT + if (model_lighting) + { + if (!gl_shadersenabled) + pglDisable(GL_LIGHTING); + pglShadeModel(GL_FLAT); + } +#endif } // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -<<<<<<< HEAD -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface); -======= -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) -{ - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, color); ->>>>>>> srb2/next + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); } // -----------------+ @@ -4132,23 +2948,14 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { static boolean special_splitscreen; -<<<<<<< HEAD - GLdouble used_fov; boolean shearing = false; -======= float used_fov; ->>>>>>> srb2/next + pglLoadIdentity(); + if (stransform) { used_fov = stransform->fovxangle; -<<<<<<< HEAD - shearing = stransform->shearing; - // keep a trace of the transformation for md2 - memcpy(&md2_transform, stransform, sizeof (md2_transform)); - -======= ->>>>>>> srb2/next #ifdef USE_FTRANSFORM_MIRROR // mirroring from Kart if (stransform->mirror) @@ -4160,18 +2967,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); -<<<<<<< HEAD - pglMatrixMode(GL_MODELVIEW); - pglRotatef(stransform->anglex, 1.0f, 0.0f, 0.0f); - pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); - pglTranslatef(-stransform->x, -stransform->z, -stransform->y); - - special_splitscreen = (stransform->splitscreen == 1); - } - else - { - //Hurdler: is "fov" correct? -======= if (stransform->roll) pglRotatef(stransform->rollangle, 0.0f, 0.0f, 1.0f); pglRotatef(stransform->anglex , 1.0f, 0.0f, 0.0f); @@ -4179,10 +2974,10 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglTranslatef(-stransform->x, -stransform->z, -stransform->y); special_splitscreen = stransform->splitscreen; + shearing = stransform->shearing; } else { ->>>>>>> srb2/next used_fov = fov; pglScalef(1.0f, 1.0f, -1.0f); } @@ -4190,43 +2985,35 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); -<<<<<<< HEAD // jimita 14042019 // Simulate Software's y-shearing // https://zdoom.org/wiki/Y-shearing if (shearing) { - float dy = FIXED_TO_FLOAT(AIMINGTODY(stransform->viewaiming)) * 2; //screen_width/BASEVIDWIDTH; - pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f); -======= + float fdy = stransform->viewaiming * 2; + if (stransform->flip) + fdy *= -1.0f; + pglTranslatef(0.0f, -fdy/BASEVIDHEIGHT, 0.0f); + } + if (special_splitscreen) { used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI; GLPerspective(used_fov, 2*ASPECT_RATIO); ->>>>>>> srb2/next } else GLPerspective(used_fov, ASPECT_RATIO); -<<<<<<< HEAD - if (special_splitscreen) - { - used_fov = atan(tan(used_fov*M_PIl/360)*0.8)*360/M_PIl; - GLPerspective((GLfloat)used_fov, 2*ASPECT_RATIO); - } - else - GLPerspective((GLfloat)used_fov, ASPECT_RATIO); -======= ->>>>>>> srb2/next pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) pglMatrixMode(GL_MODELVIEW); pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) + } EXPORT INT32 HWRAPI(GetTextureUsed) (void) { - FTextureInfo *tmp = gr_cachehead; + FTextureInfo *tmp = gl_cachehead; INT32 res = 0; while (tmp) @@ -4235,14 +3022,10 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) // I don't know which one the game actually _uses_ but this // follows format2bpp in hw_cache.c int bpp = 1; - int format = tmp->grInfo.format; - if (format == GR_RGBA) + int format = tmp->format; + if (format == GL_TEXFMT_RGBA) bpp = 4; - else if (format == GR_TEXFMT_RGB_565 - || format == GR_TEXFMT_ARGB_1555 - || format == GR_TEXFMT_ARGB_4444 - || format == GR_TEXFMT_ALPHA_INTENSITY_88 - || format == GR_TEXFMT_AP_88) + else if (format == GL_TEXFMT_ALPHA_INTENSITY_88 || format == GL_TEXFMT_AP_88) bpp = 2; // Add it up! @@ -4253,14 +3036,6 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) return res; } -<<<<<<< HEAD -======= -EXPORT INT32 HWRAPI(GetRenderVersion) (void) -{ - return VERSION; -} - ->>>>>>> srb2/next EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) { INT32 x, y; @@ -4276,11 +3051,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) 16.0f, -16.0f, 6.0f }; -<<<<<<< HEAD - // Use a power of two texture -======= // Use a power of two texture, dammit ->>>>>>> srb2/next if(screen_width <= 1024) texsize = 1024; if(screen_width <= 512) @@ -4293,11 +3064,8 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglDisable(GL_DEPTH_TEST); pglDisable(GL_BLEND); -<<<<<<< HEAD -======= // const float blackBack[16] ->>>>>>> srb2/next // Draw a black square behind the screen texture, // so nothing shows through the edges pglColor4ubv(white); @@ -4305,10 +3073,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglVertexPointer(3, GL_FLOAT, 0, blackBack); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); -<<<<<<< HEAD pglEnableClientState(GL_TEXTURE_COORD_ARRAY); -======= ->>>>>>> srb2/next for(x=0;x>>>>>> srb2/next stCoords[0] = float_x; stCoords[1] = float_y; stCoords[2] = float_x; @@ -4339,10 +3101,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglTexCoordPointer(2, GL_FLOAT, 0, stCoords); -<<<<<<< HEAD -======= // float vertCoords[12]; ->>>>>>> srb2/next vertCoords[0] = points[x][y][0]; vertCoords[1] = points[x][y][1]; vertCoords[2] = 4.4f; @@ -4374,7 +3133,6 @@ EXPORT void HWRAPI(FlushScreenTextures) (void) pglDeleteTextures(1, &startScreenWipe); pglDeleteTextures(1, &endScreenWipe); pglDeleteTextures(1, &finalScreenTexture); - screentexture = 0; startScreenWipe = 0; endScreenWipe = 0; @@ -4443,6 +3201,7 @@ EXPORT void HWRAPI(EndScreenWipe)(void) tex_downloaded = endScreenWipe; } + // Draw the last scene under the intermission EXPORT void HWRAPI(DrawIntermissionBG)(void) { @@ -4467,12 +3226,9 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); -<<<<<<< HEAD -======= // const float screenVerts[12] // float fix[8]; ->>>>>>> srb2/next fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -4483,15 +3239,10 @@ EXPORT void HWRAPI(DrawIntermissionBG)(void) fix[7] = 0.0f; pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); -<<<<<<< HEAD - pglBindTexture(GL_TEXTURE_2D, screentexture); - pglColor4ubv(white); -======= pglBindTexture(GL_TEXTURE_2D, screentexture); pglColor4ubv(white); ->>>>>>> srb2/next pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -4534,12 +3285,9 @@ EXPORT void HWRAPI(DoScreenWipe)(void) xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); -<<<<<<< HEAD -======= // const float screenVerts[12] // float fix[8]; ->>>>>>> srb2/next fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -4551,11 +3299,7 @@ EXPORT void HWRAPI(DoScreenWipe)(void) pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); -<<<<<<< HEAD - SetBlend(PF_Modulated|PF_NoDepthTest); -======= SetBlend(PF_Modulated|PF_NoDepthTest|PF_Clip|PF_NoZClip); ->>>>>>> srb2/next pglEnable(GL_TEXTURE_2D); // Draw the original screen @@ -4565,37 +3309,13 @@ EXPORT void HWRAPI(DoScreenWipe)(void) pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); -<<<<<<< HEAD - SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); -======= SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest|PF_Clip|PF_NoZClip); ->>>>>>> srb2/next // Draw the end screen that fades in pglActiveTexture(GL_TEXTURE0); pglEnable(GL_TEXTURE_2D); pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -<<<<<<< HEAD - - pglActiveTexture(GL_TEXTURE1); - pglEnable(GL_TEXTURE_2D); - pglBindTexture(GL_TEXTURE_2D, fademaskdownloaded); - - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - pglClientActiveTexture(GL_TEXTURE0); - pglTexCoordPointer(2, GL_FLOAT, 0, fix); - pglVertexPointer(3, GL_FLOAT, 0, screenVerts); - pglClientActiveTexture(GL_TEXTURE1); - pglEnableClientState(GL_TEXTURE_COORD_ARRAY); - pglTexCoordPointer(2, GL_FLOAT, 0, defaultST); - pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit - pglDisableClientState(GL_TEXTURE_COORD_ARRAY); - -======= pglActiveTexture(GL_TEXTURE1); pglEnable(GL_TEXTURE_2D); @@ -4616,7 +3336,6 @@ EXPORT void HWRAPI(DoScreenWipe)(void) pglDisable(GL_TEXTURE_2D); // disable the texture in the 2nd texture unit pglDisableClientState(GL_TEXTURE_COORD_ARRAY); ->>>>>>> srb2/next pglActiveTexture(GL_TEXTURE0); pglClientActiveTexture(GL_TEXTURE0); tex_downloaded = endScreenWipe; @@ -4715,10 +3434,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) yoff = newaspect / origaspect; } -<<<<<<< HEAD -======= // float off[12]; ->>>>>>> srb2/next off[0] = -xoff; off[1] = -yoff; off[2] = 1.0f; @@ -4732,11 +3448,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) off[10] = -yoff; off[11] = 1.0f; -<<<<<<< HEAD - -======= // float fix[8]; ->>>>>>> srb2/next fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -4754,16 +3466,9 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglColor4ubv(white); -<<<<<<< HEAD - pglTexCoordPointer(2, GL_FLOAT, 0, fix); - pglVertexPointer(3, GL_FLOAT, 0, off); - - pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); -======= pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, off); ->>>>>>> srb2/next pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); tex_downloaded = finalScreenTexture; diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index 3ce28cf2d..f44e0818b 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -57,17 +57,19 @@ #undef DEBUG_TO_FILE // maybe defined in previous *.h #define DEBUG_TO_FILE // output debugging msgs to ogllog.txt +// todo: find some way of getting SDL to log to ogllog.txt, without +// interfering with r_opengl.dll +#ifdef HAVE_SDL +#undef DEBUG_TO_FILE +#endif +//#if defined(HAVE_SDL) && !defined(_DEBUG) +//#undef DEBUG_TO_FILE +//#endif + #ifdef DEBUG_TO_FILE extern FILE *gllogstream; #endif -<<<<<<< HEAD -======= -#ifndef DRIVER_STRING -#define DRIVER_STRING "HWRAPI Init(): SRB2 OpenGL renderer" // Tails -#endif - ->>>>>>> srb2/next // ========================================================================== // PROTOS // ========================================================================== @@ -80,14 +82,6 @@ void Flush(void); INT32 isExtAvailable(const char *extension, const GLubyte *start); void SetModelView(GLint w, GLint h); void SetStates(void); -<<<<<<< HEAD -#ifdef USE_PALETTED_TEXTURE -extern PFNGLCOLORTABLEEXTPROC glColorTableEXT; -extern GLubyte palette_tex[256*3]; -#endif -======= -FUNCMATH float byteasfloat(UINT8 fbyte); ->>>>>>> srb2/next #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE