summaryrefslogtreecommitdiff
path: root/src/opengl.c
diff options
context:
space:
mode:
authorSteven Fuller <relnev@icculus.org>2017-05-05 12:00:00 +0200
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-20 03:51:51 +0200
commit5673c1665a2c6d7fdaf1a20d554bb135a20c7bc8 (patch)
treeccf08c484f14d7c5e95fa7f645db2014d61ebb78 /src/opengl.c
parent0de664d0a886bcda45a0cd05551b6896c5c46ed0 (diff)
Import icculus.org release (2017-05-05)
Diffstat (limited to 'src/opengl.c')
-rw-r--r--src/opengl.c1068
1 files changed, 825 insertions, 243 deletions
diff --git a/src/opengl.c b/src/opengl.c
index 4326fc0..dd89509 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -46,10 +46,13 @@ extern int CloakingPhase;
static D3DTexture *CurrTextureHandle;
+enum AVP_SHADER_PROGRAM CurrShaderProgram;
+
+GLuint DefaultTexture;
static enum TRANSLUCENCY_TYPE CurrentTranslucencyMode = TRANSLUCENCY_OFF;
static enum FILTERING_MODE_ID CurrentFilteringMode = FILTERING_BILINEAR_OFF;
-static GLenum TextureMinFilter = GL_LINEAR_MIPMAP_LINEAR;
+static GLenum TextureMinFilter = GL_LINEAR; //GL_LINEAR_MIPMAP_LINEAR;
static D3DTexture *CurrentlyBoundTexture = NULL;
#if defined(_MSC_VER)
@@ -86,23 +89,17 @@ static VertexArray *varrp = varr;
static TriangleArray *tarrp = tarr;
static int varrc, tarrc;
-static ALIGN16 TriangleArray starr[TA_MAXTRIANGLES];
-static TriangleArray *starrp = starr;
-static int starrc;
+static GLuint ElementArrayBuffer;
+static GLuint ArrayBuffer;
/* Do not call this directly! */
static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode)
{
- pglDisable(GL_ALPHA_TEST);
-
switch(mode) {
case TRANSLUCENCY_OFF:
if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) {
pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
- } else {
- // alien tail hack
- pglEnable(GL_ALPHA_TEST);
-
+ } else {
pglBlendFunc(GL_ONE, GL_ZERO);
}
break;
@@ -130,101 +127,693 @@ static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode)
}
}
-static void SetSecondPassTranslucencyMode(enum TRANSLUCENCY_TYPE mode)
-{
- pglDisable(GL_ALPHA_TEST);
+#if defined(USE_OPENGL_ES)
+#define SHADER_PRAGMAS "\n"
+#define SHADER_VERSION "#version 100\n"
+#else
+#define SHADER_PRAGMAS "\n"
+#define SHADER_VERSION "#version 120\n"
+#endif
- switch(mode) {
- case TRANSLUCENCY_OFF:
- if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) {
- pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE);
+#if USE_OPENGL_ES
+
+#define SHADER_SETUP \
+"#define HIGHP highp\n" \
+"#define MEDIUMP mediump\n" \
+"#define LOWP lowp\n"
+
+#else
+
+#define SHADER_SETUP \
+"#ifdef GL_ES\n" \
+"#define HIGHP highp\n" \
+"#define MEDIUMP mediump\n" \
+"#define LOWP lowp\n" \
+"#else\n" \
+"#define HIGHP\n" \
+"#define MEDIUMP\n" \
+"#define LOWP\n" \
+"#endif\n"
+
+#endif
+
+static const char AVP_VERTEX_SHADER_SOURCE[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "attribute HIGHP vec4 aVertex;\n"
+ "attribute HIGHP vec2 aTexCoord;\n"
+ "attribute LOWP vec4 aColor0;\n"
+ "attribute LOWP vec4 aColor1;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "varying LOWP vec4 vColor1;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = aVertex;\n"
+ " vTexCoord = aTexCoord;\n"
+ " vColor0 = aColor0;\n"
+ " vColor1 = aColor1;\n"
+ "}\n"
+ ;
+
+static const char AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "attribute HIGHP vec4 aVertex;\n"
+ "attribute HIGHP vec2 aTexCoord;\n"
+ "attribute LOWP vec4 aColor0;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = aVertex;\n"
+ " vTexCoord = aTexCoord;\n"
+ " vColor0 = aColor0;\n"
+ "}\n"
+ ;
+
+static const char AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "attribute HIGHP vec4 aVertex;\n"
+ "attribute LOWP vec4 aColor0;\n"
+ "\n"
+ "varying LOWP vec4 vColor0;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = aVertex;\n"
+ " vColor0 = aColor0;\n"
+ "}\n"
+ ;
+
+static const char AVP_VERTEX_SHADER_SOURCE_NO_COLOR[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "attribute HIGHP vec4 aVertex;\n"
+ "attribute HIGHP vec2 aTexCoord;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = aVertex;\n"
+ " vTexCoord = aTexCoord;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "uniform LOWP sampler2D uTexture;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "varying LOWP vec4 vColor1;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ "\n"
+ " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n"
+ " if (t.a == 0.0) discard;\n"
+ " gl_FragColor = t * vColor0 + vColor1;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "uniform LOWP sampler2D uTexture;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n"
+ " if (t.a == 0.0) discard;\n"
+ " gl_FragColor = t * vColor0;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "varying LOWP vec4 vColor0;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_FragColor = vColor0;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "uniform LOWP sampler2D uTexture;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "varying LOWP vec4 vColor1;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n"
+ " gl_FragColor = t * vColor0 + vColor1;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "uniform LOWP sampler2D uTexture;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "varying LOWP vec4 vColor0;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n"
+ " gl_FragColor = t * vColor0;\n"
+ "}\n"
+ ;
+
+static const char AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD[] =
+ SHADER_VERSION
+ SHADER_PRAGMAS
+ SHADER_SETUP
+ "\n"
+ "uniform LOWP sampler2D uTexture;\n"
+ "\n"
+ "varying HIGHP vec2 vTexCoord;\n"
+ "\n"
+ "void main(void)\n"
+ "{\n"
+ " MEDIUMP vec4 t = texture2D( uTexture, vTexCoord );\n"
+ " gl_FragColor = t;\n"
+ "}\n"
+ ;
+
+enum AVP_VERTEX_SHADER {
+ AVP_VERTEX_SHADER_DEFAULT,
+ AVP_VERTEX_SHADER_NO_TEXTURE,
+ AVP_VERTEX_SHADER_NO_SECONDARY,
+ AVP_VERTEX_SHADER_NO_COLOR,
+ AVP_VERTEX_SHADER_MAX
+};
+
+enum AVP_FRAGMENT_SHADER {
+ AVP_FRAGMENT_SHADER_DEFAULT,
+ AVP_FRAGMENT_SHADER_NO_TEXTURE,
+ AVP_FRAGMENT_SHADER_NO_DISCARD,
+ AVP_FRAGMENT_SHADER_NO_SECONDARY,
+ AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD,
+ AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD,
+ AVP_FRAGMENT_SHADER_MAX
+};
+
+static const char* const AvpVertexShaderSources[AVP_VERTEX_SHADER_MAX] = {
+ AVP_VERTEX_SHADER_SOURCE,
+ AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE,
+ AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY,
+ AVP_VERTEX_SHADER_SOURCE_NO_COLOR
+};
+
+static const char* AvpFragmentShaderSources[AVP_FRAGMENT_SHADER_MAX] = {
+ AVP_FRAGMENT_SHADER_SOURCE,
+ AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE,
+ AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD,
+ AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY,
+ AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD,
+ AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD
+};
+
+struct AvpShaderProgramSource {
+ enum AVP_VERTEX_SHADER VertexShader;
+ enum AVP_FRAGMENT_SHADER FragmentShader;
+};
+
+struct AvpVertexShader {
+ int shaderObj;
+};
+
+struct AvpFragmentShader {
+ int shaderObj;
+};
+
+struct AvpShaderProgram {
+ int programObj;
+
+ int uTexture;
+};
+
+static const struct AvpShaderProgramSource AvpShaderProgramSources[AVP_SHADER_PROGRAM_MAX] = {
+ // AVP_SHADER_PROGRAM_DEFAULT
+ {
+ AVP_VERTEX_SHADER_DEFAULT,
+ AVP_FRAGMENT_SHADER_DEFAULT
+ },
+ // AVP_SHADER_PROGRAM_NO_SECONDARY
+ {
+ AVP_VERTEX_SHADER_NO_SECONDARY,
+ AVP_FRAGMENT_SHADER_NO_SECONDARY
+ },
+ // AVP_SHADER_PROGRAM_NO_TEXTURE
+ {
+ AVP_VERTEX_SHADER_NO_TEXTURE,
+ AVP_FRAGMENT_SHADER_NO_TEXTURE
+ },
+ // AVP_SHADER_PROGRAM_NO_DISCARD
+ {
+ AVP_VERTEX_SHADER_DEFAULT,
+ AVP_FRAGMENT_SHADER_NO_DISCARD
+ },
+ // AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD
+ {
+ AVP_VERTEX_SHADER_NO_SECONDARY,
+ AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD
+ },
+ // AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD
+ {
+ AVP_VERTEX_SHADER_NO_COLOR,
+ AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD
+ }
+};
+
+static const unsigned int AvpShaderProgramAttributes[AVP_SHADER_PROGRAM_MAX+1] = {
+ // AVP_SHADER_PROGRAM_DEFAULT
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_NO_SECONDARY
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_NO_TEXTURE
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (0 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_NO_DISCARD
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD
+ (1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (0 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
+ // AVP_SHADER_PROGRAM_MAX
+ 0
+};
+
+static const char* AvpShaderProgramAttributeNames[4] = {
+ "aVertex",
+ "aTexCoord",
+ "aColor0",
+ "aColor1"
+};
+
+static struct AvpVertexShader AvpVertexShaders[AVP_FRAGMENT_SHADER_MAX];
+static struct AvpFragmentShader AvpFragmentShaders[AVP_FRAGMENT_SHADER_MAX];
+static struct AvpShaderProgram AvpShaderPrograms[AVP_SHADER_PROGRAM_MAX];
+
+static int CompileShader(GLuint shader, const GLchar* shaderSource) {
+ GLint infoLogLength;
+ GLchar* infoLog;
+ GLint compileStatus;
+
+ pglShaderSource(shader, 1, &shaderSource, NULL);
+ pglCompileShader(shader);
+
+ pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
+ if (infoLogLength > 1) {
+ infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
+ if (infoLog == NULL) {
+ fprintf(stderr, "unable to allocate info log\n");
+ return GL_FALSE;
+ }
+
+ pglGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
+ printf("Shader:\n-------\n%s\n\nCompile Log:\n------------\n%s\n", shaderSource, infoLog);
+
+ free(infoLog);
+ }
+
+ pglGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
+ return compileStatus;
+}
+
+static int LinkProgram(GLuint program) {
+ GLint infoLogLength;
+ GLchar* infoLog;
+ GLint compileStatus;
+
+ pglLinkProgram(program);
+ pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ if (infoLogLength > 1) {
+ infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
+ if (infoLog == NULL) {
+ fprintf(stderr, "unable to allocate info log\n");
+ return GL_FALSE;
+ }
+
+ pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
+ printf("Program Link Log:\n%s\n", infoLog);
+
+ free(infoLog);
+ }
+
+ pglGetProgramiv(program, GL_LINK_STATUS, &compileStatus);
+ return compileStatus;
+}
+
+static int ValidateProgram(GLuint program) {
+ GLint infoLogLength;
+ GLchar* infoLog;
+ GLint compileStatus;
+
+ pglValidateProgram(program);
+
+ pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ if (infoLogLength > 1) {
+ infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
+ if (infoLog == NULL) {
+ fprintf(stderr, "unable to allocate info log\n");
+ return GL_FALSE;
+ }
+
+ pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
+ printf("Program Validation Log:\n%s\n", infoLog);
+
+ free(infoLog);
+ }
+
+ pglGetProgramiv(program, GL_VALIDATE_STATUS, &compileStatus);
+ return compileStatus;
+}
+
+static int CreateProgram(GLuint* pprogram, const GLchar* vertexShaderSource, const GLchar* fragmentShaderSource) {
+ GLuint program;
+ GLuint vertexShader;
+ GLuint fragmentShader;
+
+ GLint compileStatus;
+
+ // create program object
+ program = pglCreateProgram();
+
+ // vertex shader
+ vertexShader = pglCreateShader(GL_VERTEX_SHADER);
+
+ compileStatus = CompileShader(vertexShader, vertexShaderSource);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "vertex shader compilation failed\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ pglAttachShader(program, vertexShader);
+ pglDeleteShader(vertexShader);
+
+ // fragment shader
+ fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER);
+
+ compileStatus = CompileShader(fragmentShader, fragmentShaderSource);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "fragment shader compilation failed\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ pglAttachShader(program, fragmentShader);
+ pglDeleteShader(fragmentShader);
+
+ // link the program
+ compileStatus = LinkProgram(program);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "program failed to link\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ // validate the program for good measure
+ compileStatus = ValidateProgram(program);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "program failed to validate\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ *pprogram = program;
+ return GL_TRUE;
+}
+
+static int CreateProgram2(GLuint* pprogram, GLuint vertexShader, GLuint fragmentShader) {
+ GLuint program;
+ GLint compileStatus;
+ int i;
+
+ // create program object
+ program = pglCreateProgram();
+
+ // vertex shader
+ pglAttachShader(program, vertexShader);
+
+ // fragment shader
+ pglAttachShader(program, fragmentShader);
+
+ // need to bind locations before linking
+ pglBindAttribLocation(program, OPENGL_VERTEX_ATTRIB_INDEX, "aVertex");
+ pglBindAttribLocation(program, OPENGL_TEXCOORD_ATTRIB_INDEX, "aTexCoord");
+ pglBindAttribLocation(program, OPENGL_COLOR0_ATTRIB_INDEX, "aColor0");
+ pglBindAttribLocation(program, OPENGL_COLOR1_ATTRIB_INDEX, "aColor1");
+
+ // link the program
+ compileStatus = LinkProgram(program);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "program failed to link\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ // validate the program for good measure
+ compileStatus = ValidateProgram(program);
+
+ if (compileStatus == GL_FALSE) {
+ fprintf(stderr, "program failed to validate\n");
+
+ pglDeleteProgram(program);
+ return GL_FALSE;
+ }
+
+ *pprogram = program;
+ return GL_TRUE;
+}
+
+static int InitOpenGLPrograms(void) {
+ GLenum status;
+ int i;
+
+ for (i = 0; i < AVP_VERTEX_SHADER_MAX; i++) {
+ GLuint vertexShader;
+
+ vertexShader = pglCreateShader(GL_VERTEX_SHADER);
+
+ status = CompileShader(vertexShader, AvpVertexShaderSources[i]);
+
+ if (status == GL_FALSE) {
+ fprintf(stderr, "vertex shader compilation failed\n");
+ return GL_FALSE;
+ }
+
+ AvpVertexShaders[i].shaderObj = vertexShader;
+ }
+
+ for (i = 0; i < AVP_FRAGMENT_SHADER_MAX; i++) {
+ GLuint fragmentShader;
+
+ fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER);
+
+ status = CompileShader(fragmentShader, AvpFragmentShaderSources[i]);
+
+ if (status == GL_FALSE) {
+ fprintf(stderr, "fragment shader compilation failed\n");
+ return GL_FALSE;
+ }
+
+ AvpFragmentShaders[i].shaderObj = fragmentShader;
+ }
+
+ for (i = 0; i < AVP_SHADER_PROGRAM_MAX; i++) {
+ GLuint program;
+ GLuint vertexShader;
+ GLuint fragmentShader;
+
+ vertexShader = AvpVertexShaders[AvpShaderProgramSources[i].VertexShader].shaderObj;
+ fragmentShader = AvpFragmentShaders[AvpShaderProgramSources[i].FragmentShader].shaderObj;
+
+ status = CreateProgram2(&program, vertexShader, fragmentShader);
+ if (status == GL_FALSE) {
+ fprintf(stderr, "program compilation failed\n");
+ return GL_FALSE;
+ }
+
+ AvpShaderPrograms[i].programObj = program;
+ AvpShaderPrograms[i].uTexture = pglGetUniformLocation(program, "uTexture");
+ }
+
+ return GL_TRUE;
+}
+
+void SelectProgram(enum AVP_SHADER_PROGRAM program) {
+
+ if (CurrShaderProgram != program) {
+ // supposed to flush here
+
+ unsigned int PrevAttribs = AvpShaderProgramAttributes[CurrShaderProgram];
+ unsigned int NextAttribs = AvpShaderProgramAttributes[program];
+ unsigned int DiffAttribs = PrevAttribs ^ NextAttribs;
+ int ShaderProgram = AvpShaderPrograms[program].programObj;
+ int TextureUniformIndex = AvpShaderPrograms[program].uTexture;
+
+ CurrShaderProgram = program;
+ pglUseProgram(ShaderProgram);
+
+ if ((DiffAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) {
+ if ((NextAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) {
+ pglEnableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX);
} else {
- pglBlendFunc(GL_ONE, GL_ONE);
+ pglDisableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX);
}
- break;
- case TRANSLUCENCY_NORMAL:
- pglBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
- case TRANSLUCENCY_GLOWING:
- pglBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
- case TRANSLUCENCY_COLOUR:
- //fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode);
- // can't easily emulate this one
- pglBlendFunc(GL_DST_COLOR, GL_ONE);
- break;
- case TRANSLUCENCY_INVCOLOUR:
- //fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode);
- // can't easily emulate this one
- pglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
- break;
+ }
- case TRANSLUCENCY_DARKENINGCOLOUR:
- case TRANSLUCENCY_JUSTSETZ:
- fprintf(stderr, "SetSecondPassTranslucencyMode: unsupported blend mode %d\n", mode);
- pglBlendFunc(GL_SRC_ALPHA, GL_ONE);
- break;
- default:
- fprintf(stderr, "SetSecondPassTranslucencyMode: invalid blend mode %d\n", mode);
- break;
+ if ((DiffAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) {
+ if ((NextAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) {
+ pglEnableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX);
+ } else {
+ pglDisableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX);
+ }
+ }
+
+ if ((DiffAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) {
+ if ((NextAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) {
+ pglEnableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX);
+ } else {
+ pglDisableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX);
+ }
+ }
+
+ if ((DiffAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) {
+ if ((NextAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) {
+ pglEnableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX);
+ } else {
+ pglDisableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX);
+ }
+ }
+
+ if (TextureUniformIndex >= 0) {
+ pglUniform1i(TextureUniformIndex, 0);
+ }
}
}
-/*
-A few things:
-- Vertices with a specular color are done twice.
- Might want to try spitting apart the three arrays and using the same vertex
- array for both passes.
-- Fix code for separate color support.
-*/
+static void InitOpenGLDefaultTexture(void) {
+ pglGenTextures(1, &DefaultTexture);
-void InitOpenGL()
+ pglBindTexture(GL_TEXTURE_2D, DefaultTexture);
+
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ GLubyte defaultTexData[4] = { 255, 255, 255, 255 };
+ pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, defaultTexData);
+}
+
+void InitOpenGL(int firsttime)
{
- pglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- pglHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
+ if (firsttime) {
+ InitOpenGLPrograms();
+ check_for_errors();
+ InitOpenGLDefaultTexture();
+ check_for_errors();
+ }
+
+ pglHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
#if GL_NV_multisample_filter_hint
- if ( ogl_use_multisample_filter_hint )
- {
- pglHint( GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST );
- }
+ if ( ogl_use_multisample_filter_hint )
+ {
+ pglHint( GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST );
+ }
#endif
CurrentTranslucencyMode = TRANSLUCENCY_OFF;
pglBlendFunc(GL_ONE, GL_ZERO);
- pglAlphaFunc(GL_GREATER, 0.0f);
-
CurrentFilteringMode = FILTERING_BILINEAR_OFF;
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
CurrentlyBoundTexture = NULL;
pglBindTexture(GL_TEXTURE_2D, 0);
-
- pglEnableClientState(GL_VERTEX_ARRAY);
- pglVertexPointer(4, GL_FLOAT, sizeof(varr[0]), varr[0].v);
-
- pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
- pglTexCoordPointer(2, GL_FLOAT, sizeof(varr[0]), varr[0].t);
-
- pglEnableClientState(GL_COLOR_ARRAY);
- pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c);
+
+ // create array and element array buffers, as required by WebGL
+ pglGenBuffers(1, &ArrayBuffer);
+ pglGenBuffers(1, &ElementArrayBuffer);
+
+ pglBindBuffer(GL_ARRAY_BUFFER, ArrayBuffer);
+ pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementArrayBuffer);
+
+ pglVertexAttribPointer(OPENGL_VERTEX_ATTRIB_INDEX, 4, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 0);
+ pglVertexAttribPointer(OPENGL_TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 16);
+ pglVertexAttribPointer(OPENGL_COLOR0_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 24);
+ pglVertexAttribPointer(OPENGL_COLOR1_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 28);
+
+ CurrShaderProgram = AVP_SHADER_PROGRAM_MAX;
+ SelectProgram(AVP_SHADER_PROGRAM_DEFAULT);
tarrc = 0;
tarrp = tarr;
varrc = 0;
varrp = varr;
-
- starrc = 0;
- starrp = starr;
+
+ check_for_errors();
}
static void FlushTriangleBuffers(int backup)
{
if (tarrc) {
- pglDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_SHORT, tarr);
+ // not optimal but required by WebGL
+ pglBufferData(GL_ARRAY_BUFFER, varrc * sizeof(varr[0]), varr, GL_STREAM_DRAW);
+ pglBufferData(GL_ELEMENT_ARRAY_BUFFER, tarrc * sizeof(tarr[0]), tarr, GL_STREAM_DRAW);
+
+ pglDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_SHORT, (const GLvoid*) 0);
tarrc = 0;
tarrp = tarr;
@@ -232,57 +821,6 @@ static void FlushTriangleBuffers(int backup)
varrc = 0;
varrp = varr;
}
-
- if (starrc) {
- //if (CurrentlyBoundTexture != NULL) {
- // if (!backup) CurrentlyBoundTexture = NULL;
- // pglBindTexture(GL_TEXTURE_2D, 0);
- //}
-
- //if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) {
- // if (!backup) CurrentTranslucencyMode = TRANSLUCENCY_GLOWING;
- // SetTranslucencyMode(TRANSLUCENCY_GLOWING);
- // //if (CurrentTranslucencyMode == TRANSLUCENCY_OFF)
- // // pglEnable(GL_BLEND);
- // //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- //}
-
- SetSecondPassTranslucencyMode(CurrentTranslucencyMode);
-
- pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
- pglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
- pglTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR);
- pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- pglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
- pglTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
- pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- pglTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
- pglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
-
- //pglDisableClientState(GL_TEXTURE_COORD_ARRAY);
- pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].s);
-
- pglDrawElements(GL_TRIANGLES, starrc*3, GL_UNSIGNED_SHORT, starr);
-
- //pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
- pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c);
-
- //if (backup) {
- // //if (CurrentlyBoundTexture)
- // // pglBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id);
- // if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING)
- // SetTranslucencyMode(CurrentTranslucencyMode);
- //} else {
- // //CurrentlyBoundTexture = NULL;
- // CurrentTranslucencyMode = TRANSLUCENCY_GLOWING;
- //}
-
- SetTranslucencyMode(CurrentTranslucencyMode);
- pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- starrc = 0;
- starrp = starr;
- }
}
static void CheckBoundTextureIsCorrect(D3DTexture *tex)
@@ -293,7 +831,7 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex)
FlushTriangleBuffers(1);
if (tex == NULL) {
- pglBindTexture(GL_TEXTURE_2D, 0);
+ pglBindTexture(GL_TEXTURE_2D, DefaultTexture);
CurrentlyBoundTexture = NULL;
@@ -302,6 +840,10 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex)
pglBindTexture(GL_TEXTURE_2D, tex->id);
+ /*if (tex->hasAlpha != 0 || tex->hasChroma != 0) {
+ // modulate emulation?
+ }*/
+
if (tex->filter != CurrentFilteringMode) {
switch(CurrentFilteringMode) {
case FILTERING_BILINEAR_OFF:
@@ -310,7 +852,7 @@ static void CheckBoundTextureIsCorrect(D3DTexture *tex)
break;
case FILTERING_BILINEAR_ON:
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->IsNpot ? GL_LINEAR : TextureMinFilter);
break;
default:
break;
@@ -336,7 +878,7 @@ static void CheckFilteringModeIsCorrect(enum FILTERING_MODE_ID filter)
break;
case FILTERING_BILINEAR_ON:
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, CurrentlyBoundTexture->IsNpot ? GL_LINEAR : TextureMinFilter);
break;
default:
break;
@@ -358,7 +900,7 @@ static void CheckTranslucencyModeIsCorrect(enum TRANSLUCENCY_TYPE mode)
CurrentTranslucencyMode = mode;
}
-static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTexture *tex, enum TRANSLUCENCY_TYPE mode, enum FILTERING_MODE_ID filter)
+static void CheckTriangleBuffer(int rver, int rtri, D3DTexture *tex, enum TRANSLUCENCY_TYPE mode, enum FILTERING_MODE_ID filter)
{
if ((rver+varrc) >= TA_MAXVERTICES) {
FlushTriangleBuffers(0);
@@ -413,44 +955,6 @@ static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, D3DTextu
}
}
#undef OUTPUT_TRIANGLE
-
-#define OUTPUT_TRIANGLE(x, y, z) \
-{ \
- starrp->a = varrc+(x); \
- starrp->b = varrc+(y); \
- starrp->c = varrc+(z); \
- \
- starrp++; \
- starrc++; \
-}
- if (stri == 0) {
- switch(sver) {
- case 0:
- break;
- case 3:
- OUTPUT_TRIANGLE(0, 2, 1);
- break;
- case 5:
- OUTPUT_TRIANGLE(0, 1, 4);
- OUTPUT_TRIANGLE(1, 3, 4);
- OUTPUT_TRIANGLE(1, 2, 3);
- break;
- case 8:
- OUTPUT_TRIANGLE(0, 6, 7);
- case 7:
- OUTPUT_TRIANGLE(0, 5, 6);
- case 6:
- OUTPUT_TRIANGLE(0, 4, 5);
- OUTPUT_TRIANGLE(0, 3, 4);
- case 4:
- OUTPUT_TRIANGLE(0, 2, 3);
- OUTPUT_TRIANGLE(0, 1, 2);
- break;
- default:
- fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", sver);
- }
- }
-#undef OUTPUT_TRIANGLE
}
static unsigned int PowerOfTwo(unsigned int v) {
@@ -513,35 +1017,27 @@ GLuint CreateOGLTexture(D3DTexture *tex, unsigned char *buf)
pglGenTextures(1, &h);
pglBindTexture(GL_TEXTURE_2D, h);
- pglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (tex->IsNpot) {
- // OpenGL 1.x compatibility
- tex->TexWidth = PotWidth;
- tex->TexHeight = PotHeight;
-
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (tex->IsNpot) {
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
- pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->TexWidth, tex->TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tex->w, tex->h, GL_RGBA, GL_UNSIGNED_BYTE, buf);
- } else {
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- if (tex->IsNpot) {
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- } else {
- pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter);
- }
+ pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
- pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ if (!tex->IsNpot && TextureMinFilter != GL_LINEAR) {
+ // generate mipmaps if needed
+ // OpenGL 3.0 / ES 2 feature -- need fbo extension support
+ //pglGenerateMipmap(GL_TEXTURE_2D);
}
- pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
tex->buf = NULL;
tex->id = h;
tex->filter = FILTERING_BILINEAR_ON;
@@ -660,7 +1156,8 @@ void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a)
if (y1 <= y0)
return;
- CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_GLOWING, -1);
+ CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_GLOWING, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
x[0] = x0;
x[0] = (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
@@ -730,8 +1227,9 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER
RecipW = TextureHandle->RecipW / 65536.0f;
RecipH = TextureHandle->RecipH / 65536.0f;
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, RenderPolygon.NumberOfVertices, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_DEFAULT);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
GLfloat x, y, z;
@@ -764,7 +1262,7 @@ void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDER
varrp->s[0] = GammaValues[vertices->SpecularR];
varrp->s[1] = GammaValues[vertices->SpecularG];
varrp->s[2] = GammaValues[vertices->SpecularB];
- varrp->s[3] = vertices->A;
+ varrp->s[3] = 0;
varrp++;
varrc++;
@@ -785,8 +1283,9 @@ void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVertice
RecipW = TextureHandle->RecipW / 65536.0f;
RecipH = TextureHandle->RecipH / 65536.0f;
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
GLfloat x, y, z;
@@ -847,8 +1346,9 @@ void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *
RecipW = TextureHandle->RecipW / 65536.0f;
RecipH = TextureHandle->RecipH / 65536.0f;
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
@@ -943,8 +1443,9 @@ void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr)
a = decalDescPtr->Alpha;
}
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, decalDescPtr->TranslucencyType, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, decalDescPtr->TranslucencyType, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
@@ -1035,8 +1536,9 @@ void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr)
a = particleDescPtr->Alpha;
}
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, particleDescPtr->TranslucencyType, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, particleDescPtr->TranslucencyType, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
@@ -1087,8 +1589,9 @@ void D3D_PredatorThermalVisionPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVER
int i;
ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, TRANSLUCENCY_OFF, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, TRANSLUCENCY_OFF, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
@@ -1133,8 +1636,9 @@ void D3D_ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *
flags = inputPolyPtr->PolyFlags;
- CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, RenderPolygon.TranslucencyMode, -1);
-
+ CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, RenderPolygon.TranslucencyMode, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
RENDERVERTEX *vertices = &renderVerticesPtr[i];
GLfloat x, y, z;
@@ -1209,8 +1713,9 @@ void D3D_PlayerOnFireOverlay()
s[3] = u;
t[3] = v + 1.0f;
- CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
-
+ CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
for (i = 0; i < 4; i++) {
varrp->v[0] = x[i];
varrp->v[1] = y[i];
@@ -1266,7 +1771,7 @@ void D3D_PlayerDamagedOverlay(int intensity)
GLfloat x[4], y[4], s[4], t[4];
if (i == 0) {
- CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON);
colour = 0xffffff - baseColour + (intensity<<24);
@@ -1275,7 +1780,7 @@ void D3D_PlayerDamagedOverlay(int intensity)
r = (colour >> 16) & 0xFF;
a = (colour >> 24) & 0xFF;
} else {
- CheckTriangleBuffer(4, 0, 0, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
colour = baseColour + (intensity<<24);
@@ -1285,6 +1790,8 @@ void D3D_PlayerDamagedOverlay(int intensity)
a = (colour >> 24) & 0xFF;
}
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
float sin = (GetSin(theta[i]))/65536.0f/16.0f;
float cos = (GetCos(theta[i]))/65536.0f/16.0f;
@@ -1368,7 +1875,8 @@ void DrawNoiseOverlay(int tr)
// changing the depth func manually, so flush now
FlushTriangleBuffers(0);
- CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
for (j = 0; j < 4; j++) {
varrp->v[0] = x[j];
@@ -1414,11 +1922,13 @@ void D3D_ScreenInversionOverlay()
GLfloat x[4], y[4], s[4], t[4];
if (i == 0) {
- CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON);
} else {
- CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON);
}
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
float sin = (GetSin(theta[i]))/65536.0f/16.0f;
float cos = (GetCos(theta[i]))/65536.0f/16.0f;
@@ -1470,8 +1980,9 @@ void D3D_PredatorScreenInversionOverlay()
// changing the depth func manually, so flush now
FlushTriangleBuffers(0);
- CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1);
-
+ CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
for (j = 0; j < 4; j++) {
switch (j) {
@@ -1554,7 +2065,8 @@ void DrawScanlinesOverlay(float level)
// changing the depth func manually, so flush now
FlushTriangleBuffers(0);
- CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON);
+ CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
for (j = 0; j < 4; j++) {
varrp->v[0] = x[j];
@@ -1594,8 +2106,9 @@ void D3D_FadeDownScreen(int brightness, int colour)
if (t<0) t = 0;
colour = (t<<24)+colour;
- CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL, -1);
-
+ CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_NORMAL, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
b = (colour >> 0) & 0xFF;
g = (colour >> 8) & 0xFF;
r = (colour >> 16) & 0xFF;
@@ -1634,6 +2147,68 @@ void D3D_FadeDownScreen(int brightness, int colour)
}
}
+void DrawFullscreenTexture(int texureObject)
+{
+ int j;
+
+ // using a custom texture, so flush now
+ FlushTriangleBuffers(0);
+ CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD);
+ pglBindTexture(GL_TEXTURE_2D, texureObject);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ for (j = 0; j < 4; j++) {
+
+ switch (j) {
+ case 0:
+ varrp->v[0] = -1.0f;
+ varrp->v[1] = -1.0f;
+ varrp->t[0] = 0.0f;
+ varrp->t[1] = 0.0f;
+ break;
+ case 1:
+ varrp->v[0] = 1.0f;
+ varrp->v[1] = -1.0f;
+ varrp->t[0] = 1.0f;
+ varrp->t[1] = 0.0f;
+ break;
+ case 2:
+ varrp->v[0] = 1.0f;
+ varrp->v[1] = 1.0f;
+ varrp->t[0] = 1.0f;
+ varrp->t[1] = 1.0f;
+ break;
+ case 3:
+ varrp->v[0] = -1.0f;
+ varrp->v[1] = 1.0f;
+ varrp->t[0] = 0.0f;
+ varrp->t[1] = 1.0f;
+ break;
+ }
+
+ varrp->v[2] = -1.0f;
+ varrp->v[3] = 1.0f;
+
+ varrp->c[0] = 255;
+ varrp->c[1] = 255;
+ varrp->c[2] = 255;
+ varrp->c[3] = 255;
+
+ varrp->s[0] = 0;
+ varrp->s[1] = 0;
+ varrp->s[2] = 0;
+ varrp->s[3] = 0;
+
+ varrp++;
+ varrc++;
+ }
+
+ FlushTriangleBuffers(0);
+ pglBindTexture(GL_TEXTURE_2D, 0);
+}
+
void D3D_HUD_Setup()
{
FlushTriangleBuffers(1);
@@ -1653,8 +2228,9 @@ void D3D_HUDQuad_Output(int imageNumber, struct VertexTag *quadVerticesPtr, unsi
/* possibly use polygon offset? (predator hud) */
- CheckTriangleBuffer(4, 0, 0, 0, tex, TRANSLUCENCY_GLOWING, -1);
-
+ CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
RecipW = tex->RecipW / 65536.0f;
RecipH = tex->RecipH / 65536.0f;
@@ -1982,11 +2558,11 @@ int Hardware_RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AV
case AVPMENUFORMAT_RIGHTJUSTIFIED:
{
int length = 0;
- signed char *ptr = (signed char*) textPtr;
+ char *ptr = textPtr;
while(*ptr)
{
- length+=AAFontWidths[*ptr++];
+ length+=AAFontWidths[(unsigned char) *ptr++];
}
x -= length;
@@ -1995,11 +2571,11 @@ int Hardware_RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AV
case AVPMENUFORMAT_CENTREJUSTIFIED:
{
int length = 0;
- signed char *ptr = (signed char*) textPtr;
+ char *ptr = textPtr;
while(*ptr)
{
- length+=AAFontWidths[*ptr++];
+ length+=AAFontWidths[(unsigned char) *ptr++];
}
x -= length/2;
@@ -2034,11 +2610,11 @@ int Hardware_RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha
case AVPMENUFORMAT_RIGHTJUSTIFIED:
{
int length = 0;
- signed char *ptr = (signed char*) textPtr;
+ char *ptr = textPtr;
while(*ptr)
{
- length+=AAFontWidths[*ptr++];
+ length+=AAFontWidths[(unsigned char) *ptr++];
}
x -= length;
@@ -2047,11 +2623,11 @@ int Hardware_RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha
case AVPMENUFORMAT_CENTREJUSTIFIED:
{
int length = 0;
- signed char *ptr = (signed char*) textPtr;
+ char *ptr = textPtr;
while(*ptr)
{
- length+=AAFontWidths[*ptr++];
+ length+=AAFontWidths[(unsigned char) *ptr++];
}
x -= length/2;
@@ -2489,7 +3065,8 @@ void D3D_DrawColourBar(int yTop, int yBottom, int rScale, int gScale, int bScale
int a;
int start;
- CheckTriangleBuffer(256*2, 0, 255*2, 0, NULL, TRANSLUCENCY_OFF, -1);
+ CheckTriangleBuffer(256*2, 255*2, NULL, TRANSLUCENCY_OFF, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
start = varrc;
@@ -2593,8 +3170,9 @@ void ColourFillBackBufferQuad(int FillColour, int x0, int y0, int x1, int y1)
if (y1 <= y0)
return;
- CheckTriangleBuffer(4, 0, 0, 0, NULL, TRANSLUCENCY_OFF, -1);
-
+ CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
b = ((FillColour >> 0) & 0xFF);
g = ((FillColour >> 8) & 0xFF);
r = ((FillColour >> 16) & 0xFF);
@@ -2741,7 +3319,8 @@ void BltImage(RECT *dest, DDSurface *image, RECT *src)
s[3] = src->left * image->RecipW;
t[3] = src->bottom * image->RecipH;
- CheckTriangleBuffer(4, 0, 0, 0, image, TRANSLUCENCY_OFF, -1);
+ CheckTriangleBuffer(4, 0, image, TRANSLUCENCY_OFF, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
for (i = 0; i < 4; i++) {
varrp->v[0] = x[i];
@@ -2834,8 +3413,9 @@ void D3D_DrawParticle_Rain(PARTICLE *particlePtr,VECTORCH *prevPositionPtr)
ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
- CheckTriangleBuffer(3, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL, -1);
-
+ CheckTriangleBuffer(3, 0, NULL, TRANSLUCENCY_NORMAL, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
+
for (i = 0; i < 3; i++) {
GLfloat xf, yf, zf;
GLfloat w;
@@ -2968,7 +3548,7 @@ void PostLandscapeRendering()
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
@@ -3000,7 +3580,7 @@ void PostLandscapeRendering()
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
@@ -3340,7 +3920,7 @@ void PostLandscapeRendering()
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
@@ -3369,7 +3949,7 @@ void PostLandscapeRendering()
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
@@ -3436,7 +4016,7 @@ void PostLandscapeRendering()
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
D3D_DrawWaterPatch(x, y, z+MeshZScale);
@@ -3518,7 +4098,7 @@ void D3D_DrawWaterTest(MODULE *testModulePtr)
MeshZScale/=2;
CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture;
- CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
+ CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
D3D_DrawWaterPatch(x, y, z);
D3D_DrawWaterPatch(x+MeshXScale, y, z);
D3D_DrawWaterPatch(x, y, z+MeshZScale);
@@ -4708,8 +5288,9 @@ void D3D_DrawMoltenMetalMesh_Unclipped(void)
int i, x, y, z;
int start;
- CheckTriangleBuffer(256, 0, 450, 0, (D3DTexture *)-1, -1, -1);
-
+ CheckTriangleBuffer(256, 450, (D3DTexture *)-1, -1, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
+
start = varrc;
for (i=0; i<256; i++) {
GLfloat xf, yf, zf;
@@ -4807,7 +5388,8 @@ void D3D_DrawMoltenMetalMesh_Clipped(void)
}
}
- CheckTriangleBuffer(256, 0, c, 0, (D3DTexture *)-1, -1, -1);
+ CheckTriangleBuffer(256, c, (D3DTexture *)-1, -1, -1);
+ SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
start = varrc;
for (i=0; i<256; i++)