Old school 3-D Vector Gaphics on new system
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Old school 3-D Vector Gaphics on new system
I am fascinated by computer graphic algorithms based on integers. Forgive the self-indulgence, this will be a pic/code/video heavy thread based on the mild success of the Parallel Video Board system that is outputting 1920x1080 video @60Hz with 65K colors. It is highly programmable and it's not finished yet but it is outputting some neat stuff which I'd like to show off here.
Did I mention I like math? Specifically geometry and less so trigonometry. I had a great 6th grade geometry teacher. Things clicked in my brain back then which I remember to this day. Also things I remember from plotting graphics in Atari 800 BASIC over 20 years ago which was maybe 2-3 years after the 6th grade. Also, vector graphic games like Star Wars were a huge inspiration.
Most of the stuff I post is meant for inspiration. Sometimes I know it is too much detail oriented, especially the code. But if it inspires one person then that's a good thing.
The PVB currently has 2 16Kx11 blockRAMs which are meant for X and Y plot scratchpad information for the cpu which is a 65Org16.b. It's basically a 16-bit 6502 with some bells and whistles.
There is also a 10-bit hardware sine LUT present inside the FPGA. The cpu outputs a phase number from 0 to 1023 into that module, and awaiting on the cpu bus is the sinewave data.
The reason for 11-bits in the blockRAMs and 10-bit sine LUT, is so that one can add offsets to the sine LUT data and just plot the values from the scratchpad BRAMs within the 1920x1080 grid. I had wrestled with making the scratchpad BRAMs only 10-bits wide, but the software got messy trying to place waveforms with offsets.
Did I mention I like math? Specifically geometry and less so trigonometry. I had a great 6th grade geometry teacher. Things clicked in my brain back then which I remember to this day. Also things I remember from plotting graphics in Atari 800 BASIC over 20 years ago which was maybe 2-3 years after the 6th grade. Also, vector graphic games like Star Wars were a huge inspiration.
Most of the stuff I post is meant for inspiration. Sometimes I know it is too much detail oriented, especially the code. But if it inspires one person then that's a good thing.
The PVB currently has 2 16Kx11 blockRAMs which are meant for X and Y plot scratchpad information for the cpu which is a 65Org16.b. It's basically a 16-bit 6502 with some bells and whistles.
There is also a 10-bit hardware sine LUT present inside the FPGA. The cpu outputs a phase number from 0 to 1023 into that module, and awaiting on the cpu bus is the sinewave data.
The reason for 11-bits in the blockRAMs and 10-bit sine LUT, is so that one can add offsets to the sine LUT data and just plot the values from the scratchpad BRAMs within the 1920x1080 grid. I had wrestled with making the scratchpad BRAMs only 10-bits wide, but the software got messy trying to place waveforms with offsets.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
So first thing was to know exactly what the sinewave LUT was outputting. This LUT is a module created by the Xilinx Core Generator tool in ISE14.1, I chose the DDS compiler. It is very conservative as far as resources used.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
After some tweaks to the LUT interface, I was able to get good data. I had half sines in different portions of the screen before this code. Basically it adjusts the Y values for the 1080 vertical:
Code: Select all
`timescale 1ns / 1ps
module sin_IF ( input clk,
input [31:0] cpuAB,
input [15:0] cpuDO,
output reg [15:0] cpuDI,
input cpuWE,
input phaseEN, //phaseEn = 1 when 32'hB000_0000 - 32'hBFFF_FFFF is on cpu address bus
output reg [SINaw-1:0] phase = 0,
input [SINaw-1:0] sin_in
);
parameter SINaw = 10;
always @(posedge clk) begin //write to phase register
if (cpuWE && phaseEN && cpuAB [1:0] == 2'b00)
phase <= cpuDO;
if (!cpuWE && phaseEN && phase > 512) //read from sine LUT
cpuDI <= sin_in - 512;
if (!cpuWE && phaseEN && phase <= 512)
cpuDI <= sin_in + 512;
else if (!phaseEN)
cpuDI <= 16'h0000;
end
endmodule-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
Now I remembered from days past that to plot a circle in an X/Y system using sine/cosine values all one had to do is put sine values in the X and cosine values in the Y. Since cosine is sin shifted by 1/4 full cycle timewise, we don't really need cosine in this application. The X value is sine the Y value is sine+1/4=cosine(256/1024)
The code below illustrates this idea. In addition, it adds vertical and horizontal offsets through XORG and YORG for easy plotting. This is why I decided to keep the scratchpad BRAMs at 11-bits for 1920x1080 resolution. Also it divides the data from the LUT by 4 by performing 2x LSR. This code only takes data from the LUT, the cpu modifies it and then places it in BRAM:
This simple code takes the data from the scratch BRAM and plots it. It's got to be simple, or I won't tolerate it.
ONE IMPORTANT NOTE:
When Y=0, a dot will be placed at 6o'clock.
When Y=256, a dot will be placed at 3o'clock.
When Y=512, a dot will be placed at 12o'clock.
When Y=768, a dot will be placed at 9o'clock.
The code below illustrates this idea. In addition, it adds vertical and horizontal offsets through XORG and YORG for easy plotting. This is why I decided to keep the scratchpad BRAMs at 11-bits for 1920x1080 resolution. Also it divides the data from the LUT by 4 by performing 2x LSR. This code only takes data from the LUT, the cpu modifies it and then places it in BRAM:
Code: Select all
;--------- Circle/Ellipse Generator from sine wave LUT
LDA #750
STA XORG
LDA #350
STA YORG
LDWi $0000
LDX #0
LDY #256
sinwave1 STX phase
LDA sinout
LSR
LSR
CLC
ADC XORG
STAaw scratchx1
STY phase
LDA sinout
LSR
LSR
CLC
ADC YORG
STAaw scratchy1
CPX #1023
BMI XNZ1
LDX #0
XNZ1 INX
CPY #1023
BMI YNZ1
LDY #0
YNZ1 INY
INW
CPWi $03FF
BNE sinwave1ONE IMPORTANT NOTE:
When Y=0, a dot will be placed at 6o'clock.
When Y=256, a dot will be placed at 3o'clock.
When Y=512, a dot will be placed at 12o'clock.
When Y=768, a dot will be placed at 9o'clock.
Code: Select all
LDX #1 ;white
LDA CLUT,X
STA color
LDY #0
plot1 LDA scratchx1,Y
STA Xp
LDA scratchy1,Y
STA Yp
INY
CPY #1023
BMI plot1-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
I'm going for a 3-D rotating cube with some special effects.
Software for first square face of cube inside the circle:
Software for first square face of cube inside the circle:
Code: Select all
triplot LDX #5 ;green
LDA CLUT,X
STA color
BCF1C $FFFE ;Branch if Control Flag 1 is Clear (0), CF1 is VSYNC input, so branch to itself and wait until vsync = 1, a non display period
LDY #128 ;1st SQUARE OF CUBE
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #256+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #512+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #768+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
Now 2 scratchpads for 2 circles offset for a cube structure, I tried to come up with a quick calculation for the unit length. It didn't work at first so I placed a set value for UNITL:
That was for the circles, which are virtex modifiers. Now 2 squares set inside 2 circles.
KEEP IN MIND EVERY TIME THE HARDWARE LINE GENERATOR SEES THE ADDRESS ly1, regardless of read or write, IT AUTO DRAWS from (lx0,ly0) to (lx1,ly1):
Code: Select all
;--------- Circle/Ellipse Generator from sine wave LUT
LDA #750
STA XORG
LDA #350
STA YORG
LDWi $0000
LDX #0
LDY #256
sinwave1 STX phase
LDA sinout
LSR
LSR
CLC
ADC XORG
STAaw scratchx1
STY phase
LDA sinout
LSR
LSR
CLC
ADC YORG
STAaw scratchy1
CPX #1023
BMI XNZ1
LDX #0
XNZ1 INX
CPY #1023
BMI YNZ1
LDY #0
YNZ1 INY
INW
CPWi $03FF
BNE sinwave1
;LDY #128 + 768 ;unit length calculation
;LDA scratchy1,Y
;LDY #128
;SEC
;SBC scratchy1,Y
;LSR
LDA #85
STA UNITL
LDWi $0000
LDX #0
LDY #256
sinwave2 STX phase
LDA sinout
LSR
LSR
CLC
ADC XORG
ADC UNITL
STAaw scratchx2
STY phase
LDA sinout
LSR
LSR
CLC
ADC YORG
ADC UNITL
STAaw scratchy2
CPX #1023
BMI XNZ2
LDX #0
XNZ2 INX
CPY #1023
BMI YNZ2
LDY #0
YNZ2 INY
INW
CPWi $03FF
BNE sinwave2KEEP IN MIND EVERY TIME THE HARDWARE LINE GENERATOR SEES THE ADDRESS ly1, regardless of read or write, IT AUTO DRAWS from (lx0,ly0) to (lx1,ly1):
Code: Select all
triplot LDX #5 ;green
LDA CLUT,X
STA color
BCF1C $FFFE ;Branch if Control Flag 1 is Clear (0), CF1 is VSYNC input, so branch to itself and wait until vsync = 1, a non display period
LDY #128 ;1st SQUARE OF CUBE
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #256+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #512+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #768+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
;2nd SQUARE OF CUBE
LDY #128
LDA scratchx2,Y
STA lx0
LDA scratchy2,Y
STA ly0
LDY #256+128
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDA scratchx2,Y
STA lx0
LDA scratchy2,Y
STA ly0
LDY #512+128
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDA scratchx2,Y
STA lx0
LDA scratchy2,Y
STA ly0
LDY #768+128
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDA scratchx2,Y
STA lx0
LDA scratchy2,Y
STA ly0
LDY #128
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
Now to add the 4 diagonal interconnects:
Code: Select all
;DIAGONAL INTERCONNECTS
LDY #128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #256+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #512+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #768+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Old school 3-D Vector Gaphics on new system
Time for macros!
They would dramatically shorten the source code and make it more clear, and still assemble the same result.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
So now, it would be neat to rotate one of the squares for an cool effect soon, but first...
I shift the Y index for the X sine on both of the LUTs represented as the circles currently, in order to make an ellipse. When X=0, Y=256 you get a circle. When X=812(arbitrary), Y=256 you get ellipse...
I shift the Y index for the X sine on both of the LUTs represented as the circles currently, in order to make an ellipse. When X=0, Y=256 you get a circle. When X=812(arbitrary), Y=256 you get ellipse...
Code: Select all
;--------- Circle/Ellipse Generator from sine wave LUT
LDA #750
STA XORG
LDA #350
STA YORG
LDWi $0000
LDX #812
LDY #256
sinwave1 STX phase
LDA sinout
LSR
LSR
CLC
ADC XORG
STAaw scratchx1
STY phase
LDA sinout
LSR
LSR
CLC
ADC YORG
STAaw scratchy1
CPX #1023
BMI XNZ1
LDX #0
XNZ1 INX
CPY #1023
BMI YNZ1
LDY #0
YNZ1 INY
INW
CPWi $03FF
BNE sinwave1
;LDY #128 + 768 ;unit length calculation
;LDA scratchy1,Y
;LDY #128
;SEC
;SBC scratchy1,Y
;LSR
LDA #85
STA UNITL
LDWi $0000
LDX #812
LDY #256
sinwave2 STX phase
LDA sinout
LSR
LSR
CLC
ADC XORG
ADC UNITL
STAaw scratchx2
STY phase
LDA sinout
LSR
LSR
CLC
ADC YORG
ADC UNITL
STAaw scratchy2
CPX #1023
BMI XNZ2
LDX #0
XNZ2 INX
CPY #1023
BMI YNZ2
LDY #0
YNZ2 INY
INW
CPWi $03FF
BNE sinwave2-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
GARTHWILSON wrote:
Time for macros!
They would dramatically shorten the source code and make it more clear, and still assemble the same result.
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Old school 3-D Vector Gaphics on new system
ElEctric_EyE wrote:
GARTHWILSON wrote:
Time for macros!
They would dramatically shorten the source code and make it more clear, and still assemble the same result.
Code: Select all
LDY #128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #256+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #512+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
LDY #768+128
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1Code: Select all
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1Code: Select all
FOOBAR: MACRO input ; (Give it a descriptive name though.)
LDY #input
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
ENDM
;------------------Code: Select all
FOOBAR 128
FOOBAR 256+128
FOOBAR 512+128
FOOBAR 768+128In applications that have a lot of LDA#...STA_abs, I like to use a macro I call PUT, like this:
Code: Select all
PUT 750, IN, XORG
PUT 350, IN, YORGWhen there are a lot of LDA_abs, STA_abs, I like to use a macro I call COPY, like this:
Code: Select all
COPY FOOBAR, TO, XLERBYou also have a lot of occurrences of LSR LSR (two lines), so it would be worth making those a macro and call it LSR2 for example, and then it only uses one line each time instead of two.
The macros for looping, conditional branching, etc, giving it all a more-visible structure are extra, and now I'm hooked on them and never want to go back.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
GARTHWILSON wrote:
Code: Select all
FOOBAR: MACRO input ; (Give it a descriptive name though.)
LDY #input
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDA scratchx2,Y
STA lx1
LDA scratchy2,Y
STA ly1
ENDM
;------------------Code: Select all
FOOBAR 128
FOOBAR 256+128
FOOBAR 512+128
FOOBAR 768+128-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
I should mention, I use macros. Currently about 16,000 lines of them, but they are only to define some of the new 65Org16.b opcodes, not to crunch software.
Like above when I use the 'W' register:
the macro is:
My focus is more on making the machine work at this point, but what you have shown I like and I'll incorporate into future software posts.
Like above when I use the 'W' register:
Code: Select all
STAaw scratchy1Code: Select all
STAaw .MACRO param ;STA $xxxxxxxx,w
.BYTE $009B
.WORD param
.ENDM-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Old school 3-D Vector Gaphics on new system
And what about when one needs to pass potentially 2 variables like in this situation:
It would be tolerable for X, Y, or W values to be used for the different Y values, but what is the syntax? Also, where are the syntax rules specifying these things I ask about?
Code: Select all
LDY #128 ;1st LINE of SQUARE OF CUBE
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #256+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Old school 3-D Vector Gaphics on new system
Code: Select all
LDY #128 ;1st LINE of SQUARE OF CUBE
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #256+128
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1Code: Select all
FOOBAR: MACRO first_param, second_param ; (Name them something meaningful if you like.)
LDY #first_param ; 1st LINE of SQUARE OF CUBE
LDA scratchx1,Y
STA lx0
LDA scratchy1,Y
STA ly0
LDY #second_param
LDA scratchx1,Y
STA lx1
LDA scratchy1,Y
STA ly1
ENDM
;------------------Code: Select all
FOOBAR 128, 256+128I've been following your video posts with interest. The reason I have not commented much is because I don't know enough about video or HDL to comment.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?