3d cube on OLED

128x128 pixel 1.5" full colour OLED display with MicroSD card slot. [Product page]
csconsulting
Posts: 62
Joined: Fri Sep 21, 2012 7:22 am

3d cube on OLED

Postby csconsulting » Tue Sep 10, 2013 2:53 pm

http://www.rainwulf.com/storage/oled.jpg

I can post the code if you want.

angusgr
Freetronics Staff
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: 3d cube on OLED

Postby angusgr » Tue Sep 10, 2013 11:43 pm

Nice work! I would love to see the code. :)

csconsulting
Posts: 62
Joined: Fri Sep 21, 2012 7:22 am

Re: 3d cube on OLED

Postby csconsulting » Wed Sep 11, 2013 2:30 am

Its a bit messy, will have to organise it a bit. Hangovers from coding in Qbasic all those years ago.

Will comment it a bit more too before i post it.

It also uses the modified FTOled lib too, but i will also make note of the modifications.

csconsulting
Posts: 62
Joined: Fri Sep 21, 2012 7:22 am

Re: 3d cube on OLED

Postby csconsulting » Fri Sep 20, 2013 8:01 am

OK cleaned up the code a lot, and implemented some Structs to make it much clearer and neater.

Code: Select all

/*
 
 
 Draws a 3d rotating cube on the freetronics OLED screen.
 
 
 
 
 */

const byte pin_cs = 7;
const byte pin_dc = 2;
const byte pin_reset = 3;

#include <SPI.h>
#include <SD.h>
#include "FTOLED.h"
#include "fonts/SystemFont5x7.h"

OLED oled(pin_cs, pin_dc, pin_reset);
// Text box takes up bottom 32 characters of the display (ie 4 rows)
OLED_TextBox box(oled, 0, 0, 128, 32);

Colour PIX;

float xx,xy,xz;
float yx,yy,yz;
float zx,zy,zz;

float fact;

int Xan,Yan;

int Xoff;
int Yoff;
int Zoff;

struct Point3d
{
  int x;
  int y;
  int z;
};

struct Point2d
{
  int x;
  int y;
};



int LinestoRender; // lines to render.
int OldLinestoRender; // lines to render just in case it changes. this makes sure the old lines all get erased.



struct Line3d
{
  Point3d p0;
  Point3d p1;
};



struct Line2d
{
  Point2d p0;
  Point2d p1;
};


Line3d Lines[20];
Line2d Render[20];
Line2d ORender[20];






/***********************************************************************************************************************************/
// Sets the global vars for the 3d transform. Any points sent through "process" will be transformed using these figures.
// only needs to be called if Xan or Yan are changed.
void SetVars(void)
{
  float Xan2,Yan2,Zan2;
  float s1,s2,s3,c1,c2,c3;
 
  Xan2 = Xan / fact; // convert degrees to radians.
  Yan2 = Yan / fact;
 
  // Zan is assumed to be zero
   
  s1 = sin(Yan2);
  s2 = sin(Xan2);
 
  c1 = cos(Yan2);
  c2 = cos(Xan2);

  xx = c1;
  xy = 0;
  xz = -s1;

  yx = (s1 * s2);
  yy = c2;
  yz = (c1 * s2);

  zx = (s1 * c2);
  zy = -s2;
  zz = (c1 * c2);
}


/***********************************************************************************************************************************/
// processes x1,y1,z1 and returns rx1,ry1 transformed by the variables set in SetVars()
// fairly heavy on floating point here.
// uses a bunch of global vars. Could be rewritten with a struct but not worth the effort.
void ProcessLine(struct Line2d *ret,struct Line3d vec)
{
  float zvt1;
  int xv1,yv1,zv1;

  float zvt2;
  int xv2,yv2,zv2;
 
  int rx1,ry1;
  int rx2,ry2;
 
  int x1;
  int y1;
  int z1;

  int x2;
  int y2;
  int z2;
 
  int Ok;
 
  x1=vec.p0.x;
  y1=vec.p0.y;
  z1=vec.p0.z;

  x2=vec.p1.x;
  y2=vec.p1.y;
  z2=vec.p1.z;

  Ok=0; // defaults to not OK

  xv1 = (x1 * xx) + (y1 * xy) + (z1 * xz);
  yv1 = (x1 * yx) + (y1 * yy) + (z1 * yz);
  zv1 = (x1 * zx) + (y1 * zy) + (z1 * zz);

  zvt1 = zv1 - Zoff;


  if( zvt1 < -5){
    rx1 = 256 * (xv1 / zvt1) + Xoff;
    ry1 = 256 * (yv1 / zvt1) + Yoff;
    Ok=1; // ok we are alright for point 1.
  }
 
 
  xv2 = (x2 * xx) + (y2 * xy) + (z2 * xz);
  yv2 = (x2 * yx) + (y2 * yy) + (z2 * yz);
  zv2 = (x2 * zx) + (y2 * zy) + (z2 * zz);

  zvt2 = zv2 - Zoff;


  if( zvt2 < -5){
    rx2 = 256 * (xv2 / zvt2) + Xoff;
    ry2 = 256 * (yv2 / zvt2) + Yoff;
  } else
  {
    Ok=0;
  }
 
 
 
 
  if(Ok==1){
   
  ret->p0.x=rx1;
  ret->p0.y=ry1;

  ret->p1.x=rx2;
  ret->p1.y=ry2;
  }
 // The ifs here are checks for out of bounds. needs a bit more code here to "safe" lines that will be way out of whack, so they dont get drawn and cause screen garbage.
 
}



/***********************************************************************************************************************************/
void setup() {
 
 
 
  oled.begin();
//  oled.selectFont(System5x7);
  box.setForegroundColour(WHITE); // in here is specific code for the display. change if you are using a different screen.

  fact = 180 / 3.14159259; // conversion from degrees to radians.

  Xoff = 63; // positions the center of the 3d conversion space into the center of the OLED screen. This is usally screen_x_size / 2.
  Yoff = 63; // screen_y_size /2
  Zoff = 500;


// line segments to draw a cube. basically p0 to p1. p1 to p2. p2 to p3 so on.

// Front Face.

  Lines[0].p0.x=-50;
  Lines[0].p0.y=-50;
  Lines[0].p0.z=50;
  Lines[0].p1.x=50;
  Lines[0].p1.y=-50;
  Lines[0].p1.z=50;



  Lines[1].p0.x=50;
  Lines[1].p0.y=-50;
  Lines[1].p0.z=50;
  Lines[1].p1.x=50;
  Lines[1].p1.y=50;
  Lines[1].p1.z=50;




  Lines[2].p0.x=50;
  Lines[2].p0.y=50;
  Lines[2].p0.z=50;
  Lines[2].p1.x=-50;
  Lines[2].p1.y=50;
  Lines[2].p1.z=50;



  Lines[3].p0.x=-50;
  Lines[3].p0.y=50;
  Lines[3].p0.z=50;
  Lines[3].p1.x=-50;
  Lines[3].p1.y=-50;
  Lines[3].p1.z=50;






//back face.

  Lines[4].p0.x=-50;
  Lines[4].p0.y=-50;
  Lines[4].p0.z=-50;
  Lines[4].p1.x=50;
  Lines[4].p1.y=-50;
  Lines[4].p1.z=-50;



  Lines[5].p0.x=50;
  Lines[5].p0.y=-50;
  Lines[5].p0.z=-50;
  Lines[5].p1.x=50;
  Lines[5].p1.y=50;
  Lines[5].p1.z=-50;




  Lines[6].p0.x=50;
  Lines[6].p0.y=50;
  Lines[6].p0.z=-50;
  Lines[6].p1.x=-50;
  Lines[6].p1.y=50;
  Lines[6].p1.z=-50;



  Lines[7].p0.x=-50;
  Lines[7].p0.y=50;
  Lines[7].p0.z=-50;
  Lines[7].p1.x=-50;
  Lines[7].p1.y=-50;
  Lines[7].p1.z=-50;




// now the 4 edge lines.

  Lines[8].p0.x=-50;
  Lines[8].p0.y=-50;
  Lines[8].p0.z=50;
  Lines[8].p1.x=-50;
  Lines[8].p1.y=-50;
  Lines[8].p1.z=-50;


  Lines[9].p0.x=50;
  Lines[9].p0.y=-50;
  Lines[9].p0.z=50;
  Lines[9].p1.x=50;
  Lines[9].p1.y=-50;
  Lines[9].p1.z=-50;




  Lines[10].p0.x=-50;
  Lines[10].p0.y=50;
  Lines[10].p0.z=50;
  Lines[10].p1.x=-50;
  Lines[10].p1.y=50;
  Lines[10].p1.z=-50;


  Lines[11].p0.x=50;
  Lines[11].p0.y=50;
  Lines[11].p0.z=50;
  Lines[11].p1.x=50;
  Lines[11].p1.y=50;
  Lines[11].p1.z=-50;



  LinestoRender=12;
  OldLinestoRender=LinestoRender;


 
}
/***********************************************************************************************************************************/
void RenderImage( void)
{
  // renders all the lines after erasing the old ones.

// in here is the only code actually interfacing with the OLED. so if you use a different lib, this is where to change it.



 for (int i=0; i<OldLinestoRender; i++ )
  {
    oled.drawLine(ORender[i].p0.x,ORender[i].p0.y,ORender[i].p1.x,ORender[i].p1.y, BLACK); // erase the old lines.
  }

   
  for (int i=0; i<LinestoRender; i++ )
  {
    oled.drawLine(Render[i].p0.x,Render[i].p0.y,Render[i].p1.x,Render[i].p1.y, PIX);
  }
  OldLinestoRender=LinestoRender;
 
}


/***********************************************************************************************************************************/

void loop() {
 
  PIX=GREEN; // colours of all lines drawn will be green until changed.
 
  Xan++;
  Yan++;


  Yan=Yan % 360;
  Xan=Xan % 360; // prevents overflow.
 


  SetVars(); //sets up the global vars to do the conversion.

  for(int i=0; i<LinestoRender ; i++)
  {
    ORender[i]=Render[i]; // stores the old line segment so we can delete it later.
    ProcessLine(&Render[i],Lines[i]); // converts the 3d line segments to 2d.
  } 
 
  RenderImage(); // go draw it!
 
}
/***********************************************************************************************************************************/

csconsulting
Posts: 62
Joined: Fri Sep 21, 2012 7:22 am

Re: 3d cube on OLED

Postby csconsulting » Fri Sep 20, 2013 8:03 am

It wont run very fast unless you modify FTOled.cpp with a few mods, i can go into detail of anyone wants it.

Things
Posts: 36
Joined: Mon Aug 26, 2013 3:47 pm
Location: Cairns, Australia
Contact:

Re: 3d cube on OLED

Postby Things » Sun Sep 29, 2013 1:55 am

Please do :D

aijii
Posts: 16
Joined: Thu Oct 03, 2013 12:06 pm

Re: 3d cube on OLED

Postby aijii » Thu Oct 03, 2013 12:07 pm

Good stuff.

Off topic - Things - did you used to post on photonlexicon ?

Things
Posts: 36
Joined: Mon Aug 26, 2013 3:47 pm
Location: Cairns, Australia
Contact:

Re: 3d cube on OLED

Postby Things » Thu Oct 03, 2013 1:47 pm

Yup, I remember you :D

aijii
Posts: 16
Joined: Thu Oct 03, 2013 12:06 pm

Re: 3d cube on OLED

Postby aijii » Fri Oct 04, 2013 4:19 am

nice :)

0miker0
Posts: 2
Joined: Tue Jan 07, 2014 6:02 pm

Re: 3d cube on OLED

Postby 0miker0 » Tue Jan 07, 2014 6:08 pm

I hope you don't mind me grabbing your code to try on one of my designs. I'm using the Adafruit i2c oled library on a 0.96" mono oled display. To my surprise it runs faster than what I was expecting. I'll try it on a 16Mhz 328P next and then on a SPI display.

http://youtu.be/uan1urYKo_w


Return to “OLED128 Display”

Who is online

Users browsing this forum: No registered users and 1 guest