void reloadParallaxTextures () { parallaxLayer * nP = parallaxStuff; if (! nP) return; while (nP) { //fprintf (stderr, "Reloading parallax. (%d, %d) ", nP->width, nP->height); nP->textureName = 0; glGenTextures (1, &nP->textureName); glBindTexture (GL_TEXTURE_2D, nP->textureName); if (nP -> wrapS) glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); else glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); if (nP -> wrapT) glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); else 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); } if (! NPOT_textures) { texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, getNextPOT(nP->width), getNextPOT(nP->height), 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName); } else { texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, nP->width, nP->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName); } nP = nP->next; } }
Texture::Texture(unsigned int p_width, unsigned int p_height, Texture::InternalFormat::Enum p_format): m_texture(generateTextureId()), m_width(p_width), m_height(p_height) { setFilterMode(FilterMode::Point); setWrapMode(WrapMode::ClampToEdge); texImage2D(p_format, p_width, p_height, NULL); }
GLuint loadTextureFromPNGData(png_byte* image_data, int &width, int &height) { if (image_data == NULL) LOGE("loadTextureFromPNGData:Image data == NULL"); GLuint texture = genTexture(); bindTexture2D(texture); texImage2D(width, height, static_cast<GLvoid*>(image_data)); texParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); texParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); return texture; }
bool restoreSnapshot (FILE * fp) { unsigned int picWidth = get2bytes (fp); unsigned int picHeight = get2bytes (fp); if ((picWidth != winWidth) || (picHeight != winHeight)) return false; unsigned int t1, t2, n; unsigned short c; GLubyte * target; if (! NPOT_textures) { picWidth = getNextPOT(picWidth); picHeight = getNextPOT(picHeight); snapTexW = ((double)winWidth) / picWidth; snapTexH = ((double)winHeight) / picHeight; } GLubyte * snapshotTexture = new GLubyte [picHeight*picWidth*4]; if (! snapshotTexture) return fatal("Out of memory while restoring snapshot."); for (t2 = 0; t2 < winHeight; t2 ++) { t1 = 0; while (t1 < winWidth) { c = (unsigned short) get2bytes (fp); if (c & 32) { n = fgetc (fp) + 1; c -= 32; } else { n = 1; } while (n --) { target = snapshotTexture + 4*picWidth*t2 + t1*4; target[0] = (GLubyte) redValue(c); target[1] = (GLubyte) greenValue(c); target[2] = (GLubyte) blueValue(c); target[3] = (GLubyte) 255; t1++; } } } if (! 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); texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, snapshotTexture, snapshotTextureName); delete snapshotTexture; snapshotTexture = NULL; return true; }
Texture::Texture(unsigned int p_width, unsigned int p_height, unsigned char p_byte): m_texture(generateTextureId()), m_width(p_width), m_height(p_height) { unsigned char* data = new unsigned char[p_width * p_height* 4]; std::fill(data, data + p_width * p_height * 4, p_byte); setFilterMode(FilterMode::Point); setWrapMode(WrapMode::ClampToEdge); texImage2D(InternalFormat::RGBA8, p_width, p_height, data); delete[] data; }
bool snapshot () { nosnapshot (); if (! freeze ()) return false; setPixelCoords (true); glGenTextures (1, &snapshotTextureName); int w = winWidth; int h = winHeight; if (! NPOT_textures) { w = getNextPOT(winWidth); h = getNextPOT(winHeight); snapTexW = ((double)winWidth) / w; snapTexH = ((double)winHeight) / h; } 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); texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, snapshotTextureName); // Render scene glDepthMask (GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen glDepthMask (GL_FALSE); drawBackDrop (); // Draw the room drawZBuffer(cameraX, cameraY, false); glEnable(GL_DEPTH_TEST); drawPeople (); // Then add any moving characters... glDisable(GL_DEPTH_TEST); viewSpeech (); // ...and anything being said drawStatusBar (); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewportOffsetX, viewportOffsetY, winWidth, winHeight, snapshotTextureName); setPixelCoords (false); unfreeze (false); return true; }
bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment) { ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); std::unique_ptr<unsigned char[]> zero; if (!isResourceSafe() && width > 0 && height > 0) { unsigned int size; GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0); if (error != GraphicsContext3D::NO_ERROR) { synthesizeGLError(error); return false; } zero = std::make_unique<unsigned char[]>(size); if (!zero) { synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return false; } memset(zero.get(), 0, size); } return texImage2D(target, level, internalformat, width, height, border, format, type, zero.get()); }
GLuint loadTextureFromPNG(const ResourcePtr& pngData, int &width, int &height) { //Now generate the OpenGL texture object GLuint texture = genTexture(); bindTexture2D(texture); png_byte* image_data = loadImageFromPNG(pngData, width, height); // got this logic from android_source/frameworks/base/cmds/bootanimation/BootAnimation.cpp, // but it doesn't seem to work right. The odd-sized texture loads, but it is squished. I could probably fix // that, but I'm not going to worry about it for now. // int tw = 1 << (31 - __builtin_clz(width)); // int th = 1 << (31 - __builtin_clz(height)); // if (tw < width) tw <<= 1; // if (th < height) th <<= 1; // // if (tw != width || th != height) // { // GLint crop[4] = { 0, height, width, -height }; // texImage2D(tw, th, 0); // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, static_cast<GLvoid*>(image_data)); // checkGLError("glTexSubImage2D"); // glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); // checkGLError("glTexParameteriv"); // } // else // { texImage2D(width, height, static_cast<GLvoid*>(image_data)); // } texParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); texParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); // I thought these might help with random black pixels on the edge of a rotated texture, but they didn't. // texParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // texParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //clean up memory and close stuff //png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); //delete[] image_data; //delete[] row_pointers; delete[] image_data; return texture; }
bool reserveBackdrop () { cameraX = 0; cameraY = 0; input.mouseX = (int)((float)input.mouseX * cameraZoom); input.mouseY = (int)((float)input.mouseY * cameraZoom); cameraZoom = 1.0; input.mouseX = (int)((float)input.mouseX / cameraZoom); input.mouseY = (int)((float)input.mouseY / cameraZoom); setPixelCoords(false); int picWidth = sceneWidth; int picHeight = sceneHeight; glPixelStorei (GL_UNPACK_ALIGNMENT, 1); if (backdropTexture) delete backdropTexture; if (! NPOT_textures) { picWidth = getNextPOT(sceneWidth); picHeight = getNextPOT(sceneHeight); backdropTexW = ((double)sceneWidth) / picWidth; backdropTexH = ((double)sceneHeight) / picHeight; } backdropTexture = new GLubyte [picWidth*picHeight*4]; if (! checkNew (backdropTexture)) return false; if (! 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); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, backdropTextureName); return true; }
bool loadHSI (FILE * fp, int x, int y, bool reserve) { int t1, t2, n; unsigned short c; GLubyte * target; int32_t transCol = reserve ? -1 : 63519; int picWidth; int picHeight; int realPicWidth, realPicHeight; long file_pointer = ftell (fp); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; size_t bytes_read = fread(tmp, 1, 8, fp); if (bytes_read != 8 && ferror (fp)) { debugOut("Reading error in loadHSI.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(fp, file_pointer, SEEK_SET); picWidth = realPicWidth = get2bytes (fp); picHeight = realPicHeight = get2bytes (fp); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, fp); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); picWidth = realPicWidth = width; picHeight = realPicHeight = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); //int rowbytes = png_get_rowbytes(png_ptr, info_ptr); } GLfloat texCoordW = 1.0; GLfloat texCoordH = 1.0; if (! NPOT_textures) { picWidth = getNextPOT(picWidth); picHeight = getNextPOT(picHeight); texCoordW = ((double)realPicWidth) / picWidth; texCoordH = ((double)realPicHeight) / picHeight; } if (reserve) { if (! resizeBackdrop (realPicWidth, realPicHeight)) return false; } if (x == IN_THE_CENTRE) x = (sceneWidth - realPicWidth) >> 1; if (y == IN_THE_CENTRE) y = (sceneHeight - realPicHeight) >> 1; if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) return false; if (fileIsPNG) { unsigned char * row_pointers[realPicHeight]; for (int i = 0; i<realPicHeight; i++) row_pointers[i] = backdropTexture + 4*i*picWidth; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { for (t2 = 0; t2 < realPicHeight; t2 ++) { t1 = 0; while (t1 < realPicWidth) { c = (unsigned short) get2bytes (fp); if (c & 32) { n = fgetc (fp) + 1; c -= 32; } else { n = 1; } while (n --) { target = backdropTexture + 4*picWidth*t2 + t1*4; if (c == transCol || c == 2015) { target[0] = (GLubyte) 0; target[1] = (GLubyte) 0; target[2] = (GLubyte) 0; target[3] = (GLubyte) 0; } else { target[0] = (GLubyte) redValue(c); target[1] = (GLubyte) greenValue(c); target[2] = (GLubyte) blueValue(c); target[3] = (GLubyte) 255; } t1++; } } } } GLuint tmpTex; glGenTextures (1, &tmpTex); glBindTexture(GL_TEXTURE_2D, tmpTex); 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); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, tmpTex); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); float btx1; float btx2; float bty1; float bty2; if (! NPOT_textures) { btx1 = backdropTexW * x / sceneWidth; btx2 = backdropTexW * (x+realPicWidth) / sceneWidth; bty1 = backdropTexH * y / sceneHeight; bty2 = backdropTexH * (y+realPicHeight) / sceneHeight; } else { btx1 = (float) x / sceneWidth; btx2 = (float) (x+realPicWidth) / sceneWidth; bty1 = (float) y / sceneHeight; bty2 = (float) (y+realPicHeight) / sceneHeight; } const GLfloat btexCoords[] = { btx1, bty1, btx2, bty1, btx1, bty2, btx2, bty2 }; setPixelCoords (true); int xoffset = 0; while (xoffset < realPicWidth) { int w = (realPicWidth-xoffset < viewportWidth) ? realPicWidth-xoffset : viewportWidth; int yoffset = 0; while (yoffset < realPicHeight) { int h = (realPicHeight-yoffset < viewportHeight) ? realPicHeight-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)realPicWidth-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)-yoffset+realPicHeight, 0., (GLfloat)realPicWidth-xoffset, (GLfloat)-yoffset+realPicHeight, 0. }; const GLfloat texCoords[] = { 0.0f, 0.0f, texCoordW, 0.0f, 0.0f, texCoordH, texCoordW, texCoordH }; if (backdropExists) { // Render the sprite to the backdrop // (using mulitexturing, so the old backdrop is seen where alpha < 1.0) glActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glActiveTexture(GL_TEXTURE0); glUseProgram(shader.paste); GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); // No lighting setPMVMatrix(shader.paste); setPrimaryColor(1.0, 1.0, 1.0, 1.0); glBindTexture(GL_TEXTURE_2D, tmpTex); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords); glUseProgram(0); } else { // It's all new - nothing special to be done. glUseProgram(shader.texture); setPMVMatrix(shader.texture); glBindTexture(GL_TEXTURE_2D, tmpTex); setPrimaryColor(1.0, 0.0, 0.0, 0.0); drawQuad(shader.texture, vertices, 1, texCoords); glUseProgram(0); } // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, x+xoffset, y+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } deleteTextures(1, &tmpTex); setPixelCoords (false); backdropExists = true; return true; }
bool loadParallax (unsigned short v, unsigned short fracX, unsigned short fracY) { setResourceForFatal (v); if (! openFileFromNum (v)) return fatal ("Can't open parallax image"); parallaxLayer * nP = new parallaxLayer; if (! checkNew (nP)) return false; nP -> next = parallaxStuff; parallaxStuff = nP; if (nP -> next) { nP -> next -> prev = nP; } nP -> prev = NULL; int picWidth; int picHeight; long file_pointer = ftell (bigDataFile); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; size_t bytes_read = fread(tmp, 1, 8, bigDataFile); if (bytes_read != 8 && ferror (bigDataFile)) { debugOut("Reading error in loadParallax.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(bigDataFile, file_pointer, SEEK_SET); picWidth = nP -> width = get2bytes (bigDataFile); picHeight = nP -> height = get2bytes (bigDataFile); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); picWidth = nP -> width = width; picHeight = nP -> height = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); //int rowbytes = png_get_rowbytes(png_ptr, info_ptr); } if (! NPOT_textures) { picWidth = getNextPOT(picWidth); picHeight = getNextPOT(picHeight); } nP -> fileNum = v; nP -> fractionX = fracX; nP -> fractionY = fracY; if (fracX == 65535) { nP -> wrapS = false; if (nP -> width < winWidth) { fatal ("For AUTOFIT parallax backgrounds, the image must be at least as wide as the game window/screen."); return false; } } else { nP -> wrapS = true; } if (fracY == 65535) { nP -> wrapT = false; if (nP -> height < winHeight) { fatal ("For AUTOFIT parallax backgrounds, the image must be at least as tall as the game window/screen."); return false; } } else { nP -> wrapT = true; } nP -> texture = new GLubyte [picHeight * picWidth * 4]; if (! checkNew (nP -> texture)) return false; if (fileIsPNG) { unsigned char * row_pointers[nP -> height]; for (int i = 0; i < nP -> height; i++) row_pointers[i] = nP -> texture + 4*i*picWidth; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { int t1, t2, n; unsigned short c; GLubyte * target; for (t2 = 0; t2 < nP -> height; t2 ++) { t1 = 0; while (t1 < nP -> width) { c = (unsigned short) get2bytes (bigDataFile); if (c & 32) { n = fgetc (bigDataFile) + 1; c -= 32; } else { n = 1; } while (n--) { target = nP -> texture + 4*picWidth*t2 + t1*4; if (c == 63519 || c == 2015) { target[0] = (GLubyte) 0; target[1] = (GLubyte) 0; target[2] = (GLubyte) 0; target[3] = (GLubyte) 0; } else { target[0] = (GLubyte) redValue(c); target[1] = (GLubyte) greenValue(c); target[2] = (GLubyte) blueValue(c); target[3] = (GLubyte) 255; } t1 ++; } } } } glGenTextures (1, &nP->textureName); glBindTexture (GL_TEXTURE_2D, nP->textureName); if (nP -> wrapS) glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); else glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); if (nP -> wrapT) glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); else 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); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nP->texture, nP->textureName); finishAccess (); setResourceForFatal (-1); return true; }
bool loadLightMap (int v) { int newPicWidth, newPicHeight; setResourceForFatal (v); if (! openFileFromNum (v)) return fatal ("Can't open light map."); long file_pointer = ftell (bigDataFile); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; size_t bytes_read = fread(tmp, 1, 8, bigDataFile); if (bytes_read != 8 && ferror (bigDataFile)) { debugOut("Reading error in loadLightMap.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(bigDataFile, file_pointer, SEEK_SET); newPicWidth = lightMap.w = get2bytes (bigDataFile); newPicHeight = lightMap.h = get2bytes (bigDataFile); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); newPicWidth = lightMap.w = width; newPicHeight = lightMap.h = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); //int rowbytes = png_get_rowbytes(png_ptr, info_ptr); } if (lightMapMode == LIGHTMAPMODE_HOTSPOT) { if (lightMap.w != sceneWidth || lightMap.h != sceneHeight) { return fatal ("Light map width and height don't match scene width and height. That is required for lightmaps in HOTSPOT mode."); } } if (! NPOT_textures) { newPicWidth = getNextPOT(lightMap.w); newPicHeight = getNextPOT(lightMap.h); lightMap.texW = (double) lightMap.w / newPicWidth; lightMap.texH = (double) lightMap.h / newPicHeight; } else { lightMap.texW = 1.0; lightMap.texH = 1.0; } killLightMap (); lightMapNumber = v; glPixelStorei (GL_UNPACK_ALIGNMENT, 1); if (lightMap.data) delete [] lightMap.data; lightMap.data = new GLubyte [newPicWidth*newPicHeight*4]; if (! lightMap.data) { return fatal ("Out of memory loading light map."); } int t1, t2, n; unsigned short c; GLubyte * target; if (fileIsPNG) { unsigned char * row_pointers[lightMap.h]; for (int i = 0; i<lightMap.h; i++) row_pointers[i] = lightMap.data + 4*i*newPicWidth; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { for (t2 = 0; t2 < lightMap.h; t2 ++) { t1 = 0; while (t1 < lightMap.w) { c = (unsigned short) get2bytes (bigDataFile); if (c & 32) { n = fgetc (bigDataFile) + 1; c -= 32; } else { n = 1; } while (n --) { target = lightMap.data + 4*newPicWidth*t2 + t1*4; target[0] = (GLubyte) redValue(c); target[1] = (GLubyte) greenValue(c); target[2] = (GLubyte) blueValue(c); target[3] = (GLubyte) 255; t1++; } } } } if (! lightMap.name) glGenTextures (1, &lightMap.name); glBindTexture(GL_TEXTURE_2D, lightMap.name); 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); texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, newPicWidth, newPicHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, lightMap.data, lightMap.name); finishAccess (); setResourceForFatal (-1); return true; }
bool loadSpriteBank (int fileNum, spriteBank & loadhere, bool isFont) { int i, tex_num, total, picwidth, picheight, spriteBankVersion = 0, howmany=0, startIndex=0; int * totalwidth, * maxheight; int numTextures = 0; byte * data; setResourceForFatal (fileNum); if (! openFileFromNum (fileNum)) return fatal ("Can't open sprite bank / font"); loadhere.isFont = isFont; total = get2bytes (bigDataFile); if (! total) { spriteBankVersion = fgetc (bigDataFile); if (spriteBankVersion == 1) { total = 0; } else { total = get2bytes (bigDataFile); } } if (total <= 0) return fatal ("No sprites in bank or invalid sprite bank file"); if (spriteBankVersion > 3) return fatal ("Unsupported sprite bank file format"); loadhere.total = total; loadhere.sprites = new sprite [total]; if (! checkNew (loadhere.sprites)) return false; byte ** spriteData = new byte * [total]; if (! checkNew (spriteData)) return false; totalwidth = new int[total]; if (! checkNew (totalwidth)) return false; maxheight = new int[total]; if (! checkNew (maxheight)) return false; loadhere.myPalette.tex_names = new GLuint [total]; if (! checkNew (loadhere.myPalette.tex_names)) return false; if (isFont) { loadhere.myPalette.burnTex_names = new GLuint [total]; if (! checkNew (loadhere.myPalette.burnTex_names)) return false; } loadhere.myPalette.tex_w = new int [total]; if (! checkNew (loadhere.myPalette.tex_w)) return false; loadhere.myPalette.tex_h = new int [total]; if (! checkNew (loadhere.myPalette.tex_h)) return false; if (spriteBankVersion && spriteBankVersion < 3) { howmany = fgetc (bigDataFile); startIndex = 1; } totalwidth[0] = maxheight[0] = 1; for (i = 0; i < total; i ++) { switch (spriteBankVersion) { case 3: { loadhere.sprites[i].xhot = getSigned (bigDataFile); loadhere.sprites[i].yhot = getSigned (bigDataFile); png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return fatal ("Can't open sprite bank / font."); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return fatal ("Can't open sprite bank / font."); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return fatal ("Can't open sprite bank / font."); } png_init_io(png_ptr, bigDataFile); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // No sig png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); int rowbytes = png_get_rowbytes(png_ptr, info_ptr); unsigned char * row_pointers[height]; spriteData[i] = new unsigned char [rowbytes*height]; if (! checkNew (spriteData[i])) return false; for (unsigned int row = 0; row<height; row++) row_pointers[row] = spriteData[i] + row*rowbytes; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); picwidth = loadhere.sprites[i].width = width; picheight = loadhere.sprites[i].height = height; break; } case 2: picwidth = get2bytes (bigDataFile); picheight = get2bytes (bigDataFile); loadhere.sprites[i].xhot = getSigned (bigDataFile); loadhere.sprites[i].yhot = getSigned (bigDataFile); break; default: picwidth = (byte) fgetc (bigDataFile); picheight = (byte) fgetc (bigDataFile); loadhere.sprites[i].xhot = fgetc (bigDataFile); loadhere.sprites[i].yhot = fgetc (bigDataFile); break; } if (totalwidth[numTextures] + picwidth < 2047) { loadhere.sprites[i].tex_x = totalwidth[numTextures]; totalwidth[numTextures] += (loadhere.sprites[i].width = picwidth) + 1; if ((loadhere.sprites[i].height = picheight)+2 > maxheight[numTextures]) maxheight[numTextures] = picheight+2; } else { numTextures++; if (numTextures > 255) return fatal ("Can't open sprite bank / font - it's too big."); loadhere.sprites[i].tex_x = 0; totalwidth[numTextures] = (loadhere.sprites[i].width = picwidth); maxheight[numTextures] = loadhere.sprites[i].height = picheight; } loadhere.sprites[i].texNum = numTextures; if (spriteBankVersion < 3) { data = (byte *) new byte [picwidth * (picheight + 1)]; if (! checkNew (data)) return false; int ooo = picwidth * picheight; for (int tt = 0; tt < picwidth; tt ++) { data[ooo ++] = 0; } spriteData[i] = data; switch (spriteBankVersion) { case 2: // RUN LENGTH COMPRESSED DATA { unsigned size = picwidth * picheight; unsigned pip = 0; while (pip < size) { byte col = fgetc (bigDataFile); int looper; if (col > howmany) { col -= howmany + 1; looper = fgetc (bigDataFile) + 1; } else looper = 1; while (looper --) { data[pip ++] = col; } } } break; default: // RAW DATA size_t bytes_read = fread (data, picwidth, picheight, bigDataFile); if (bytes_read != picwidth * picheight && ferror (bigDataFile)) { debugOut("Reading error in loadSpriteBank.\n"); } break; } } } numTextures++; if (! spriteBankVersion) { howmany = fgetc (bigDataFile); startIndex = fgetc (bigDataFile); } if (spriteBankVersion < 3) { if (! reserveSpritePal (loadhere.myPalette, howmany + startIndex)) return false; for (i = 0; i < howmany; i ++) { loadhere.myPalette.r[i + startIndex] = (byte) fgetc (bigDataFile); loadhere.myPalette.g[i + startIndex] = (byte) fgetc (bigDataFile); loadhere.myPalette.b[i + startIndex] = (byte) fgetc (bigDataFile); loadhere.myPalette.pal[i + startIndex] = makeColour (loadhere.myPalette.r[i + startIndex], loadhere.myPalette.g[i + startIndex], loadhere.myPalette.b[i + startIndex]); } } loadhere.myPalette.originalRed = loadhere.myPalette.originalGreen = loadhere.myPalette.originalBlue = 255; loadhere.myPalette.numTextures = numTextures; GLubyte * tmp[numTextures]; GLubyte * tmp2[numTextures]; for (tex_num = 0; tex_num < numTextures; tex_num++) { if (! NPOT_textures) { totalwidth[tex_num] = getNextPOT(totalwidth[tex_num]); maxheight[tex_num] = getNextPOT(maxheight[tex_num]); } tmp[tex_num] = new GLubyte [(maxheight[tex_num]+1)*totalwidth[tex_num]*4]; if (! checkNew (tmp[tex_num])) return false; memset (tmp[tex_num], 0, maxheight[tex_num]*totalwidth[tex_num]*4); if (isFont) { tmp2[tex_num] = new GLubyte [(maxheight[tex_num]+1)*totalwidth[tex_num]*4]; if (! checkNew (tmp2[tex_num])) return false; memset (tmp2[tex_num], 0, maxheight[tex_num]*totalwidth[tex_num]*4); } loadhere.myPalette.tex_w[tex_num] = totalwidth[tex_num]; loadhere.myPalette.tex_h[tex_num] = maxheight[tex_num]; } int fromhere; unsigned char s; for (i = 0; i < total; i ++) { fromhere = 0; int transColour = -1; if (spriteBankVersion < 3) { int size = loadhere.sprites[i].height * loadhere.sprites[i].width; while (fromhere < size) { s = spriteData[i][fromhere++]; if (s) { transColour = s; break; } } fromhere = 0; } for (int y = 1; y < 1 + loadhere.sprites[i].height; y ++) { for (int x = loadhere.sprites[i].tex_x; x < loadhere.sprites[i].tex_x+loadhere.sprites[i].width; x ++) { GLubyte * target = tmp[loadhere.sprites[i].texNum] + 4*totalwidth[loadhere.sprites[i].texNum]*y + x*4; if (spriteBankVersion < 3) { s = spriteData[i][fromhere++]; if (s) { target[0] = (GLubyte) loadhere.myPalette.r[s]; target[1] = (GLubyte) loadhere.myPalette.g[s]; target[2] = (GLubyte) loadhere.myPalette.b[s]; target[3] = (GLubyte) 255; transColour = s; } else if (transColour >=0) { target[0] = (GLubyte) loadhere.myPalette.r[transColour]; target[1] = (GLubyte) loadhere.myPalette.g[transColour]; target[2] = (GLubyte) loadhere.myPalette.b[transColour]; target[3] = (GLubyte) 0; } if (isFont) { target = tmp2[loadhere.sprites[i].texNum] + 4*totalwidth[loadhere.sprites[i].texNum]*y + x*4; target[0] = (GLubyte) 255; target[1] = (GLubyte) 255; target[2] = (GLubyte) 255; if (s) target[3] = (GLubyte) loadhere.myPalette.r[s]; /*else target[3] = (GLubyte) 0;*/ } } else { target[0] = (GLubyte) spriteData[i][fromhere++]; target[1] = (GLubyte) spriteData[i][fromhere++]; target[2] = (GLubyte) spriteData[i][fromhere++]; target[3] = (GLubyte) spriteData[i][fromhere++]; } } } delete spriteData[i]; } delete spriteData; spriteData = NULL; glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glGenTextures (numTextures, loadhere.myPalette.tex_names); if (isFont) glGenTextures (numTextures, loadhere.myPalette.burnTex_names); for (tex_num = 0; tex_num < numTextures; tex_num++) { glBindTexture (GL_TEXTURE_2D, loadhere.myPalette.tex_names[tex_num]); 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); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, totalwidth[tex_num], maxheight[tex_num], 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp[tex_num], loadhere.myPalette.tex_names[tex_num]); delete tmp[tex_num]; tmp[tex_num] = NULL; if (isFont) { glBindTexture (GL_TEXTURE_2D, loadhere.myPalette.burnTex_names[tex_num]); 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); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, totalwidth[tex_num], maxheight[tex_num], 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp2[tex_num], loadhere.myPalette.burnTex_names[tex_num]); delete tmp2[tex_num]; tmp2[tex_num] = NULL; } } finishAccess (); setResourceForFatal (-1); return true; }