From 219044abf9841461043d6e2acf0d5a48a7c7648b Mon Sep 17 00:00:00 2001 From: yinsimei Date: Fri, 26 May 2017 05:24:38 +0200 Subject: SLUDGE: Add sludge files and make it compile --- engines/sludge/graphics.cpp | 956 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 956 insertions(+) create mode 100644 engines/sludge/graphics.cpp (limited to 'engines/sludge/graphics.cpp') diff --git a/engines/sludge/graphics.cpp b/engines/sludge/graphics.cpp new file mode 100644 index 0000000000..8bdc917515 --- /dev/null +++ b/engines/sludge/graphics.cpp @@ -0,0 +1,956 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ +#if 0 +#include + +#include +#endif + +#include "allfiles.h" +#include "debug.h" +#include "platform-dependent.h" +#include "CommonCode/specialsettings.h" +#include "graphics.h" +#include "language.h" +#include "newfatal.h" +#include "sprbanks.h" +#include "zbuffer.h" +#include "backdrop.h" +#include "shaders.h" +#include "movie.h" +#include "stringy.h" + +#include "language.h" // for settings + +#if 0 +#if !defined(HAVE_GLES2) +#ifdef _WIN32 +#include // handy for gluErrorString +#elif defined __APPLE__ +#include +#else +#include +#endif +#endif +#endif + +unsigned int winWidth, winHeight; +int viewportHeight, viewportWidth; +int viewportOffsetX = 0, viewportOffsetY = 0; + +extern float cameraZoom; + +bool NPOT_textures = true; + +extern int specialSettings; + +void setMovieViewport(); + +#if 0 +extern GLuint backdropTextureName; +extern GLuint snapshotTextureName; +#endif + +extern unsigned int sceneWidth, sceneHeight; +extern zBufferData zBuffer; +extern int lightMapNumber; +#if 0 +extern GLuint yTextureName; +extern GLuint uTextureName; +extern GLuint vTextureName; +//extern GLubyte * ytex, * utex, * vtex; + +shaders shader; +GLfloat aPMVMatrix[16]; + +void sludgeDisplay(); + +GLfloat primaryColor[4]; +GLfloat secondaryColor[4]; +#endif + +struct textureList *firstTexture = NULL; + +textureList *addTexture() { + textureList *newTexture = new textureList; + newTexture -> next = firstTexture; + firstTexture = newTexture; + return newTexture; +} + +#if 0 +void deleteTextures(GLsizei n, const GLuint *textures) { + if (firstTexture == NULL) { + //debugOut("Deleting texture while list is already empty.\n"); + } else { + for (int i = 0; i < n; i++) { + bool found = false; + textureList *list = firstTexture; + if (list->name == textures[i]) { + found = true; + firstTexture = list->next; + delete list; + continue; + } + + while (list->next) { + if (list->next->name == textures[i]) { + found = true; + textureList *deleteMe = list->next; + list->next = list->next->next; + delete deleteMe; + break; + } + list = list->next; + } + //if (!found) + // debugOut("Deleting texture that was not in list.\n"); + } + } + + glDeleteTextures(n, textures); + +} + +void getTextureDimensions(GLuint name, GLint *width, GLint *height) { + textureList *list = firstTexture; + while (list) { + if (list->name == name) { + *width = list->width; + *height = list->height; +#if !defined(HAVE_GLES2) + //For the following test it is assumed that glBindTexture is always + //called for the right texture before getTextureDimensions. + GLint tw, th; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tw); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &th); + if (tw != *width || th != *height) { + debugOut("Warning: Texture dimensions don't match: They are %ix%i, but SLUDGEs bookkeeping says %ix%i.\n", tw, th, *width, *height); + } +#endif + return; + } + list = list->next; + } + fatal("Texture not found in list.\n"); +} + +void storeTextureDimensions(GLuint name, GLsizei width, GLsizei height, const char *file, int line) { + if (! NPOT_textures && !(((height & (height - 1)) == 0) || ((width & (width - 1)) == 0))) { + debugOut("I was told to create a texture with dimensions %ix%i in %s @ line %d although NPOT textures are disabled.\n", width, height, file, line); + //height = getNextPOT(height); + //width = getNextPOT(width); + } + + textureList *list = firstTexture; + while (list) { + if (list->name == name) { + //debugOut("Texture dimensions are overwritten.\n"); + break; + } + list = list->next; + } + if (list == NULL) { + list = addTexture(); + } + list->name = name; + list->width = width; + list->height = height; + +} +#endif + +#ifdef HAVE_GLES2 +void glesCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + // Work around for broken glCopy(Sub)TexImage2D... + void *tmp = malloc(width * height * 4); + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp); + free(tmp); +} +void glesCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + // Work around for broken glCopy(Sub)TexImage2D... + void *tmp = malloc(width * height * 4); + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp); + glTexImage2D(target, level, GL_RGBA, width, height, border, GL_RGBA, GL_UNSIGNED_BYTE, tmp); + free(tmp); +} +#endif + +#if 0 +void dcopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border, GLuint name, const char *file, int line) { + + glBindTexture(GL_TEXTURE_2D, name); +#ifdef HAVE_GLES2_ + glesCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +#else + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +#endif +} + +void dcopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLuint name, const char *file, int line) { + glBindTexture(GL_TEXTURE_2D, name); +#ifdef HAVE_GLES2_ + glesCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +#else + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +#endif +} + +void dtexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, const GLvoid *data, GLuint name, const char *file, int line) { + storeTextureDimensions(name, width, height, file, line); + glBindTexture(GL_TEXTURE_2D, name); + glTexImage2D(target, level, internalformat, width, height, border, format, type, data); +} + +void dtexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *data, GLuint name, const char *file, int line) { + storeTextureDimensions(name, width, height, file, line); + glBindTexture(GL_TEXTURE_2D, name); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, data); +} + +void setPrimaryColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + primaryColor[0] = r; + primaryColor[1] = g; + primaryColor[2] = b; + primaryColor[3] = a; +} + +void setSecondaryColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + secondaryColor[0] = r; + secondaryColor[1] = g; + secondaryColor[2] = b; + secondaryColor[3] = a; +} + +void drawQuad(GLint program, const GLfloat *vertices, int numTexCoords, ...) { + int i, vertexLoc, texCoordLocs[numTexCoords]; + const GLfloat *texCoords[numTexCoords]; + + va_list vl; + va_start(vl, numTexCoords); + for (i = 0; i < numTexCoords; i++) { + texCoords[i] = va_arg(vl, const GLfloat *); + } + va_end(vl); + + glUniform4f(glGetUniformLocation(program, "myColor"), primaryColor[0], primaryColor[1], primaryColor[2], primaryColor[3]); + if (program == shader.smartScaler || program == shader.paste) { + glUniform4f(glGetUniformLocation(program, "mySecondaryColor"), secondaryColor[0], secondaryColor[1], secondaryColor[2], secondaryColor[3]); + } + + vertexLoc = glGetAttribLocation(program, "myVertex"); + texCoordLocs[0] = glGetAttribLocation(program, "myUV0"); + if (numTexCoords > 1) texCoordLocs[1] = glGetAttribLocation(program, "myUV1"); + if (numTexCoords > 2) texCoordLocs[2] = glGetAttribLocation(program, "myUV2"); + if (numTexCoords > 3) texCoordLocs[3] = glGetAttribLocation(program, "myUV3"); + + glEnableVertexAttribArray(vertexLoc); + glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices); + + for (i = 0; i < numTexCoords; i++) { + if (texCoords[i]) { + glEnableVertexAttribArray(texCoordLocs[i]); + glVertexAttribPointer(texCoordLocs[i], 2, GL_FLOAT, GL_FALSE, 0, texCoords[i]); + } + } + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + for (i = 0; i < numTexCoords; i++) { + if (texCoords[i]) { + glDisableVertexAttribArray(texCoordLocs[i]); + } + } + glDisableVertexAttribArray(vertexLoc); + +} + + +void setPMVMatrix(GLint program) { + glUniformMatrix4fv(glGetUniformLocation(program, "myPMVMatrix"), 1, GL_FALSE, aPMVMatrix); +} +#endif +// This is for swapping settings between rendering to texture or to the screen +void setPixelCoords(bool pixels) { + static int current = -1; +// if (current == pixels) return; + current = pixels; +#if 0 + glBindTexture(GL_TEXTURE_2D, backdropTextureName); + + if (pixels) { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glClear(GL_COLOR_BUFFER_BIT); + + const GLfloat bPMVMatrix[] = { + 2.0f / viewportWidth, .0, .0, .0, + .0, 2.0f / viewportHeight, .0, .0, + .0, .0, 1.0f, .0, + -1.0, -1.0f, .0, 1.0f + + }; + for (int i = 0; i < 16; i++) { + aPMVMatrix[i] = bPMVMatrix[i]; + } + } else { + if (gameSettings.antiAlias < 0) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + GLfloat w = (GLfloat) winWidth / cameraZoom; + GLfloat h = (GLfloat) winHeight / cameraZoom; + + const GLfloat bPMVMatrix[] = { + 2.0f / w, .0, .0, .0, + .0, -2.0f / h, .0, .0, + .0, .0, 1.0f, .0, + -1.0, 1.0f, .0, 1.0f + + }; + for (int i = 0; i < 16; i++) { + aPMVMatrix[i] = bPMVMatrix[i]; + } + } +#endif +} + +int desktopW = 0, desktopH = 0; +bool runningFullscreen = false; + + +#if defined(HAVE_GLES2) +void saveTexture(GLuint tex, GLubyte *data) { + // use an FBO to easily grab the texture... + static GLuint fbo = 0; + GLuint old_fbo; + GLint tw, th; + GLint old_vp[4]; + if (fbo == 0) { + glGenFramebuffers(1, &fbo); + } + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&old_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + getTextureDimensions(tex, &tw, &th); + glGetIntegerv(GL_VIEWPORT, old_vp); + glViewport(0, 0, tw, th); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glReadPixels(0, 0, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, data); + glViewport(old_vp[0], old_vp[1], old_vp[2], old_vp[3]); + glBindFramebuffer(GL_FRAMEBUFFER, old_fbo); +} +#elif defined _WIN32 +// Replacement for glGetTexImage, because some ATI drivers are buggy. +void saveTexture(GLuint tex, GLubyte *data) { + setPixelCoords(true); + + glBindTexture(GL_TEXTURE_2D, tex); + + GLint tw, th; + getTextureDimensions(tex, &tw, &th); + + //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + int xoffset = 0; + while (xoffset < tw) { + int w = (tw - xoffset < viewportWidth) ? tw - xoffset : viewportWidth; + + int yoffset = 0; + while (yoffset < th) { + int h = (th - yoffset < viewportHeight) ? th - yoffset : viewportHeight; + + glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen + + const GLfloat vertices[] = { + (GLfloat) - xoffset, (GLfloat) - yoffset, 0.f, + (GLfloat)tw - xoffset, (GLfloat) - yoffset, 0.f, + (GLfloat) - xoffset, (GLfloat) - yoffset + th, 0.f, + (GLfloat)tw - xoffset, (GLfloat) - yoffset + th, 0.f + }; + + const GLfloat texCoords[] = { + 0.0f, 0.0f, + 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f + }; + + glUseProgram(shader.texture); + setPMVMatrix(shader.texture); + + drawQuad(shader.texture, vertices, 1, texCoords); + glUseProgram(0); + + for (int i = 0; i < h; i++) { + glReadPixels(viewportOffsetX, viewportOffsetY + i, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, data + xoffset * 4 + (yoffset + i) * 4 * tw); + } + + yoffset += viewportHeight; + } + + xoffset += viewportWidth; + } + //glReadPixels(viewportOffsetX, viewportOffsetY, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, data); + + setPixelCoords(false); + +} +#else +#if 0 +void saveTexture(GLuint tex, GLubyte *data) { + + glBindTexture(GL_TEXTURE_2D, tex); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); +} +#endif +#endif + +// This is for setting windowed or fullscreen graphics. +// Used for switching, and for initial window creation. +void setGraphicsWindow(bool fullscreen, bool restoreGraphics, bool resize) { +#if defined(PANDORA) + fullscreen = true; +#endif +#if 0 + GLubyte *snapTexture = NULL; + + Uint32 videoflags = 0; + + if (! desktopW) { + + // Get video hardware information + const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); + desktopW = videoInfo->current_w; + desktopH = videoInfo->current_h; + + } else if (restoreGraphics && fullscreen == runningFullscreen & ! resize) return; + + runningFullscreen = fullscreen; + + if (restoreGraphics) { + /* + * Save the textures + */ + if (backdropTextureName) { + if (backdropTexture) delete backdropTexture; + int picWidth = sceneWidth; + int picHeight = sceneHeight; + if (! NPOT_textures) { + picWidth = getNextPOT(picWidth); + picHeight = getNextPOT(picHeight); + } + backdropTexture = new GLubyte [picHeight * picWidth * 4]; + if (! checkNew(backdropTexture)) return; + + saveTexture(backdropTextureName, backdropTexture); + } + if (snapshotTextureName) { + int picWidth = winWidth; + int picHeight = winHeight; + if (! NPOT_textures) { + picWidth = getNextPOT(picWidth); + picHeight = getNextPOT(picHeight); + } + snapTexture = new GLubyte [picHeight * picWidth * 4]; + if (! checkNew(snapTexture)) return; + + saveTexture(snapshotTextureName, snapTexture); + } + } + + /* + * Set the graphics mode + */ + float winAspect = (float) winWidth / winHeight; + + if (fullscreen) { + specialSettings &= ~SPECIAL_INVISIBLE; +#if !defined(HAVE_GLES2) + videoflags = SDL_OPENGL | SDL_FULLSCREEN; +#else + videoflags = SDL_SWSURFACE | SDL_FULLSCREEN; +#endif + + if (gameSettings.fixedPixels) { + viewportWidth = realWinWidth = winWidth; + viewportHeight = realWinHeight = winHeight; + viewportOffsetY = 0; + viewportOffsetX = 0; + } else { + realWinWidth = desktopW; + realWinHeight = desktopH; + + float realAspect = (float) realWinWidth / realWinHeight; + + if (realAspect > winAspect) { + viewportHeight = realWinHeight; + viewportWidth = (int)(realWinHeight * winAspect); + viewportOffsetY = 0; + viewportOffsetX = (realWinWidth - viewportWidth) / 2; + } else { + viewportWidth = realWinWidth; + viewportHeight = (int)((float) realWinWidth / winAspect); + viewportOffsetY = (realWinHeight - viewportHeight) / 2; + viewportOffsetX = 0; + } + } + + } else { +#if !defined(HAVE_GLES2) + videoflags = SDL_OPENGL/* | SDL_RESIZABLE*/; +#else + videoflags = SDL_SWSURFACE; +#endif + + if (resize) { + float realAspect = (float) desktopW / desktopH; + + if (realAspect > winAspect) { + realWinWidth = (int)(realWinHeight * winAspect); + } else { + realWinHeight = (int)(realWinWidth / winAspect); + } + + realAspect = (float) realWinWidth / realWinHeight; + + if (realAspect > winAspect) { + viewportHeight = realWinHeight; + viewportWidth = (int)(realWinHeight * winAspect); + viewportOffsetY = 0; + viewportOffsetX = (realWinWidth - viewportWidth) / 2; + } else { + viewportWidth = realWinWidth; + viewportHeight = (int)((float) realWinWidth / winAspect); + viewportOffsetY = (realWinHeight - viewportHeight) / 2; + viewportOffsetX = 0; + } + } else { + + if (gameSettings.fixedPixels) { + viewportWidth = realWinWidth = winWidth; + viewportHeight = realWinHeight = winHeight; + viewportOffsetY = 0; + viewportOffsetX = 0; + } else { + realWinHeight = desktopH * 3 / 4; + realWinWidth = (int)(realWinHeight * winAspect); + + if (realWinWidth > desktopW) { + realWinWidth = desktopW; + realWinHeight = (int)((float) realWinWidth / winAspect); + } + + viewportHeight = realWinHeight; + viewportWidth = realWinWidth; + viewportOffsetY = 0; + viewportOffsetX = 0; + } + } + } + + debugHeader(); + + if (SDL_SetVideoMode(realWinWidth, realWinHeight, 32, videoflags) == 0) { + msgBox("Startup Error: Couldn't set video mode.", SDL_GetError()); + SDL_Quit(); + exit(2); + } + debugOut("Video mode %d %d set successfully.\n", realWinWidth, realWinHeight); + +#if defined(HAVE_GLES2) + if (EGL_Open()) { + msgBox("Startup Error", "Couldn't initialize EGL."); + SDL_Quit(); + exit(1); + } + EGL_Init(); +#endif + + GLint uniform; + const char *Vertex; + const char *Fragment; + + Vertex = shaderFileRead("scale.vert"); + +#if !defined(HAVE_GLES2) + Fragment = shaderFileRead("scale.frag"); +#else + /* const GLubyte *str; + int glDerivativesAvailable; + str = glGetString (GL_EXTENSIONS); + glDerivativesAvailable = (strstr((const char *)str, "GL_OES_standard_derivatives") != NULL); + if (!glDerivativesAvailable) { + debugOut("Extension \"GL_OES_standard_derivatives\" not available. Advanced anti-aliasing is not possible. Using linear anti-aliasing instead."); + gameSettings.antiAlias = -1; + */ + Fragment = shaderFileRead("scale_noaa.frag"); +// } + + Fragment = joinStrings("precision mediump float;\n", Fragment); +#endif + + if (! Vertex || ! Fragment) { + fatal("Error loading \"scale\" shader program!", "Try re-installing the game. (scale.frag, scale_noaa.frag or scale.vert was not found.)"); + gameSettings.antiAlias = -1; + shader.smartScaler = 0; + } else { + + shader.smartScaler = buildShaders(Vertex, Fragment); + + if (! shader.smartScaler) { + fatal("Error building \"scale\" shader program!"); + gameSettings.antiAlias = -1; + shader.smartScaler = 0; + } else { + debugOut("Built shader program: %d (smartScaler)\n", shader.smartScaler); + + glUseProgram(shader.smartScaler); + uniform = glGetUniformLocation(shader.smartScaler, "Texture"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.smartScaler, "lightTexture"); + if (uniform >= 0) glUniform1i(uniform, 1); + uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.smartScaler, "antialias"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.smartScaler, "scale"); + + float scale = (float)realWinWidth / (float)winWidth * 0.25; + if (scale > 1.0) scale = 1.0; + if (uniform >= 0) glUniform1f(uniform, scale); + + } + } + + Vertex = shaderFileRead("fixScaleSprite.vert"); + Fragment = shaderFileRead("fixScaleSprite.frag"); + +#if defined(HAVE_GLES2) + Fragment = joinStrings("precision mediump float;\n", Fragment); +#endif + + if (! Vertex || ! Fragment) { + fatal("Error loading \"fixScaleSprite\" shader program!", "Try re-installing the game. (fixScaleSprite.frag or fixScaleSprite.vert was not found.)"); + shader.paste = 0; + } else { + + shader.paste = buildShaders(Vertex, Fragment); + if (! shader.paste) { + fatal("Error building \"fixScaleSprite\" shader program!"); + } else { + debugOut("Built shader program: %d (fixScaleSprite)\n", shader.paste); + + glUseProgram(shader.paste); + uniform = glGetUniformLocation(shader.paste, "tex0"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.paste, "tex1"); + if (uniform >= 0) glUniform1i(uniform, 1); + uniform = glGetUniformLocation(shader.paste, "tex2"); + if (uniform >= 0) glUniform1i(uniform, 2); + uniform = glGetUniformLocation(shader.paste, "useLightTexture"); + if (uniform >= 0) glUniform1i(uniform, 0); + + } + } + + Vertex = shaderFileRead("yuv.vert"); + Fragment = shaderFileRead("yuv.frag"); + +#if defined(HAVE_GLES2) + Fragment = joinStrings("precision mediump float;\n", Fragment); +#endif + + if (! Vertex || ! Fragment) { + fatal("Error loading \"yuv\" shader program!", "Try re-installing the game. (yuv.frag or yuv.vert was not found.)"); + shader.yuv = 0; + } else { + + shader.yuv = buildShaders(Vertex, Fragment); + if (! shader.yuv) { + fatal("Error building \"yuv\" shader program!"); + } else { + debugOut("Built shader program: %d (yuv)\n", shader.yuv); + + glUseProgram(shader.yuv); + uniform = glGetUniformLocation(shader.yuv, "Ytex"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.yuv, "Utex"); + if (uniform >= 0) glUniform1i(uniform, 1); + uniform = glGetUniformLocation(shader.yuv, "Vtex"); + if (uniform >= 0) glUniform1i(uniform, 2); + + } + } + + Vertex = shaderFileRead("texture.vert"); + Fragment = shaderFileRead("texture.frag"); + +#if defined(HAVE_GLES2) + Fragment = joinStrings("precision mediump float;\n", Fragment); +#endif + + if (! Vertex || ! Fragment) { + fatal("Error loading \"texture\" shader program!", "Try re-installing the game. (texture.frag or texture.vert was not found.)"); + shader.texture = 0; + } else { + + shader.texture = buildShaders(Vertex, Fragment); + if (! shader.texture) { + fatal("Error building \"texture\" shader program!"); + } else { + debugOut("Built shader program: %d (texture)\n", shader.texture); + + glUseProgram(shader.texture); + uniform = glGetUniformLocation(shader.texture, "sampler2d"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.texture, "zBuffer"); + if (uniform >= 0) glUniform1i(uniform, 0); + uniform = glGetUniformLocation(shader.texture, "zBufferLayer"); + if (uniform >= 0) glUniform1f(uniform, 0.); + uniform = glGetUniformLocation(shader.texture, "modulateColor"); + if (uniform >= 0) glUniform1i(uniform, 0); + } + } + + Vertex = shaderFileRead("color.vert"); + Fragment = shaderFileRead("color.frag"); + +#if defined(HAVE_GLES2) + Fragment = joinStrings("precision mediump float;\n", Fragment); +#endif + + if (! Vertex || ! Fragment) { + fatal("Error loading \"color\" shader program!", "Try re-installing the game. (color.frag or color.vert was not found.)"); + shader.color = 0; + } else { + + shader.color = buildShaders(Vertex, Fragment); + if (! shader.color) { + fatal("Error building \"color\" shader program!"); + } else { + debugOut("Built shader program: %d (color)\n", shader.color); + glUseProgram(shader.color); + } + } + glUseProgram(0); + + glViewport(viewportOffsetX, viewportOffsetY, viewportWidth, viewportHeight); + + /* + * Set up OpenGL for 2D rendering. + */ + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + setPixelCoords(false); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + if (restoreGraphics) { + /* + * Restore the textures + */ + if (backdropTextureName) { + if (!glIsTexture(backdropTextureName)) { + glGenTextures(1, &backdropTextureName); + } + glBindTexture(GL_TEXTURE_2D, backdropTextureName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (gameSettings.antiAlias < 0) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + // Restore the backdrop + texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sceneWidth, sceneHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, backdropTextureName); + + } + if (snapshotTextureName) { + if (!glIsTexture(snapshotTextureName)) { + glGenTextures(1, &snapshotTextureName); + } + glBindTexture(GL_TEXTURE_2D, snapshotTextureName); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // Restore the backdrop + texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, winWidth, winHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, snapTexture, snapshotTextureName); + delete snapTexture; + } + + if (yTextureName) { + if (!glIsTexture(yTextureName)) { + glGenTextures(1, &yTextureName); + glGenTextures(1, &uTextureName); + glGenTextures(1, &vTextureName); + } + } + + + reloadSpriteTextures(); + reloadParallaxTextures(); + zBuffer.texName = 0; + if (zBuffer.numPanels) { + setZBuffer(zBuffer.originalNum); + } + lightMap.name = 0; + if (lightMapNumber) { + loadLightMap(lightMapNumber); + } + + sludgeDisplay(); + } + + if (movieIsPlaying) + setMovieViewport(); +#endif +} + +void setupOpenGLStuff() { + + /* + * Time to setup our requested window attributes for our OpenGL window. + * We want *at least* 8 bits of red, green and blue. We also want at least a 16-bit + * depth buffer. + * + * The last thing we do is request a double buffered window. '1' turns on double + * buffering, '0' turns it off. + */ +#if 0 + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +#endif + setGraphicsWindow(gameSettings.userFullScreen, false); + +#if !defined(HAVE_GLES2) +#if 0 + /* Check for graphics capabilities... */ + if (GLEE_VERSION_2_0) { + // Yes! Textures can be any size! + NPOT_textures = true; + debugOut("OpenGL 2.0! All is good.\n"); + } else { + if (GLEE_VERSION_1_5) { + debugOut("OpenGL 1.5!\n"); + } else if (GLEE_VERSION_1_4) { + debugOut("OpenGL 1.4!\n"); + } else if (GLEE_VERSION_1_3) { + debugOut("OpenGL 1.3!\n"); + } else if (GLEE_VERSION_1_2) { + debugOut("OpenGL 1.2!\n"); + } + + if (GLEE_ARB_texture_non_power_of_two) { + // Yes! Textures can be any size! + NPOT_textures = true; + } else { + // Workaround needed for lesser graphics cards. Let's hope this works... + NPOT_textures = false; + debugOut("Warning: Old graphics card! GLEE_ARB_texture_non_power_of_two not supported.\n"); + } + + if (GLEE_ARB_shading_language_100) { + debugOut("ARB_shading_language_100 supported.\n"); + } else { + debugOut("Warning: Old graphics card! ARB_shading_language_100 not supported. Try updating your drivers.\n"); + } + if (GLEE_ARB_shader_objects) { + debugOut("ARB_shader_objects supported.\n"); + } else { + fatal("Error: Old graphics card! ARB_shader_objects not supported.\n"); + } + if (GLEE_ARB_vertex_shader) { + debugOut("ARB_vertex_shader supported.\n"); + } else { + fatal("Error: Old graphics card! ARB_vertex_shader not supported.\n"); + } + if (GLEE_ARB_fragment_shader) { + debugOut("ARB_fragment_shader supported.\n"); + } else { + fatal("Error: Old graphics card! ARB_fragment_shader not supported.\n"); + } + } +#else + NPOT_textures = false; +#endif +#endif + int n; +#if 0 + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (GLint *) &n); +#endif + debugOut("Max texture image units: %d\n", n); + +} + + +// I found this function on a coding forum on the 'net. +// Looks a bit weird, but it should work. +int getNextPOT(int n) { + --n; + n |= n >> 16; + n |= n >> 8; + n |= n >> 4; + n |= n >> 2; + n |= n >> 1; + ++n; + return n; +} + +int printOglError(const char *file, int line) { + /* Returns 1 if an OpenGL error occurred, 0 otherwise. */ + int retCode = 0; +#if 0 + GLenum glErr; + + glErr = glGetError(); + while (glErr != GL_NO_ERROR) { +#if !defined(HAVE_GLES2) + debugOut("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr)); +#else + debugOut("glError in file %s @ line %d: error code %i\n", file, line, glErr); +#endif + retCode = 1; + glErr = glGetError(); + } +#endif + return retCode; +} -- cgit v1.2.3