void sf2d_draw_texture_part(const sf2d_texture *texture, int x, int y, int tex_x, int tex_y, int tex_w, int tex_h) { sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex)); vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, 0.5f}; vertices[1].position = (sf2d_vector_3f){(float)x+tex_w, (float)y, 0.5f}; vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+tex_h, 0.5f}; vertices[3].position = (sf2d_vector_3f){(float)x+tex_w, (float)y+tex_h, 0.5f}; float u0 = tex_x/(float)texture->pow2_w; float v0 = tex_y/(float)texture->pow2_h; float u1 = (tex_x+tex_w)/(float)texture->pow2_w; float v1 = (tex_y+tex_h)/(float)texture->pow2_h; vertices[0].texcoord = (sf2d_vector_2f){u0, v0}; vertices[1].texcoord = (sf2d_vector_2f){u1, v0}; vertices[2].texcoord = (sf2d_vector_2f){u0, v1}; vertices[3].texcoord = (sf2d_vector_2f){u1, v1}; sf2d_bind_texture(texture, GPU_TEXUNIT0); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, //0b1100 0x10, 1, //number of buffers (u32[]){0x0}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); GPU_DrawArray(GPU_TRIANGLE_STRIP, 4); }
static void sceneRender(void) { // Bind the shader program shaderProgramUse(&program); // Configure the first fragment shading substage to just pass through the vertex color // See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // RGB channels GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), // Alpha GPU_TEVOPERANDS(0, 0, 0), // RGB GPU_TEVOPERANDS(0, 0, 0), // Alpha GPU_REPLACE, GPU_REPLACE, // RGB, Alpha 0xFFFFFFFF); // Configure the "attribute buffers" (that is, the vertex input buffers) GPU_SetAttributeBuffers( 2, // Number of inputs per vertex (u32*)osConvertVirtToPhys((u32)vbo_data), // Location of the VBO GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_FLOAT), // Format of the inputs (in this case the only input is a 3-element float vector) 0xFFC, // Unused attribute mask, in our case bit 0 is cleared since it is used 0x10, // Attribute permutations (here it is the identity) 1, // Number of buffers (u32[]) { 0x0 }, // Buffer offsets (placeholders) (u64[]) { 0x10 }, // Attribute permutations for each buffer (identity again) (u8[]) { 2 }); // Number of attributes for each buffer // Upload the projection matrix GPU_SetFloatUniformMatrix(GPU_GEOMETRY_SHADER, uLoc_projection, &projection); // Draw the VBO - GPU_UNKPRIM allows the geoshader to control primitive emission GPU_DrawArray(GPU_UNKPRIM, 0, vertex_list_count); }
void sf2d_draw_texture_rotate_cut_scale(const sf2d_texture *texture, int x, int y, float rad, int tex_x, int tex_y, int tex_w, int tex_h, float x_scale, float y_scale) { sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex)); //Don't even try to understand what I'm doing here (because I don't even understand it). //Matrices are boring. int w2 = (texture->width * x_scale)/2.0f; int h2 = (texture->height * y_scale)/2.0f; vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, 0.5f}; vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, 0.5f}; vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, 0.5f}; vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, 0.5f}; float u0 = tex_x/(float)texture->pow2_w; float v0 = tex_y/(float)texture->pow2_h; float u1 = (tex_x+tex_w)/(float)texture->pow2_w; float v1 = (tex_y+tex_h)/(float)texture->pow2_h; vertices[0].texcoord = (sf2d_vector_2f){u0, v0}; vertices[1].texcoord = (sf2d_vector_2f){u1, v0}; vertices[2].texcoord = (sf2d_vector_2f){u0, v1}; vertices[3].texcoord = (sf2d_vector_2f){u1, v1}; float m[4*4]; matrix_set_z_rotation(m, rad); sf2d_vector_3f rot[4]; int i; for (i = 0; i < 4; i++) { vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]); } vertices[0].position = (sf2d_vector_3f){rot[0].x + x + w2, rot[0].y + y + h2, rot[0].z}; vertices[1].position = (sf2d_vector_3f){rot[1].x + x * x_scale + w2, rot[1].y + y + h2, rot[1].z}; vertices[2].position = (sf2d_vector_3f){rot[2].x + x + w2, rot[2].y + y * y_scale + h2, rot[2].z}; vertices[3].position = (sf2d_vector_3f){rot[3].x + x * x_scale + w2, rot[3].y + y * y_scale + h2, rot[3].z}; sf2d_bind_texture(texture, GPU_TEXUNIT0); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, //0b1100 0x10, 1, //number of buffers (u32[]){0x0}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); GPU_DrawArray(GPU_TRIANGLE_STRIP, 4); }
void drawPlayerGun(player_s* p) { if(!p)return; gsPushMatrix(); useCamera(&p->camera); gsLoadIdentity(); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_DEPTH); gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys(rectangleBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT), // we want v0 (vertex position) and v1 (texcoord) 0xFFC, // mask : we want v0 and v1 0x10, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)rectangleVertexData-rectangleBaseAddr}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); gsSetShader(&passthroughProgram); GPU_DrawArray(GPU_TRIANGLES, 6); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); GPUCMD_AddWrite(GPUREG_ATTRIBBUFFER0_CONFIG0, (u32)crosshairVertexData-rectangleBaseAddr); textureBind(&crosshairTexture, GPU_TEXUNIT0); GPU_DrawArray(GPU_TRIANGLES, 6); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); gsSwitchRenderMode(md2GsMode); gsTranslate(1.3, -1.65, -3.1); gsRotateY(p->tempAngle.y); gsRotateX(-p->tempAngle.x); gsRotateX(-0.1); gsRotateZ(M_PI/2); gsRotateY(-M_PI/2); gsRotateX(-M_PI/2); gsScale(3.0f/8, 3.0f/8, 3.0f/8); md2InstanceDraw(&p->gunInstance); gsPopMatrix(); }
void sf2d_draw_texture_rotate(const sf2d_texture *texture, int x, int y, float rad) { sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex)); int w2 = texture->width/2.0f; int h2 = texture->height/2.0f; vertices[0].position = (sf2d_vector_3f){(float)-w2, (float)-h2, 0.5f}; vertices[1].position = (sf2d_vector_3f){(float) w2, (float)-h2, 0.5f}; vertices[2].position = (sf2d_vector_3f){(float)-w2, (float) h2, 0.5f}; vertices[3].position = (sf2d_vector_3f){(float) w2, (float) h2, 0.5f}; float u = texture->width/(float)texture->pow2_w; float v = texture->height/(float)texture->pow2_h; vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f}; vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f}; vertices[2].texcoord = (sf2d_vector_2f){0.0f, v}; vertices[3].texcoord = (sf2d_vector_2f){u, v}; float m[4*4]; matrix_set_z_rotation(m, rad); sf2d_vector_3f rot[4]; int i; for (i = 0; i < 4; i++) { vector_mult_matrix4x4(m, &vertices[i].position, &rot[i]); } for (i = 0; i < 4; i++) { vertices[i].position = (sf2d_vector_3f){rot[i].x + x + w2, rot[i].y + y + h2, rot[i].z}; } sf2d_bind_texture(texture, GPU_TEXUNIT0); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, //0b1100 0x10, 1, //number of buffers (u32[]){0x0}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); GPU_DrawArray(GPU_TRIANGLE_STRIP, 4); }
// topscreen void renderFrame() { GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut),(u32*)osConvertVirtToPhys((u32)gpuOut),0,0,240*2,400); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_KEEP, GPU_KEEP, GPU_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); GPUCMD_AddSingleParam(0x00010062, 0); GPUCMD_AddSingleParam(0x000F0118, 0); //setup shader SHDR_UseProgram(shader, 0); GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); GPU_SetTextureEnable(GPU_TEXUNIT0); GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); //texturing stuff GPU_SetTexture(GPU_TEXUNIT0, (u32*)osConvertVirtToPhys((u32)texData),128,128,GPU_TEXTURE_MAG_FILTER(GPU_NEAREST)|GPU_TEXTURE_MIN_FILTER(GPU_NEAREST),GPU_RGBA8); GPU_SetAttributeBuffers(3, (u32*)osConvertVirtToPhys((u32)texData), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT)|GPU_ATTRIBFMT(2, 3, GPU_FLOAT), 0xFFC, 0x210, 1, (u32[]){0x00000000}, (u64[]){0x210}, (u8[]){3}); //setup lighting (this is specific to our shader) vect3Df_s lightDir=vnormf(vect3Df(cos(lightAngle), -1.0f, sin(lightAngle))); GPU_SetUniform(SHDR_GetUniformRegister(shader, "lightDirection", 0), (u32*)(float[]){0.0f, -lightDir.z, -lightDir.y, -lightDir.x}, 1);
void drawRoom(room_s* r) { if(!r)return; gsSwitchRenderMode(-1); gsSetShader(&roomProgram); GPU_SetAttributeBuffers( 3, // number of attributes (u32*)osConvertVirtToPhys(roomBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_SHORT)|GPU_ATTRIBFMT(1, 2, GPU_SHORT)|GPU_ATTRIBFMT(2, 2, GPU_SHORT), // we want v0, v1 and v2 0xFF8, // mask : we want v0, v1 and v2 0x210, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)r->vertexBuffer-roomBaseAddr}, // buffer offsets (placeholders) (u64[]){0x210}, // attribute permutations for each buffer (u8[]){3} // number of attributes for each buffer ); GPU_SetTextureEnable(GPU_TEXUNIT0|GPU_TEXUNIT1); GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_TEXTURE1, GPU_PRIMARY_COLOR), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); gsPushMatrix(); gsScale(TILESIZE_FLOAT*2, HEIGHTUNIT_FLOAT, TILESIZE_FLOAT*2); gsUpdateTransformation(); int i; for(i=0; i<r->numIndexBuffers; i++) { textureBind(r->indexBufferTextures[i], GPU_TEXUNIT0); textureBind(r->lightingData.data.lightMap.texture, GPU_TEXUNIT1); GPU_SetFloatUniform(GPU_VERTEX_SHADER, roomUniformTextureDimensions, (u32*)(float[]){0.0f, 0.0f, 1.0f / r->indexBufferTextures[i]->height, 1.0f / r->indexBufferTextures[i]->width}, 1); GPU_DrawElements(GPU_UNKPRIM, (u32*)((u32)r->indexBuffers[i]-roomBaseAddr), r->numIndices[i]); }
void drawPortals(portal_s* portals[], int n, renderSceneCallback_t callback, camera_s* c, int depth, u8 stencil) { if(!portals || !portalVertexData || !callback || !c || !depth)return; int i; gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 1, // number of attributes (u32*)osConvertVirtToPhys(portalBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT), // we want v0 (vertex position) 0xFFE, // mask : we want v0 0x0, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)portalOutlineVertexData-portalBaseAddr}, // buffer offsets (placeholders) (u64[]){0x0}, // attribute permutations for each buffer (u8[]){1} // number of attributes for each buffer ); gsPushMatrix(); shaderInstanceSetBool(portalProgram.vertexShader, 0, true); gsSetShader(&portalProgram); //TEMP int colorUniformLoc = shaderInstanceGetUniformLocation(portalProgram.vertexShader, "color"); GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); for(i=0; i<n; i++) { portal_s* p = portals[i]; if(!p->draw)continue; GPU_SetFloatUniform(GPU_VERTEX_SHADER, colorUniformLoc, (u32*)(float[]){1.0f, p->color.z, p->color.y, p->color.x}, 1); gsPushMatrix(); gsTranslate(p->position.x, p->position.y, p->position.z); gsMultMatrix(p->matrix); gsUpdateTransformation(); GPU_DrawArray(GPU_TRIANGLE_STRIP, portalNumVertices); gsPopMatrix(); }
void sf2d_draw_texture_scale(const sf2d_texture *texture, int x, int y, float x_scale, float y_scale) { sf2d_vertex_pos_tex *vertices = sf2d_pool_malloc(4 * sizeof(sf2d_vertex_pos_tex)); int ws = texture->width * x_scale; int hs = texture->height * y_scale; vertices[0].position = (sf2d_vector_3f){(float)x, (float)y, 0.5f}; vertices[1].position = (sf2d_vector_3f){(float)x+ws, (float)y, 0.5f}; vertices[2].position = (sf2d_vector_3f){(float)x, (float)y+hs, 0.5f}; vertices[3].position = (sf2d_vector_3f){(float)x+ws, (float)y+hs, 0.5f}; float u = texture->width/(float)texture->pow2_w; float v = texture->height/(float)texture->pow2_h; vertices[0].texcoord = (sf2d_vector_2f){0.0f, 0.0f}; vertices[1].texcoord = (sf2d_vector_2f){u, 0.0f}; vertices[2].texcoord = (sf2d_vector_2f){0.0f, v}; vertices[3].texcoord = (sf2d_vector_2f){u, v}; sf2d_bind_texture(texture, GPU_TEXUNIT0); GPU_SetAttributeBuffers( 2, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, //0b1100 0x10, 1, //number of buffers (u32[]){0x0}, // buffer offsets (placeholders) (u64[]){0x10}, // attribute permutations for each buffer (u8[]){2} // number of attributes for each buffer ); GPU_DrawArray(GPU_TRIANGLE_STRIP, 4); }
void drawEmancipationGrid(emancipationGrid_s* eg) { if(!eg)return; float l=fabs(eg->length); // TODO : animate surface texture gsPushMatrix(); gsSwitchRenderMode(md2GsMode); gsTranslate(eg->position.x, eg->position.y, eg->position.z); if(eg->direction)gsRotateY(-(M_PI/2)); if(eg->length<0)gsRotateY((M_PI/2)*2); md2InstanceDraw(&gridInstance); gsPushMatrix(); gsTranslate(l,0,0); gsRotateY((M_PI/2)*2); md2InstanceDraw(&gridInstance); gsPopMatrix(); gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 1, // number of attributes (u32*)osConvertVirtToPhys(emancipationBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT), // we want v0 (vertex position) 0xFFE, // mask : we want v0 0x0, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)emancipationRectangleVertexData-emancipationBaseAddr}, // buffer offsets (placeholders) (u64[]){0x0}, // attribute permutations for each buffer (u8[]){1} // number of attributes for each buffer ); gsSetShader(&emancipationProgram); gsScale(l, 4.0f, 1.0f); gsUpdateTransformation(); textureBind(&gridSurfaceTexture, GPU_TEXUNIT0); GPU_SetFloatUniform(GPU_VERTEX_SHADER, emancipationUniformTextureDimensions, (u32*)(float[]){0.0f, 0.0f, 0.7f, l/8}, 1);
void RectangleShape::draw() { if (!_device->isInitialized() || !_visible) return; updateTransform(); if (_color.a > 0) { ShaderProgram::setUniform(UNIFORM_MODELVIEW_NAME, getCombinedTransform()); #ifdef _3DS auto vertices = VertexPool::getInstance()-> pushVertices<VertexPositionTexture>(4); vertices[0].position = Vec2(0, 0); vertices[1].position = Vec2(_size.x, 0); vertices[2].position = Vec2(0, _size.y); vertices[3].position = Vec2(_size.x, _size.y); vertices[0].texcoord = Vec2::Zero; vertices[1].texcoord = Vec2::Zero; vertices[2].texcoord = Vec2::Zero; vertices[3].texcoord = Vec2::Zero; //========================================================================= GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, GPU_CONSTANT), GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, GPU_CONSTANT), GPU_TEVOPERANDS(0, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_REPLACE, GPU_REPLACE, _color.r | _color.g << 8 | _color.b << 16 | _color.a << 24); u32 bufferOffsets[] = { 0x00 }; u64 bufferPermutations[] = { 0x10 }; u8 bufferNumAttributes[] = { 2 }; GPU_SetAttributeBuffers( 2, (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 2, GPU_FLOAT) | GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFFC, 0x10, 1, bufferOffsets, bufferPermutations, bufferNumAttributes); GPU_DrawArray(GPU_TRIANGLE_STRIP, 0, 4); #else Vec4 c = _color.toVector(); float vertices[] = { 0, 0, -0.5f, c.x, c.y, c.z, c.w, 0, 0, _size.x, 0, -0.5f, c.x, c.y, c.z, c.w, 0, 0, 0, _size.y, -0.5f, c.x, c.y, c.z, c.w, 0, 0, _size.x, _size.y, -0.5f, c.x, c.y, c.z, c.w, 0, 0 }; glUniform1i(ShaderProgram::getCurrentProgram()-> getUniformLocation("textureEnabled"), false); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 36, vertices); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(_vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); #endif // _3DS } if (getOutlineColor().a > 0) { _outline.setTransform(getCombinedTransform()); _outline.setLine(0, 0, _size.x, 0); _outline.draw(); _outline.setLine(_size.x, 0, _size.x, _size.y); _outline.draw(); _outline.setLine(0, _size.y, _size.x, _size.y); _outline.draw(); _outline.setLine(0, 0, 0, _size.y); _outline.draw(); } Node::draw(); }
static const u16 test_texture_w=256; static const u16 test_texture_h=256; extern const struct { u32 width; u32 height; u32 bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ u8 pixel_data[256 * 256 * 4 + 1]; } texture_data; void DrawSmallSquare() { //Setup the buffers data GPU_SetAttributeBuffers( 3, // number of attributes (u32 *) osConvertVirtToPhys((u32) test_data1), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE)|GPU_ATTRIBFMT(2, 2, GPU_FLOAT), 0xFFF8,//Attribute mask, in our case 0b1110 since we use only the first one 0x210,//Attribute permutations (here it is the identity) 1, //number of buffers (u32[]) {0x0}, // buffer offsets (placeholders) (u64[]) {0x210}, // attribute permutations for each buffer (identity again) (u8[]) {3} // number of attributes for each buffer ); //Display the buffers data GPU_DrawArray(GPU_TRIANGLES, sizeof(test_mesh1) / sizeof(test_mesh1[0])); } void DrawBigSquare() { GPU_SetAttributeBuffers( 3, // number of attributes
// topscreen void renderMenuFrame(u32* outBuffer, u32* outDepthBuffer) { GPU_SetViewport((u32*)osConvertVirtToPhys((u32)outDepthBuffer),(u32*)osConvertVirtToPhys((u32)outBuffer),0,0,240,400); GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_FRONT_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); GPU_SetStencilOp(GPU_STENCIL_KEEP, GPU_STENCIL_KEEP, GPU_STENCIL_KEEP); GPU_SetBlendingColor(0,0,0,0); GPU_SetDepthTestAndWriteMask(true, GPU_GREATER, GPU_WRITE_ALL); GPUCMD_AddMaskedWrite(GPUREG_0062, 0x1, 0); GPUCMD_AddWrite(GPUREG_0118, 0); GPU_SetAlphaBlending(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); GPU_SetAlphaTest(false, GPU_ALWAYS, 0x00); GPU_SetTextureEnable(GPU_TEXUNIT0); GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); gsMatrixMode(GS_MODELVIEW); gsPushMatrix(); gsLoadIdentity(); useCamera(&menuCamera); gsSwitchRenderMode(md2GsMode); md2InstanceDraw(&gladosInstance); md2InstanceDraw(&gladosLairInstance); gsPopMatrix(); GPU_SetDepthTestAndWriteMask(true, GPU_ALWAYS, GPU_WRITE_ALL); if(currentCameraState==2) { gsPushMatrix(); gsSwitchRenderMode(-1); GPU_SetAttributeBuffers( 1, // number of attributes (u32*)osConvertVirtToPhys(logoBaseAddr), // we use the start of linear heap as base since that's where all our buffers are located GPU_ATTRIBFMT(0, 3, GPU_FLOAT), // we want v0 (vertex position) 0xFFE, // mask : we want v0 0x0, // permutation : we use identity 1, // number of buffers : we have one attribute per buffer (u32[]){(u32)logoRectangleVertexData-logoBaseAddr}, // buffer offsets (placeholders) (u64[]){0x0}, // attribute permutations for each buffer (u8[]){1} // number of attributes for each buffer ); gsSetShader(&logoProgram); gsMatrixMode(GS_MODELVIEW); gsLoadIdentity(); gsPushMatrix(); gsTranslate(0.15f, 0.325f, 0.0f); gsScale(64.0f * 2.0f / 240.0f, 64.0f * 2.0f / 400.0f, 1.0f); gsTranslate(0.5f, 0.5f, 0.0f); gsRotateZ(logoangle+=0.01f); gsTranslate(-0.5f, -0.5f, 0.0f); gsUpdateTransformation(); textureBind(&rotateLogoTexture, GPU_TEXUNIT0); GPU_SetFloatUniform(GPU_VERTEX_SHADER, logoUniformTextureDimensions, (u32*)(float[]){0.0f, 0.0f, 1.0f, 1.0f}, 1);
void RenderTarget::draw(const Vertex* vertices, unsigned int vertexCount, PrimitiveType type, const RenderStates& states) { // Nothing to draw? if (!vertices || (vertexCount == 0)) return; // Vertices allocated in the stack (common) can't be converted to physical address #ifndef EMULATION if (osConvertVirtToPhys((u32)vertices) == 0) { err() << "RenderTarget::draw() called with vertex array in inaccessible memory space." << std::endl; return; } #endif // GL_QUADS is unavailable on OpenGL ES if (type == Quads) { err() << "cpp3ds::Quads primitive type is not supported on OpenGL ES platforms, drawing skipped" << std::endl; return; } #define GL_QUADS 0 if (activate(true)) { // First set the persistent OpenGL states if it's the very first call if (!m_cache.glStatesSet) resetGLStates(); // Check if the vertex count is low enough so that we can pre-transform them bool useVertexCache = (vertexCount <= StatesCache::VertexCacheSize); if (useVertexCache) { // Pre-transform the vertices and store them into the vertex cache for (unsigned int i = 0; i < vertexCount; ++i) { Vertex& vertex = m_cache.vertexCache[i]; vertex.position = states.transform * vertices[i].position; vertex.color = vertices[i].color; vertex.texCoords = vertices[i].texCoords; } // Since vertices are transformed, we must use an identity transform to render them if (!m_cache.useVertexCache) applyTransform(Transform::Identity); } else { applyTransform(states.transform); } // Apply the view if (m_cache.viewChanged) applyCurrentView(); // Apply the blend mode if (states.blendMode != m_cache.lastBlendMode) applyBlendMode(states.blendMode); // Apply the texture Uint64 textureId = states.texture ? states.texture->m_cacheId : 0; if (textureId != m_cache.lastTextureId) applyTexture(states.texture); // Apply the shader if (states.shader) applyShader(states.shader); // If we pre-transform the vertices, we must use our internal vertex cache if (useVertexCache) { // ... and if we already used it previously, we don't need to set the pointers again if (!m_cache.useVertexCache) vertices = m_cache.vertexCache; else vertices = NULL; } // Setup the pointers to the vertices' components if (vertices) { #ifdef EMULATION const char* data = reinterpret_cast<const char*>(vertices); glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0)); glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8)); // 8 = sizeof(Vector2f) glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)); // 12 = 8 + sizeof(Color) #else // Temorary workaround until gl3ds can get VAO gl*Pointer functions working u32 bufferOffsets[] = {0}; u64 bufferPermutations[] = {0x210}; u8 bufferAttribCounts[] = {3}; GPU_SetAttributeBuffers( 3, // number of attributes (u32*)osConvertVirtToPhys((u32)vertices), GPU_ATTRIBFMT(0, 2, GPU_FLOAT) | GPU_ATTRIBFMT(1, 4, GPU_UNSIGNED_BYTE) | GPU_ATTRIBFMT(2, 2, GPU_FLOAT), 0xFF8, //0b1100 0x210, 1, //number of buffers bufferOffsets, bufferPermutations, bufferAttribCounts // number of attributes for each buffer ); #endif } // Find the OpenGL primitive type static const GLenum modes[] = {GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS }; GLenum mode = modes[type]; // Draw the primitives glCheck(glDrawArrays(mode, 0, vertexCount)); // Unbind the shader, if any if (states.shader) applyShader(NULL); // Update the cache m_cache.useVertexCache = useVertexCache; } }
void RenderTopScreen() { // notes on the drawing process // GPU hangs if we attempt to draw an even number of arrays :/ which is why we draw the border 'twice' // textures used here are actually 512x256. TODO: investigate if GPU_SetTexture() really has the params in the wrong order // or if we did something wrong. //general setup GPU_SetViewport((u32*)osConvertVirtToPhys((u32)gpuDOut),(u32*)osConvertVirtToPhys((u32)gpuOut),0,0,240*2,400); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00); GPU_SetDepthTest(false, GPU_ALWAYS, 0x1F); // ? GPUCMD_AddSingleParam(0x00010062, 0x00000000); //param always 0x0 according to code GPUCMD_AddSingleParam(0x000F0118, 0x00000000); //setup shader SHDR_UseProgram(shader, 0); //? GPUCMD_AddSingleParam(0x000F0100, 0x00E40100); GPUCMD_AddSingleParam(0x000F0101, 0x01010000); GPUCMD_AddSingleParam(0x000F0104, 0x00000010); //texturing stuff GPUCMD_AddSingleParam(0x0002006F, 0x00000100); GPUCMD_AddSingleParam(0x000F0080, 0x00011001); //enables/disables texturing //texenv GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, 0, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_REPLACE, GPU_REPLACE, 0xFFFFFFFF); GPU_SetDummyTexEnv(1); GPU_SetDummyTexEnv(2); GPU_SetDummyTexEnv(3); GPU_SetDummyTexEnv(4); GPU_SetDummyTexEnv(5); //texturing stuff GPU_SetTexture((u32*)osConvertVirtToPhys((u32)BorderTex),256,512,0,GPU_RGBA8); // texture is actually 512x256 //setup matrices setUniformMatrix(0x24, mvMatrix); setUniformMatrix(0x20, projMatrix); // border GPU_SetAttributeBuffers(2, (u32*)osConvertVirtToPhys((u32)borderVertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT), 0xFFC, 0x10, 1, (u32[]){0x00000000}, (u64[]){0x10}, (u8[]){2}); GPU_DrawArray(GPU_TRIANGLES, 3); GPU_DrawArray(GPU_TRIANGLES, 2*3); GPU_DepthRange(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_BACK_CCW); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00); GPU_SetDepthTest(false, GPU_ALWAYS, 0x1F); GPUCMD_AddSingleParam(0x00010062, 0x00000000); GPUCMD_AddSingleParam(0x000F0118, 0x00000000); GPUCMD_AddSingleParam(0x000F0100, 0x00000100); GPUCMD_AddSingleParam(0x000F0101, 0x01010000); GPUCMD_AddSingleParam(0x000F0104, 0x00000010); //texturing stuff GPUCMD_AddSingleParam(0x0002006F, 0x00000700); // enables/disables texcoord output GPUCMD_AddSingleParam(0x000F0080, 0x00011007); //enables/disables texturing // TEXTURE ENV STAGES // --- // blending operation: (Main.Color +- (Sub.Color * Main.Alpha)) * Sub.Alpha // Main.Alpha = 0/255 depending on color math // Sub.Alpha = 128/255 depending on color div2 // note: the main/sub intensities are halved to prevent overflow during the operations. // (each TEV stage output is clamped to [0,255]) // stage 4 makes up for this // --- // STAGE 1: Out.Color = Sub.Color * Main.Alpha, Out.Alpha = Sub.Alpha + (1-Main.Alpha) (cancel out div2 when color math doesn't happen) GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE1, GPU_TEXTURE0, 0), GPU_TEVSOURCES(GPU_TEXTURE1, GPU_TEXTURE0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,1,0), GPU_MODULATE, GPU_ADD, 0xFFFFFFFF); // STAGE 2: Out.Color = Main.Color +- Prev.Color, Out.Alpha = Prev.Alpha GPU_SetTexEnv(1, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), (PPU_ColorMath & 0x80) ? GPU_SUBTRACT:GPU_ADD, GPU_REPLACE, 0xFFFFFFFF); // STAGE 3: Out.Color = Prev.Color * Prev.Alpha, Out.Alpha = Prev.Alpha GPU_SetTexEnv(2, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_PREVIOUS, 0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_REPLACE, 0xFFFFFFFF); // STAGE 4: Out.Color = Prev.Color + Prev.Color (doubling color intensity), Out.Alpha = Const.Alpha GPU_SetTexEnv(3, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,0,0), GPU_TEVOPERANDS(0,0,0), GPU_ADD, GPU_REPLACE, 0xFFFFFFFF); // STAGE 5: master brightness - Out.Color = Prev.Color * Bright.Alpha, Out.Alpha = Const.Alpha GPU_SetTexEnv(4, GPU_TEVSOURCES(GPU_PREVIOUS, GPU_TEXTURE2, 0), GPU_TEVSOURCES(GPU_CONSTANT, 0, 0), GPU_TEVOPERANDS(0,2,0), GPU_TEVOPERANDS(0,0,0), GPU_MODULATE, GPU_REPLACE, 0xFFFFFFFF); // STAGE 6: dummy GPU_SetDummyTexEnv(5); GPU_SetAttributeBuffers(3, (u32*)osConvertVirtToPhys((u32)screenVertices), GPU_ATTRIBFMT(0, 3, GPU_FLOAT)|GPU_ATTRIBFMT(1, 2, GPU_FLOAT)|GPU_ATTRIBFMT(2, 2, GPU_FLOAT), 0xFFC, 0x210, 1, (u32[]){0x00000000}, (u64[]){0x210}, (u8[]){3}); GPU_SetTexture((u32*)osConvertVirtToPhys((u32)MainScreenTex),256,512,0,GPU_RGBA8); GPU_SetTexture1((u32*)osConvertVirtToPhys((u32)SubScreenTex),256,512,0,GPU_RGBA8); GPU_SetTexture2((u32*)osConvertVirtToPhys((u32)BrightnessTex),256,8,0x200,GPU_A8); GPU_DrawArray(GPU_TRIANGLES, 2*3); }