I am writing a ray tracer with ABAP by studying the book "Ray Tracing from the Ground Up".
A ray tracer is able to create computer generated imagery.
If you like to know more about my motivation behind this endeavour, check out my first blog.
In my second blog I converted the first C++ classes to ABAP, which are needed to patch together my first ray tracer. On the way of conversion I managed to tackle some language feature shortcomings of ABAP, for example overloading.
In this third blog I am going to get the most rudimentary ray tracer running. The book calls that the skeleton ray tracer.
I'm gonna explain the basic concept behind a ray tracer and give you code examples from my implementation to highlight this concept.
Also I let you take part how I struggled with getting my rendered results displayed.
The Skeleton Ray Tracer
The following figure gives you an idea of how ray casting works.
Alright, my code seems to work. But I really need to be able to display pixels with a certain RGB color value.
I didn't find anything which let me place at x and y coordinates a pixel with a certain color.
After reading an old blog, my gut feeling told me that this is going to need extra effort on my end.
thomas.jung provided a solution to the authors question, which put me in the right direction.
Though I still was looking for an easy way out, which made me tackle that problem from two sides.
I asked the community, if someone still has Thomas Jungs full fledged Bitmap image processing class laying around, which he posted in response to helping that fellow from above. I was hoping to just copy & paste the bitmap part I need and be done with it.
And while the community was digging in their SAP graveyards, searching for a 10 years old class, I was reading up on how to:
create a bitmap
display a bitmap
As Thomas mentioned, Wikipedia has an excellent article regarding the Bitmap file format, dissecting all the parts, like how a bitmap header is structured. That allowed me to come up with my own abstraction.
CLASS zcl_art_bitmap DEFINITION
BEGIN OF pixel,
x TYPE int4,
y TYPE int4,
r TYPE int4,
g TYPE int4,
b TYPE int4,
END OF pixel.
i_image_height_in_pixel TYPE int4
i_image_width_in_pixel TYPE int4,
i_pixel TYPE pixel,
VALUE(r_bitmap) TYPE xstring.
CLASS zcl_art_bitmap IMPLEMENTATION.
r TYPE x LENGTH 1,
g TYPE x LENGTH 1,
b TYPE x LENGTH 1.
_converter->convert( EXPORTING data = i_pixel-r IMPORTING buffer = r ).
_converter->convert( EXPORTING data = i_pixel-g IMPORTING buffer = g ).
_converter->convert( EXPORTING data = i_pixel-b IMPORTING buffer = b ).
CONCATENATE _data b g r INTO _data IN BYTE MODE.
IF i_pixel-x + 1 = _image_width_in_pixel.
CONCATENATE _data _remaining_bytes INTO _data IN BYTE MODE.
DATA magic_number TYPE x LENGTH 2.
_converter->convert( EXPORTING data = _co_magic_number_in_ascii IMPORTING buffer = magic_number ).
DATA file_size TYPE x LENGTH 4.
DATA(bmp_file_size_in_byte) = get_bmp_file_size( ).
_converter->convert( EXPORTING data = bmp_file_size_in_byte IMPORTING buffer = file_size ).
After reading several articles (1, 2, 3 and 4) on how to display bitmaps with Dynpro, I was also able to conjure something, which got the job done in the display department.
FORM display USING i_bitmap type xstring.
"now we go from XSTRING back to binary characters
TYPES binary_row TYPE x LENGTH 256.
DATA binary_rows TYPE TABLE OF binary_row WITH DEFAULT KEY.