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); } } }
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); }
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); }