Exemple #1
0
void ERenderer::renderScene(bool fast) {
    uint16_t scenarioTag = map->principal_tag;
    if (scenarioTag != NULLED_TAG_ID) {
        ProtonTag *scenarioTag = map->tags.at(map->principal_tag).get();
        HaloScenarioTag *scenario = (HaloScenarioTag *)(scenarioTag->Data());
        
        // Render the sky
        float cut = options->fogcut;
        options->fogcut = 0.0;
        shader *scex = shaders->get_shader(shader_SCEX);
        scex->start(options);
        skies->render(shader_SCEX);
        scex->stop();
        shader *schi = shaders->get_shader(shader_SCHI);
        schi->start(options);
        skies->render(shader_SCHI);
        schi->stop();
        options->fogcut = cut;

        // Render everything else
        //glAlphaFunc(GL_GREATER, 0.1);
        for (int pass = ShaderStart; pass <= ShaderEnd; pass++ )
        {
            if (fast && (/*pass == shader_SCEX || pass == shader_SCHI || pass == shader_SGLA ||*/pass == shader_SWAT)) continue;
            #ifdef RENDER_CORE_32
            if (pass != shader_SENV && pass != shader_SOSO && pass != shader_SCEX && pass != shader_SCHI) continue;
            #endif
            
            ShaderType type = static_cast<ShaderType>(pass);
            shader *shader = shaders->get_shader(type);
            shader->start(options);
            bsp->render(type);
            GLuint number = 0;
            objects->render(&number, nullptr, type, options);
            shader->stop();
        }
    }
}
Exemple #2
0
Model::Model(ModelManager *manager, ProtonMap *map, HaloTagDependency tag) {
    if (tag.tag_id.tag_index == NULLED_TAG_ID) {
        return;
    }
    
    printf("reading model 0x%x\n", tag.tag_id.tag_index);
    ProtonTag *modelTag = map->tags.at(tag.tag_id.tag_index).get();
    HaloModel *modelData = (HaloModel *)modelTag->Data();
    float base_u = *(float*)(modelTag->Data() + 0x30);
    float base_v = *(float*)(modelTag->Data() + 0x34);
    int i,p;
    
    // Read shaders
    printf("reading shaders\n");
    shaders.resize(modelData->shaders.count);
    for (i=0; i < modelData->shaders.count; i++) {
        HaloShader *shaderRef = (HaloShader *)(modelTag->Data() + modelTag->PointerToOffset(modelData->shaders.address) + 32 * i);
        shaders[i] = (manager->shaders->create_shader(map, shaderRef->shader));
    }
    
    // Count geometry
    printf("counting geom\n");
    geom = (ModelRenderMesh ***)malloc(modelData->geometry.count * sizeof(ModelRenderMesh **));
    geomCount = (uint16_t*)malloc(modelData->geometry.count * sizeof(uint16_t));
    geometries.resize(modelData->geometry.count);
    for (i=0; i < modelData->geometry.count; i++) {
        HaloGeometry *geometry = (HaloGeometry *)(modelTag->Data() + modelTag->PointerToOffset(modelData->geometry.address) + 48 * i);
        int renderable_count = 0;
        for (p=0; p < geometry->parts.count; p++) {
            HaloGeometryPart *part = (HaloGeometryPart *)(modelTag->Data() + modelTag->PointerToOffset(geometry->parts.address) + 132 * p);
            if (part->indexPointer1 != part->indexPointer2) {
                continue;
            }
            renderable_count++;
        }
        geometries[i] = std::vector<ModelRenderMesh*>(renderable_count);
        geom[i] = (ModelRenderMesh**)malloc(renderable_count * sizeof(ModelRenderMesh*));
        geomCount[i] = renderable_count;
    }
    
    // Read geometry
    printf("reading geom\n");
    for (i=0; i < modelData->geometry.count; i++) {
        HaloGeometry *geometry = (HaloGeometry *)(modelTag->Data() + modelTag->PointerToOffset(modelData->geometry.address) + 48 * i);

        int render = 0;
        for (p=0; p < geometry->parts.count; p++) {
            HaloGeometryPart *part = (HaloGeometryPart *)(modelTag->Data() + modelTag->PointerToOffset(geometry->parts.address) + 132 * p);
            if (part->indexPointer1 != part->indexPointer2) {
                printf("bad part\n");
                continue;
            }
            
            uint8_t *vertIndexOffset    = (uint8_t *)(modelTag->ResourcesData() + part->indexPointer1);
            uint8_t *PcVertexDataOffset = (uint8_t *)(modelTag->ResourcesData() + part->vertPointer1);
            int vertex_number = part->vertCount;
            int indexSize     = part->indexCount + 2;
            
            ModelRenderMesh *renderer = new ModelRenderMesh;
            renderer->setup();
            renderer->base_u = base_u;
            renderer->base_v = base_v;
            renderer->shader = shaders[part->shader];
            renderer->indexCount = indexSize;
            
            // Assemble the VBO
            renderer->vertex_array    = (float*)malloc(vertex_number   * 3 * sizeof(float)); // cleaned
            renderer->texture_uv      = (float*)malloc(vertex_number   * 2 * sizeof(float)); // cleaned
            renderer->light_uv        = (float*)malloc(vertex_number   * 2 * sizeof(float)); // cleaned
            renderer->normals         = (float*)malloc(vertex_number   * 3 * sizeof(float)); // cleaned
            renderer->tangents        = (float*)malloc(vertex_number   * 3 * sizeof(float));
            renderer->binormals       = (float*)malloc(vertex_number   * 3 * sizeof(float));
            renderer->index_array     = (int*)  malloc(indexSize * sizeof(int)); // cleaned
            
            int v;
            int vert = 0, uv = 0;
            for (v = 0; v < vertex_number; v++)
            {
                MODEL_VERT *vert1 = (MODEL_VERT*)(PcVertexDataOffset + v * sizeof(MODEL_VERT));
                renderer->vertex_array[vert]   = vert1->vertex_k[0];
                renderer->vertex_array[vert+1] = vert1->vertex_k[1];
                renderer->vertex_array[vert+2] = vert1->vertex_k[2];
                renderer->normals[vert]        = vert1->normal[0];
                renderer->normals[vert+1]      = vert1->normal[1];
                renderer->normals[vert+2]      = vert1->normal[2];
                renderer->binormals[vert]      = vert1->binormal[0];
                renderer->binormals[vert+1]    = vert1->binormal[1];
                renderer->binormals[vert+2]    = vert1->binormal[2];
                renderer->tangents[vert]       = vert1->tangent[0];
                renderer->tangents[vert+1]     = vert1->tangent[1];
                renderer->tangents[vert+2]     = vert1->tangent[2];
                renderer->texture_uv[uv]       = vert1->uv[0];
                renderer->texture_uv[uv+1]     = vert1->uv[1];
                vert+=3; uv+=2;
            }
            
            for (v = 0; v < indexSize; v++)
            {
                uint16_t *index = (uint16_t*)(vertIndexOffset + sizeof(uint16_t) * v);
                renderer->index_array[v]   = index[0];
            }
            
            #define vertex_buffer 0
            #define texCoord_buffer 1
            #define texCoord_buffer_light 3
            #define normals_buffer 2
            #define binormals_buffer 5
            #define tangents_buffer 6
            
            #ifdef RENDER_PIPELINE
            
                // TODO
            
            #else
                #ifdef RENDER_CORE_32
                    glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[POS_VB]);
                    glBufferData(GL_ARRAY_BUFFER, vertex_number * 3 * sizeof(GLfloat), renderer->vertex_array, GL_STATIC_DRAW);
                    glEnableVertexAttribArray(vertex_buffer);
                    glVertexAttribPointer(vertex_buffer, 3, GL_FLOAT, GL_FALSE, 0, NULL);
                #else
                    glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[POS_VB]);
                    glBufferData(GL_ARRAY_BUFFER, vertex_number * 3 * sizeof(GLfloat), NULL, GL_STATIC_DRAW);
                    GLvoid* my_vertex_pointer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
                    memcpy(my_vertex_pointer, renderer->vertex_array, vertex_number * 3 * sizeof(GLfloat));
                    glUnmapBuffer(GL_ARRAY_BUFFER);
                    glEnableVertexAttribArray(0);
                    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
                #endif
            
                glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[TEXCOORD_VB]);
                glBufferData(GL_ARRAY_BUFFER, vertex_number * 2 * sizeof(GLfloat), renderer->texture_uv, GL_STATIC_DRAW);
                glEnableVertexAttribArray(texCoord_buffer);
                glVertexAttribPointer(texCoord_buffer, 2, GL_FLOAT, GL_FALSE, 0, 0);
            
                glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[NORMAL_VB]);
                glBufferData(GL_ARRAY_BUFFER, vertex_number * 3 * sizeof(GLfloat), renderer->normals, GL_STATIC_DRAW);
                glEnableVertexAttribArray(normals_buffer);
                glVertexAttribPointer(normals_buffer, 3, GL_FLOAT, GL_FALSE, 0, 0);
            
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->m_Buffers[INDEX_BUFFER]);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * sizeof(GLint), renderer->index_array, GL_STATIC_DRAW);
            
                glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[LIGHT_VB]);
                glBufferData(GL_ARRAY_BUFFER, vertex_number * 2 * sizeof(GLfloat), renderer->light_uv, GL_STATIC_DRAW);
                glEnableVertexAttribArray(texCoord_buffer_light);
                glVertexAttribPointer(texCoord_buffer_light, 2, GL_FLOAT, GL_FALSE, 0, 0);
            
                glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[BINORMAL_VB]);
                glBufferData(GL_ARRAY_BUFFER, vertex_number * 3 * sizeof(GLfloat), renderer->binormals, GL_STATIC_DRAW);
                glEnableVertexAttribArray(binormals_buffer);
                glVertexAttribPointer(binormals_buffer, 3, GL_FLOAT, GL_FALSE, 0, 0);
            
                glBindBuffer(GL_ARRAY_BUFFER, renderer->m_Buffers[TANGENT_VB]);
                glBufferData(GL_ARRAY_BUFFER, vertex_number * 3 * sizeof(GLfloat), renderer->tangents, GL_STATIC_DRAW);
                glEnableVertexAttribArray(tangents_buffer);
                glVertexAttribPointer(tangents_buffer, 3, GL_FLOAT, GL_FALSE, 0, 0);
            
                #ifdef RENDER_VAO_NORMAL
                    glBindVertexArray(0);
                #else
                    glBindVertexArrayAPPLE(0);
                #endif
            
                glBindBuffer(GL_ARRAY_BUFFER, 0);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
            #endif
            
            // Clean up
            #ifdef RENDER_VBO
            free(renderer->vertex_array);
            free(renderer->texture_uv);
            free(renderer->light_uv);
            free(renderer->normals);
            free(renderer->index_array);
            #endif
            
            printf("geom %d %d\n", i, render);
            geometries[i][render] = renderer;
            geom[i][render] = renderer;
            render++;
        }
    }
    printf("geometries %ld\n", geometries.size());
    
    // Read regions
    int LOD = 4;
    printf("regions %d\n", modelData->region.count);
    for (i=0; i < modelData->region.count; i++) {
        MODEL_REGION *region = (MODEL_REGION *)(modelTag->Data() + modelTag->PointerToOffset(modelData->region.address) + 76 * i);
        printf("region %d %d\n", i, region->Permutations.count);
        for (p=0; p < region->Permutations.count; p++) {
            MODEL_REGION_PERMUTATION *permutation = (MODEL_REGION_PERMUTATION *)(modelTag->Data() + modelTag->PointerToOffset(region->Permutations.address) + 88 * p);
            printf("permutation %d, %d\n", i, permutation->LOD_MeshIndex[LOD]);
            if ((permutation->Flags[0] & 0xFF) != 1) {
                renderIndices.push_back(permutation->LOD_MeshIndex[LOD]);
            }
            
        }
    }
    
    printf("creating model object\n");
    name = modelTag->Name();
    ready = true;
}