OpenCores
URL https://opencores.org/ocsvn/orsoc_graphics_accelerator/orsoc_graphics_accelerator/trunk

Subversion Repositories orsoc_graphics_accelerator

[/] [orsoc_graphics_accelerator/] [trunk/] [sw/] [drivers/] [gfx/] [bare/] [orgfx_3d.c] - Rev 5

Compare with Previous | Blame | View Log

/*
Bare metal OpenCores GFX IP driver for Wishbone bus.
 
Anton Fosselius, Per Lenander 2012
  */
 
#include "orgfx_3d.h"
#include "orgfx.h"
 
#include <math.h>
 
orgfx_matrix orgfx3d_identity(void)
{
    orgfx_matrix i;
    i.aa = i.bb = i.cc = 1;
    i.ab = i.ac = i.ba = i.bc = i.ca = i.cb = 0;
    i.tx = i.ty = i.tz = 0;
    return i;
}
 
orgfx_matrix orgfx3d_rotateX(orgfx_matrix mat, float rad)
{
    orgfx_matrix ret = mat;
 
    float sinrad = sin(rad);
    float cosrad = cos(rad);
 
    //ret.aa = mat.aa
    ret.ab = mat.ab*cosrad - mat.ac*sinrad;
    ret.ac = mat.ab*sinrad + mat.ac*cosrad;
    //ret.ba = mat.ba
    ret.bb = mat.bb*cosrad - mat.bc*sinrad;
    ret.bc = mat.bb*sinrad + mat.bc*cosrad;
    //ret.ca = mat.ca
    ret.cb = mat.cb*cosrad - mat.cc*sinrad;
    ret.cc = mat.cb*sinrad + mat.cc*cosrad;
    //ret.tx = mat.tx
    ret.ty = mat.ty*cosrad - mat.tz*sinrad;
    ret.tz = mat.ty*sinrad + mat.tz*cosrad;
    return ret;
}
 
orgfx_matrix orgfx3d_rotateY(orgfx_matrix mat, float rad)
{
    orgfx_matrix ret = mat;
 
    float sinrad = sin(rad);
    float cosrad = cos(rad);
 
    ret.aa = mat.aa*cosrad + mat.ac*sinrad;
    //ret.ab = mat.ab
    ret.ac = -mat.aa*sinrad + mat.ac*cosrad;
    ret.ba = mat.ba*cosrad + mat.bc*sinrad;
    //ret.bb = mat.bb
    ret.bc = -mat.ba*sinrad + mat.bc*cosrad;
    ret.ca = mat.ca*cosrad + mat.cc*sinrad;
    //ret.cb = mat.cb
    ret.cc = -mat.ca*sinrad + mat.cc*cosrad;
    ret.tx = mat.tx*cosrad + mat.tz*sinrad;
    //ret.ty = mat.ty
    ret.tz = -mat.tx*sinrad + mat.tz*cosrad;
    return ret;
}
 
orgfx_matrix orgfx3d_rotateZ(orgfx_matrix mat, float rad)
{
    orgfx_matrix ret = mat;
 
    float sinrad = sin(rad);
    float cosrad = cos(rad);
 
    ret.aa = mat.aa*cosrad - mat.ab*sinrad;
    ret.ab = mat.aa*sinrad + mat.ab*cosrad;
    //ret.ac = mat.ac
    ret.ba = mat.ba*cosrad - mat.bb*sinrad;
    ret.bb = mat.ba*sinrad + mat.bb*cosrad;
    //ret.bc = mat.bc
    ret.ca = mat.ca*cosrad - mat.cb*sinrad;
    ret.cb = mat.ca*sinrad + mat.cb*cosrad;
    //ret.cc = mat.cc
    ret.tx = mat.tx*cosrad - mat.ty*sinrad;
    ret.ty = mat.tx*sinrad + mat.ty*cosrad;
    //ret.tz = mat.tz
    return ret;
}
 
orgfx_matrix orgfx3d_scale(orgfx_matrix mat, orgfx_point3 s)
{
    orgfx_matrix ret = mat;
    ret.aa *= s.x;
    ret.ab *= s.x;
    ret.ac *= s.x;
    ret.tx *= s.x;
    ret.ba *= s.y;
    ret.bb *= s.y;
    ret.bc *= s.y;
    ret.ty *= s.y;
    ret.ca *= s.z;
    ret.cb *= s.z;
    ret.cc *= s.z;
    ret.tz *= s.z;
    return ret;
}
 
orgfx_matrix orgfx3d_translate(orgfx_matrix mat, orgfx_point3 t)
{
    orgfx_matrix ret = mat;
    ret.tx += t.x;
    ret.ty += t.y;
    ret.tz += t.z;
    return ret;
}
 
void orgfx3d_set_matrix(orgfx_matrix mat)
{
    orgfx_set_transformation_matrix(mat.aa*FIXEDW, mat.ab*FIXEDW, mat.ac*FIXEDW, mat.tx*FIXEDW,
                                    mat.ba*FIXEDW, mat.bb*FIXEDW, mat.bc*FIXEDW, mat.ty*FIXEDW,
                                    mat.ca*FIXEDW, mat.cb*FIXEDW, mat.cc*FIXEDW, mat.tz*FIXEDW);
}
 
orgfx_mesh orgfx3d_make_mesh(orgfx_face* faces,
                             unsigned int nFaces,
                             orgfx_point3* verts,
                             unsigned int nVerts,
                             orgfx_point2* uvs,
                             unsigned int nUvs)
{
    orgfx_mesh mesh;
    mesh.numFaces = nFaces;
    mesh.numVerts = nVerts;
    mesh.numUvs = nUvs;
    mesh.translation.x = mesh.translation.y = mesh.translation.z = 0.0;
    mesh.rotation.x = mesh.rotation.y = mesh.rotation.z = 0.0;
    mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.0;
    mesh.faces = faces;
    mesh.verts = verts;
    mesh.uvs = uvs;
    return mesh;
}
 
void orgfx3d_mesh_texture_size(orgfx_mesh* mesh,
                               unsigned int width,
                               unsigned int height)
{
    orgfx_point2 *uvs = mesh->uvs;
    unsigned int numUvs = mesh->numUvs;
 
    unsigned int i;
    for(i = 0; i < numUvs; i++)
    {
        uvs[i].x *= width;
        uvs[i].y = 1.0 - uvs[i].y; // Mirror v coordinate
        uvs[i].y *= height;
    }
}
 
void orgfx3d_draw_mesh(orgfx_mesh *mesh, int filled, int textured)
{
    if(textured)
        orgfx_enable_tex0(1);
    else
        orgfx_enable_tex0(0);
 
    orgfx_enable_transform(1);
 
    orgfx_matrix m = orgfx3d_identity();
    m = orgfx3d_rotateX(m, mesh->rotation.x);
    m = orgfx3d_rotateY(m, mesh->rotation.y);
    m = orgfx3d_rotateZ(m, mesh->rotation.z);
    m = orgfx3d_scale(m, mesh->scale);
    m = orgfx3d_translate(m, mesh->translation);
    orgfx3d_set_matrix(m);
 
    int f;
    for(f = 0; f < mesh->numFaces; f++)
    {
        orgfx_point3 p1 = mesh->verts[mesh->faces[f].p1];
        orgfx_point3 p2 = mesh->verts[mesh->faces[f].p2];
        orgfx_point3 p3 = mesh->verts[mesh->faces[f].p3];
 
        // Handle coloring
        if(textured)
        {
            orgfx_point2 uv1 = mesh->uvs[mesh->faces[f].uv1];
            orgfx_point2 uv2 = mesh->uvs[mesh->faces[f].uv2];
            orgfx_point2 uv3 = mesh->uvs[mesh->faces[f].uv3];
 
            orgfx_uv(uv1.x, uv1.y,
                     uv2.x, uv2.y,
                     uv3.x, uv3.y);
        }
        else
        {
            orgfx_set_colors(mesh->faces[f].color1,
                             mesh->faces[f].color2,
                             mesh->faces[f].color3);
        }
 
        if(filled)
            orgfx_triangle3d(p1.x*FIXEDW, p1.y*FIXEDW, p1.z*FIXEDW,
                             p2.x*FIXEDW, p2.y*FIXEDW, p2.z*FIXEDW,
                             p3.x*FIXEDW, p3.y*FIXEDW, p3.z*FIXEDW,
                             1);
        else
        {
            orgfx_line3d(p1.x*FIXEDW, p1.y*FIXEDW, p1.z*FIXEDW, p2.x*FIXEDW, p2.y*FIXEDW, p2.z*FIXEDW);
            orgfx_line3d(p2.x*FIXEDW, p2.y*FIXEDW, p2.z*FIXEDW, p3.x*FIXEDW, p3.y*FIXEDW, p3.z*FIXEDW);
            orgfx_line3d(p3.x*FIXEDW, p3.y*FIXEDW, p3.z*FIXEDW, p1.x*FIXEDW, p1.y*FIXEDW, p1.z*FIXEDW);
        }
    }
 
    orgfx_enable_transform(0);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.