Example #1
0
/*!
 * 3D vector perspective projection
 * Projects 3D vector into 2D screen space
 * \param v3d       3D vector to project
 * \param[out] v2d  resulting 2D vector
 * \return projected z component of v2d
 */
int32_t pie_RotateProject(const Vector3i *v3d, const glm::mat4& matrix, Vector2i *v2d)
{
	float hackScaleFactor = 1.0f / (3 * 330);  // HACK: This seems to work by experimentation, not sure why.

	/*
	 * v = curMatrix . v3d
	 */
	glm::vec4 v(pie_PerspectiveGet() * matrix * glm::vec4(*v3d, 1.f));

	const float xx = v.x / v.w;
	const float yy = v.y / v.w;

	if (v.w < 256 * hackScaleFactor)
	{
		v2d->x = LONG_WAY; //just along way off screen
		v2d->y = LONG_WAY;
	}
	else
	{
		v2d->x = (.5 + .5 * xx) * pie_GetVideoBufferWidth();
		v2d->y = (.5 - .5 * yy) * pie_GetVideoBufferHeight();
	}

	return v.w;
}
Example #2
0
void pie_DrawSkybox(float scale, const glm::mat4 &viewMatrix)
{
	// no use in updating the depth buffer
	glDepthMask(GL_FALSE);
	// enable alpha
	pie_SetRendMode(REND_ALPHA);

	// Apply scale matrix
	skyboxGfx->draw(pie_PerspectiveGet() * viewMatrix * glm::scale(scale, scale / 2.f, scale));
}
Example #3
0
void pie_TransColouredTriangle(const std::array<Vector3f, 3> &vrt, PIELIGHT c, const glm::mat4 &modelViewMatrix)
{
	pie_SetTexturePage(TEXPAGE_NONE);
	pie_SetRendMode(REND_ADDITIVE);
	glm::vec4 color(c.byte.r / 255.f, c.byte.g / 255.f, c.byte.b / 255.f, 128.f / 255.f);
	const auto &program = pie_ActivateShader(SHADER_GENERIC_COLOR, pie_PerspectiveGet() * modelViewMatrix, color);

	static glBufferWrapper buffer;
	glBindBuffer(GL_ARRAY_BUFFER, buffer.id);
	glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(Vector3f), vrt.data(), GL_STREAM_DRAW);
	glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
	glEnableVertexAttribArray(program.locVertex);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
	glDisableVertexAttribArray(program.locVertex);
}
Example #4
0
/// Draw the shadow for a shape
static void pie_DrawShadow(iIMDShape *shape, int flag, int flag_data, const glm::vec4 &light, const glm::mat4 &modelViewMatrix)
{
    static std::vector<EDGE> edgelist;  // Static, to save allocations.
    static std::vector<EDGE> edgelistFlipped;  // Static, to save allocations.
    static std::vector<EDGE> edgelistFiltered;  // Static, to save allocations.
    EDGE *drawlist = NULL;

    unsigned edge_count;
    Vector3f *pVertices = shape->points;
    if (flag & pie_STATIC_SHADOW && shape->shadowEdgeList)
    {
        drawlist = shape->shadowEdgeList;
        edge_count = shape->nShadowEdges;
    }
    else
    {
        edgelist.clear();
        iIMDPoly *end = shape->polys + shape->npolys;
        for (iIMDPoly *pPolys = shape->polys; pPolys != end; ++pPolys)
        {
            glm::vec3 p[3];
            for (int j = 0; j < 3; ++j)
            {
                int current = pPolys->pindex[j];
                p[j] = glm::vec3(pVertices[current].x, scale_y(pVertices[current].y, flag, flag_data), pVertices[current].z);
            }
            if (glm::dot(glm::cross(p[2] - p[0], p[1] - p[0]), glm::vec3(light)) > 0.0f)
            {
                for (int n = 0; n < 3; ++n)
                {
                    // Add the edges
                    edgelist.push_back({pPolys->pindex[n], pPolys->pindex[(n + 1)%3]});
                }
            }
        }

        // Remove duplicate pairs from the edge list. For example, in the list ((1 2), (2 6), (6 2), (3, 4)), remove (2 6) and (6 2).
        edgelistFlipped = edgelist;
        std::for_each(edgelistFlipped.begin(), edgelistFlipped.end(), flipEdge);
        std::sort(edgelist.begin(), edgelist.end(), edgeLessThan);
        std::sort(edgelistFlipped.begin(), edgelistFlipped.end(), edgeLessThan);
        edgelistFiltered.resize(edgelist.size());
        edgelistFiltered.erase(std::set_difference(edgelist.begin(), edgelist.end(), edgelistFlipped.begin(), edgelistFlipped.end(), edgelistFiltered.begin(), edgeLessThan), edgelistFiltered.end());

        drawlist = &edgelistFiltered[0];
        edge_count = edgelistFiltered.size();
        //debug(LOG_WARNING, "we have %i edges", edge_count);

        if (flag & pie_STATIC_SHADOW)
        {
            // then store it in the imd
            shape->nShadowEdges = edge_count;
            shape->shadowEdgeList = (EDGE *)realloc(shape->shadowEdgeList, sizeof(EDGE) * shape->nShadowEdges);
            std::copy(drawlist, drawlist + edge_count, shape->shadowEdgeList);
        }
    }

    std::vector<Vector3f> vertexes;
    for (unsigned i = 0; i < edge_count; i++)
    {
        int a = drawlist[i].from, b = drawlist[i].to;

        glm::vec3 v1(pVertices[b].x, scale_y(pVertices[b].y, flag, flag_data), pVertices[b].z);
        glm::vec3 v2(pVertices[b].x + light[0], scale_y(pVertices[b].y, flag, flag_data) + light[1], pVertices[b].z + light[2]);
        glm::vec3 v3(pVertices[a].x + light[0], scale_y(pVertices[a].y, flag, flag_data) + light[1], pVertices[a].z + light[2]);
        glm::vec3 v4(pVertices[a].x, scale_y(pVertices[a].y, flag, flag_data), pVertices[a].z);

        vertexes.push_back(v1);
        vertexes.push_back(v2);
        vertexes.push_back(v3);

        vertexes.push_back(v3);
        vertexes.push_back(v4);
        vertexes.push_back(v1);
    }

    // draw the shadow volume
    const auto &program = pie_ActivateShader(SHADER_GENERIC_COLOR, pie_PerspectiveGet() * modelViewMatrix, glm::vec4());
    static glBufferWrapper buffer;
    glBindBuffer(GL_ARRAY_BUFFER, buffer.id);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3f) * vertexes.size(), vertexes.data(), GL_STREAM_DRAW);
    glEnableVertexAttribArray(program.locVertex);
    glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glDrawArrays(GL_TRIANGLES, 0, edge_count * 2 * 3);
    glDisableVertexAttribArray(program.locVertex);
    pie_DeactivateShader();
}
Example #5
0
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 const &matrix)
{
    bool light = true;

    /* Set fog status */
    if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_PREMULTIPLIED))
    {
        pie_SetFogStatus(false);
    }
    else
    {
        pie_SetFogStatus(true);
    }

    /* Set tranlucency */
    if (pieFlag & pie_ADDITIVE)
    {
        pie_SetRendMode(REND_ADDITIVE);
        colour.byte.a = (UBYTE)pieFlagData;
        light = false;
    }
    else if (pieFlag & pie_TRANSLUCENT)
    {
        pie_SetRendMode(REND_ALPHA);
        colour.byte.a = (UBYTE)pieFlagData;
        light = false;
    }
    else if (pieFlag & pie_PREMULTIPLIED)
    {
        pie_SetRendMode(REND_PREMULTIPLIED);
        light = false;
    }
    else
    {
        pie_SetRendMode(REND_OPAQUE);
    }

    if (pieFlag & pie_ECM)
    {
        pie_SetRendMode(REND_ALPHA);
        light = true;
        pie_SetShaderEcmEffect(true);
    }

    glm::vec4 sceneColor(lighting0[LIGHT_EMISSIVE][0], lighting0[LIGHT_EMISSIVE][1], lighting0[LIGHT_EMISSIVE][2], lighting0[LIGHT_EMISSIVE][3]);
    glm::vec4 ambient(lighting0[LIGHT_AMBIENT][0], lighting0[LIGHT_AMBIENT][1], lighting0[LIGHT_AMBIENT][2], lighting0[LIGHT_AMBIENT][3]);
    glm::vec4 diffuse(lighting0[LIGHT_DIFFUSE][0], lighting0[LIGHT_DIFFUSE][1], lighting0[LIGHT_DIFFUSE][2], lighting0[LIGHT_DIFFUSE][3]);
    glm::vec4 specular(lighting0[LIGHT_SPECULAR][0], lighting0[LIGHT_SPECULAR][1], lighting0[LIGHT_SPECULAR][2], lighting0[LIGHT_SPECULAR][3]);

    SHADER_MODE mode = shape->shaderProgram == SHADER_NONE ? light ? SHADER_COMPONENT : SHADER_NOLIGHT : shape->shaderProgram;
    pie_internal::SHADER_PROGRAM &program = pie_ActivateShaderDeprecated(mode, shape, teamcolour, colour, matrix, pie_PerspectiveGet(),
                                            glm::vec4(currentSunPosition, 0.f), sceneColor, ambient, diffuse, specular);

    if (program.locations.size() >= 9)
        glUniform1i(program.locations[8], (pieFlag & pie_PREMULTIPLIED) == 0);

    pie_SetTexturePage(shape->texpage);

    frame %= std::max<int>(1, shape->numFrames);

    enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
    glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(frame * shape->npolys * 3 * sizeof(uint16_t)));
    disableArrays();

    polyCount += shape->npolys;

    pie_SetShaderEcmEffect(false);
    pie_DeactivateShader();
}
Example #6
0
static void pie_Draw3DButton(iIMDShape *shape, PIELIGHT teamcolour, const glm::mat4 &matrix)
{
    const PIELIGHT colour = WZCOL_WHITE;
    pie_SetFogStatus(false);
    pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON);
    pie_internal::SHADER_PROGRAM &program = pie_ActivateShaderDeprecated(SHADER_BUTTON, shape, teamcolour, colour, matrix, pie_PerspectiveGet(),
                                            glm::vec4(), glm::vec4(), glm::vec4(), glm::vec4(), glm::vec4());
    pie_SetRendMode(REND_OPAQUE);
    pie_SetTexturePage(shape->texpage);
    enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0);
    enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]);
    glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, NULL);
    disableArrays();
    polyCount += shape->npolys;
    pie_DeactivateShader();
    pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON);
}