Exemple #1
0
void glEnd (void)
{
	struct pspgl_context *c = pspgl_curctx;

	if (likely(c->beginend.vertex_count > 0)) {
		long prim = __pspgl_glprim2geprim(c->beginend.primitive);

		if (unlikely(prim < 0))
			goto out_error;

		/* If we've finished a line loop, connect the last
		   edge to the first vertex to close the loop. */
		if (c->beginend.primitive == GL_LINE_LOOP) {
			struct t2f_c4ub_n3f_v3f *vbuf = (struct t2f_c4ub_n3f_v3f *) c->beginend.vbuf_adr;

			vbuf += c->beginend.vertex_count;
			memcpy(vbuf, &c->beginend.line_loop_start, sizeof(*vbuf));
			c->beginend.vertex_count++;
		}

		__pspgl_context_render_prim(pspgl_curctx, prim, c->beginend.vertex_count,
					    GE_TEXTURE_32BITF | GE_COLOR_8888 | GE_NORMAL_32BITF | GE_VERTEX_32BITF,
					    c->beginend.vbuf_adr, NULL);
	}

	pspgl_curctx->beginend.primitive = -1;
	return;

  out_error:
	GLERROR(GL_INVALID_ENUM);
}
void CPlanarShadow::render()
{

	video::IVideoDriver* driver = SceneManager->getVideoDriver();


	int i;
	core::vector3df lpos;


	s32 lights = SceneManager->getVideoDriver()->getDynamicLightCount();
	for (i=0; i<lights; ++i)
	{
		const video::SLight& dl = SceneManager->getVideoDriver()->getDynamicLight(i);
		lpos = dl.Position;

		if (dl.CastShadows &&
		    fabs((lpos - Transform.getTranslation()).getLengthSQ()) <= (dl.Radius*dl.Radius*4.0f))
		{

			core::matrix4 mat;


			mat.buildShadowMatrix(dl.Position, Plane, 0.f );
			mat *= Transform;

			core::matrix4 backup_view = driver->getTransform(video::ETS_VIEW);


			mat = View*mat;
			for (int x = 0; x<16; x++)
				mat.M[x]/=Divisor;
			driver->setTransform(video::ETS_VIEW, core::matrix4());
			driver->setTransform(video::ETS_WORLD, mat);


			glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT |
			             GL_POLYGON_BIT   | GL_STENCIL_BUFFER_BIT   );
			glEnable(GL_STENCIL_TEST);
			glDisable(GL_ALPHA_TEST);
			glDisable(GL_TEXTURE_2D);

			if (enableDepth == false)
				glDisable (GL_DEPTH_TEST );
			else
			{
				glEnable( GL_DEPTH_TEST );
				glDepthFunc( GL_LEQUAL );
			}
			glStencilOp(GL_INCR, GL_INCR, GL_INCR);
			glStencilFunc(GL_EQUAL, 128, 0xFF);

			video::SColor pow = SceneManager->getShadowColor();

			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA,
			            GL_ONE_MINUS_SRC_ALPHA);
			glDisable(GL_LIGHTING);

			glColor4f(pow.getRed()/255.f, pow.getGreen()/255.f, pow.getBlue()/255.f, pow.getAlpha()/255.f);
			sceKernelDcacheWritebackAll();

			__pspgl_context_render_prim(pspgl_curctx, GE_TRIANGLES, IndexCount, GE_VERTEX_32BITF|GE_VINDEX_16BIT|GE_TRANSFORM_3D,
			                            Vertices, Indices);
			glFlush();

			if (enableDepth == false)
				glEnable (GL_DEPTH_TEST );
			else
			{
				glEnable( GL_DEPTH_TEST );
				glDepthFunc( GL_LEQUAL );
			}
			glDisable(GL_STENCIL_TEST);

			glPopAttrib();

			driver->setTransform(video::ETS_VIEW, backup_view);

		}
	}

}
Exemple #3
0
void glClear (GLbitfield mask)
{
	struct clear_vertex *vbuf;
	struct pspgl_surface *s = pspgl_curctx->draw;
	unsigned long clearmask = pspgl_curctx->clear.color;
	unsigned long clearmode = 0;
	unsigned x, y, width, height;

	if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
		goto out_error;

	/* make room for 2 embedded vertices in cmd_buf, aligned to 16byte boundary */
	vbuf = __pspgl_dlist_insert_space(2 * sizeof(struct clear_vertex));

	if (mask & GL_COLOR_BUFFER_BIT) {
		clearmode |= GU_COLOR_BUFFER_BIT;
		if (s->alpha_mask)
			clearmode |= GU_STENCIL_BUFFER_BIT; /* really alpha */
	}

	if (s->stencil_mask && (mask & GL_STENCIL_BUFFER_BIT)) {
		static const unsigned char stencil_shift [] = { 32-1, 32-4, 32-8 };
		clearmask &= 0x00ffffff;
		clearmask |= (pspgl_curctx->clear.stencil) << stencil_shift[s->pixfmt-1];
		clearmode |= GU_STENCIL_BUFFER_BIT;
	}

	if (s->depth_buffer && (mask & GL_DEPTH_BUFFER_BIT))
		clearmode |= GU_DEPTH_BUFFER_BIT;

	if (pspgl_curctx->scissor_test.enabled) {
		x = pspgl_curctx->scissor_test.x;
		y = pspgl_curctx->scissor_test.y;
		width = pspgl_curctx->scissor_test.width;
		height = pspgl_curctx->scissor_test.height;
	} else {
		x = 0;
		y = 0;
		width = s->width;
		height = s->height;
	}

	vbuf[0].color = clearmask;
	vbuf[0].x = x;
	vbuf[0].y = s->height - y;
	vbuf[0].z = pspgl_curctx->clear.depth;

	vbuf[1].color = clearmask;
	vbuf[1].x = x + width;
	vbuf[1].y = s->height - (y + height);
	vbuf[1].z = pspgl_curctx->clear.depth;

	/* enable clear mode */
	sendCommandi(CMD_CLEARMODE, (clearmode << 8) | 1);

	/* draw array */
	__pspgl_context_render_prim(pspgl_curctx, GE_SPRITES, 2, 
				    GE_COLOR_8888 | GE_VERTEX_16BIT | GE_TRANSFORM_2D, vbuf, NULL);

	/* leave clear mode */
	sendCommandi(CMD_CLEARMODE, 0);
	return;

  out_error:
	GLERROR(GL_INVALID_VALUE);
}
Exemple #4
0
void glVertex3f (GLfloat x, GLfloat y, GLfloat z)
{
	struct pspgl_context *c = pspgl_curctx;
	struct t2f_c4ub_n3f_v3f *vbuf;

	if (c->beginend.vertex_count == 0)
		c->beginend.vbuf_adr = __pspgl_dlist_insert_space(BUFSZ * sizeof(struct t2f_c4ub_n3f_v3f));

	vbuf = (struct t2f_c4ub_n3f_v3f *) c->beginend.vbuf_adr;

	if (unlikely(!vbuf))
		goto out_error;

	vbuf += c->beginend.vertex_count;

	vbuf->texcoord[0] = c->current.texcoord[0];
	vbuf->texcoord[1] = c->current.texcoord[1];
	vbuf->color = c->current.color;
	vbuf->normal[0] = c->current.normal[0];
	vbuf->normal[1] = c->current.normal[1];
	vbuf->normal[2] = c->current.normal[2];
	vbuf->vertex[0] = x;
	vbuf->vertex[1] = y;
	vbuf->vertex[2] = z;

	/* If it's a line loop, save the first vertex so that we can close the loop in glEnd(). */
	if (c->beginend.primitive == GL_LINE_LOOP && c->beginend.vertex_count == 0) {
		/* Note: If a vertex buffer is split (see below), the vertex_count of the new buffer
		   will be 1 because of the overhang copied from the previous buffer.  If there were
		   no overhang for line loops, we wouldn't be able to get away with this. */
		memcpy(&c->beginend.line_loop_start, vbuf, sizeof(*vbuf));
	}

	if (unlikely(++c->beginend.vertex_count == BUFSZ)) {
		static const char overhang_count [] = {
			0,	/* GL_POINTS */
			0,	/* GL_LINES */
			1,	/* GL_LINE_LOOP */
			1,	/* GL_LINE_STRIP */
			0,	/* GL_TRIANGLES */
			2,	/* GL_TRIANGLE_STRIP */
			2,	/* GL_TRIANGLE_FAN */
			1,	/* GL_QUADS (really trifan) */
			1,	/* GL_QUAD_STRIP (really trifan) */
			1,	/* GL_POLYGON (really trifan) */
			0	/* GL_SPRITES_PSP */
		};
		char overhang = overhang_count[c->beginend.primitive];
		long prim = __pspgl_glprim2geprim(c->beginend.primitive);

		/* vertex buffer full, render + restart */
		__pspgl_context_render_prim(c, prim, c->beginend.vertex_count,
					    GE_TEXTURE_32BITF | GE_COLOR_8888 | GE_NORMAL_32BITF | GE_VERTEX_32BITF,
					    c->beginend.vbuf_adr, NULL);

		/* copy overhang */
		c->beginend.vertex_count = overhang;

		if (overhang) {
			struct t2f_c4ub_n3f_v3f *vbuf_start, *prev;

			prev = c->beginend.vbuf_adr;
			c->beginend.vbuf_adr = __pspgl_dlist_insert_space(BUFSZ * sizeof(struct t2f_c4ub_n3f_v3f));
			vbuf_start = c->beginend.vbuf_adr;

			if (c->beginend.primitive == GL_TRIANGLE_FAN || c->beginend.primitive == GL_POLYGON) {
				memcpy(vbuf_start, prev, sizeof(vbuf_start[0]));
				c->beginend.vertex_count++;
				vbuf_start++;
			}

			memcpy(vbuf_start, vbuf - overhang + 1, overhang * sizeof(vbuf[0]));
		}
	}
	return;

  out_error:
	GLERROR(GL_OUT_OF_MEMORY);
}