void startParallel() { startAllThreads(); __sync_fetch_and_add(&gActiveThreadCount, 1); }
// All threads start execution here. int main() { if (__builtin_nyuzi_read_control_reg(0) != 0) workerThread(); // Set up resource data char *resourceData = readResourceFile(); const FileHeader *resourceHeader = (FileHeader*) resourceData; const TextureEntry *texHeader = (TextureEntry*)(resourceData + sizeof(FileHeader)); const MeshEntry *meshHeader = (MeshEntry*)(resourceData + sizeof(FileHeader) + resourceHeader->numTextures * sizeof(TextureEntry)); Texture **textures = new Texture*[resourceHeader->numTextures]; printf("%d textures %d meshes\n", resourceHeader->numTextures, resourceHeader->numMeshes); // Create texture objects for (unsigned int textureIndex = 0; textureIndex < resourceHeader->numTextures; textureIndex++) { #if TEST_TEXTURE textures[textureIndex] = createCheckerboardTexture(); #else textures[textureIndex] = new Texture(); textures[textureIndex]->enableBilinearFiltering(true); int offset = texHeader[textureIndex].offset; for (unsigned int mipLevel = 0; mipLevel < texHeader[textureIndex].mipLevels; mipLevel++) { int width = texHeader[textureIndex].width >> mipLevel; int height = texHeader[textureIndex].height >> mipLevel; Surface *surface = new Surface(width, height, resourceData + offset); textures[textureIndex]->setMipSurface(mipLevel, surface); offset += width * height * 4; } #endif } // Create Render Buffers RenderBuffer *vertexBuffers = new RenderBuffer[resourceHeader->numMeshes]; RenderBuffer *indexBuffers = new RenderBuffer[resourceHeader->numMeshes]; for (unsigned int meshIndex = 0; meshIndex < resourceHeader->numMeshes; meshIndex++) { const MeshEntry &entry = meshHeader[meshIndex]; vertexBuffers[meshIndex].setData(resourceData + entry.offset, entry.numVertices, sizeof(float) * kAttrsPerVertex); indexBuffers[meshIndex].setData(resourceData + entry.offset + entry.numVertices * kAttrsPerVertex * sizeof(float), entry.numIndices, sizeof(int)); } // Set up render state RenderContext *context = new RenderContext(0x1000000); RenderTarget *renderTarget = new RenderTarget(); Surface *colorBuffer = new Surface(FB_WIDTH, FB_HEIGHT, (void*) 0x200000); Surface *depthBuffer = new Surface(FB_WIDTH, FB_HEIGHT); renderTarget->setColorBuffer(colorBuffer); renderTarget->setDepthBuffer(depthBuffer); context->bindTarget(renderTarget); context->enableDepthBuffer(true); #if SHOW_DEPTH context->bindShader(new DepthShader()); #else context->bindShader(new TextureShader()); #endif context->setClearColor(0.52, 0.80, 0.98); Matrix projectionMatrix = Matrix::getProjectionMatrix(FB_WIDTH, FB_HEIGHT); TextureUniforms uniforms; uniforms.fLightDirection = Vec3(-1, -0.5, 1).normalized(); uniforms.fDirectional = 0.5f; uniforms.fAmbient = 0.4f; float theta = 0.0; startAllThreads(); for (int frame = 0; ; frame++) { Matrix modelViewMatrix = Matrix::lookAt(Vec3(cos(theta) * 6, 3, sin(theta) * 6), Vec3(0, 3.1, 0), Vec3(0, 1, 0)); theta = theta + M_PI / 8; if (theta > M_PI * 2) theta -= M_PI * 2; uniforms.fMVPMatrix = projectionMatrix * modelViewMatrix; uniforms.fNormalMatrix = modelViewMatrix.upper3x3(); context->clearColorBuffer(); for (unsigned int meshIndex = 0; meshIndex < resourceHeader->numMeshes; meshIndex++) { const MeshEntry &entry = meshHeader[meshIndex]; if (entry.textureId != 0xffffffff) { assert(entry.textureId < resourceHeader->numTextures); context->bindTexture(0, textures[entry.textureId]); uniforms.fHasTexture = true; } else uniforms.fHasTexture = false; context->bindUniforms(&uniforms, sizeof(uniforms)); context->bindVertexAttrs(&vertexBuffers[meshIndex]); context->drawElements(&indexBuffers[meshIndex]); } int startInstructions = __builtin_nyuzi_read_control_reg(6); context->finish(); printf("rendered frame in %d instructions\n", __builtin_nyuzi_read_control_reg(6) - startInstructions); } return 0; }