Example #1
0
static inline u32 SampleNearest(int level, unsigned int u, unsigned int v)
{
	GETextureFormat texfmt = gstate.getTextureFormat();
	u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000);
	u8* srcptr = (u8*)Memory::GetPointer(texaddr); // TODO: not sure if this is the right place to load from...?

	// Special rules for kernel textures (PPGe), TODO: Verify!
	int texbufwidth = (texaddr < PSP_GetUserMemoryBase()) ? gstate.texbufwidth[level] & 0x1FFF : gstate.texbufwidth[level] & 0x7FF;

	// TODO: Should probably check if textures are aligned properly...

	if (texfmt == GE_TFMT_4444) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGBA4444(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_5551) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGBA5551(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_5650) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
		return DecodeRGB565(*(u16*)srcptr);
	} else if (texfmt == GE_TFMT_8888) {
		srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);
		return DecodeRGBA8888(*(u32*)srcptr);
	} else if (texfmt == GE_TFMT_CLUT32) {
		srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);

		u32 val = srcptr[0] + (srcptr[1] << 8) + (srcptr[2] << 16) + (srcptr[3] << 24);

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT16) {
		srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);

		u16 val = srcptr[0] + (srcptr[1] << 8);

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT8) {
		srcptr += GetPixelDataOffset(8, texbufwidth*8, u, v);

		u8 val = *srcptr;

		return LookupColor(GetClutIndex(val), level);
	} else if (texfmt == GE_TFMT_CLUT4) {
		srcptr += GetPixelDataOffset(4, texbufwidth*8, u, v);

		u8 val = (u & 1) ? (srcptr[0] >> 4) : (srcptr[0] & 0xF);

		return LookupColor(GetClutIndex(val), level);
	} else {
Example #2
0
// Copies RGBA8 data from RAM to the currently bound render target.
void CopyToCurrentFboFromRam(u8* data, int srcwidth, int srcheight, int dstwidth, int dstheight)
{
    glDisable(GL_BLEND);
	glViewport(0, 0, dstwidth, dstheight);
	glScissor(0, 0, dstwidth, dstheight);

	glBindTexture(GL_TEXTURE_2D, temp_texture);

	GLfloat texvert_u;
	if (gstate.FrameBufFormat() == GE_FORMAT_8888) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)gstate.FrameBufStride(), (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		texvert_u = (float)srcwidth / gstate.FrameBufStride();
	} else {
		// TODO: This should probably be converted in a shader instead..
		// TODO: Do something less brain damaged to manage this buffer...
		u32 *buf = new u32[srcwidth * srcheight];
		u16 *fb16 = (u16 *)fb;
		for (int y = 0; y < srcheight; ++y) {
			u32 *buf_line = &buf[y * srcwidth];
			u16 *fb_line = &fb16[y * gstate.FrameBufStride()];

			switch (gstate.FrameBufFormat()) {
			case GE_FORMAT_565:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGB565(fb_line[x]);
				}
				break;

			case GE_FORMAT_5551:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGBA5551(fb_line[x]);
				}
				break;

			case GE_FORMAT_4444:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGBA4444(fb_line[x]);
				}
				break;

			default:
				ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", gstate.FrameBufFormat());
			}
		}

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
		texvert_u = 1.0f;

		delete[] buf;
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glUseProgram(program);

	static const GLfloat verts[4][2] = {
		{ -1, -1}, // Left top
		{ -1,  1}, // left bottom
		{  1,  1}, // right bottom
		{  1, -1}  // right top
	};
	const GLfloat texverts[4][2] = {
		{0, 1},
		{0, 0},
		{texvert_u, 0},
		{texvert_u, 1}
	};

	glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
	glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts);
	glEnableVertexAttribArray(attr_pos);
	glEnableVertexAttribArray(attr_tex);
	glUniform1i(uni_tex, 0);
	glActiveTexture(GL_TEXTURE0);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	glDisableVertexAttribArray(attr_pos);
	glDisableVertexAttribArray(attr_tex);

	glBindTexture(GL_TEXTURE_2D, 0);
}
Example #3
0
// Copies RGBA8 data from RAM to the currently bound render target.
void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight)
{
	float dstwidth = (float)PSP_CoreParameter().pixelWidth;
	float dstheight = (float)PSP_CoreParameter().pixelHeight;

	glstate.blend.disable();
	glstate.viewport.set(0, 0, dstwidth, dstheight);
	glstate.scissorTest.disable();

	glBindTexture(GL_TEXTURE_2D, temp_texture);

	GLfloat texvert_u;
	if (displayFramebuf_ == 0) {
		u32 data[] = {0};
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		texvert_u = 1.0f;
	} else if (displayFormat_ == GE_FORMAT_8888) {
		u8 *data = Memory::GetPointer(displayFramebuf_);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)displayStride_, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		texvert_u = (float)srcwidth / displayStride_;
	} else {
		// TODO: This should probably be converted in a shader instead..
		// TODO: Do something less brain damaged to manage this buffer...
		u32 *buf = new u32[srcwidth * srcheight];
		FormatBuffer displayBuffer;
		displayBuffer.data = Memory::GetPointer(displayFramebuf_);
		for (int y = 0; y < srcheight; ++y) {
			u32 *buf_line = &buf[y * srcwidth];
			const u16 *fb_line = &displayBuffer.as16[y * displayStride_];

			switch (displayFormat_) {
			case GE_FORMAT_565:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGB565(fb_line[x]);
				}
				break;

			case GE_FORMAT_5551:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGBA5551(fb_line[x]);
				}
				break;

			case GE_FORMAT_4444:
				for (int x = 0; x < srcwidth; ++x) {
					buf_line[x] = DecodeRGBA4444(fb_line[x]);
				}
				break;

			default:
				ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_);
			}
		}

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)srcwidth, (GLsizei)srcheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
		texvert_u = 1.0f;

		delete[] buf;
	}

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glUseProgram(program);

	float x, y, w, h;
	CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, dstwidth, dstheight);

	x /= 0.5f * dstwidth;
	y /= 0.5f * dstheight;
	w /= 0.5f * dstwidth;
	h /= 0.5f * dstheight;
	float x2 = x + w;
	float y2 = y + h;
	x -= 1.0f;
	y -= 1.0f;
	x2 -= 1.0f;
	y2 -= 1.0f;

	const GLfloat verts[4][2] = {
		{ x, y }, // Left top
		{ x, y2}, // left bottom
		{ x2, y2}, // right bottom
		{ x2, y}  // right top
	};

	const GLfloat texverts[4][2] = {
		{0, 1},
		{0, 0},
		{texvert_u, 0},
		{texvert_u, 1}
	};

	glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
	glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts);
	glEnableVertexAttribArray(attr_pos);
	glEnableVertexAttribArray(attr_tex);
	glUniform1i(uni_tex, 0);
	glActiveTexture(GL_TEXTURE0);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	glDisableVertexAttribArray(attr_pos);
	glDisableVertexAttribArray(attr_tex);

	glBindTexture(GL_TEXTURE_2D, 0);
}