예제 #1
0
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;
	}
}
예제 #2
0
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);	
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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());
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}