Making a 3D (viewport-ish)/real-time renderer.. from skratch

Discuss stuff not about Indigo.
User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Fri May 18, 2007 11:32 am

Shit my original notes were scratched on a napkin (I wish I were joking)

I'll have to grab that .asp file to get the offsets for you.

at least its an easy format though.

User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Fri May 18, 2007 11:46 am

Okay, lemme start from the top:
I didn't comment my code with what each code offset does, unfortunately - but this should help you.

fileSize=(width * height * 3) + 54
'this is the file size in bytes, for our 24-bit dib
bitmapDataSize=(width * height * 3)
'this is the actual bitmap data size in bytes

Here's the header (you can probably figure it out, but each chr() returns a byte, and &h makes the data passed to it hexidecimal):

chr(&h42) + chr(&h4D) + *4 bytes here for fileSize* + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h36) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h28) + chr(&h00) + chr(&h00) + chr(&h00) + *4 bytes here for image width in pixels* + *4 bytes here for image height in pixels* + chr(&h01) + chr(&h00) + chr(&h18) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + *4 bytes here for bitmapDataSize* + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + chr(&h00) + *image data goes here, scanlines in reverse order. 1 byte R, 1 byte G, 1 byte B. padded to DWORD boundaries if your width isn't divisible by 4*

To create a simple 24-bit bitmap, with no wierd settings, that will do.
I remember parts of the header, specifying for example the offset to the beginning of the image data, but that's not important for this exercise - i built it into the header code.

If this doesn't make sense, tell me.

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Fri May 18, 2007 9:18 pm

Can't say I understood much of that, sorry :?
How does it write the information??
where does it do it? No 'for loops' at all?

Heh.. It proably works, and works good,
but I can't understand how it is doing it, at all... (except the two first lines :))

:?: ...

User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Fri May 18, 2007 11:15 pm

You know how to do simple file IO in C++?

Create a handle to a new file.

Next, we prepare the header data for your bmp file.

The header is going to be 54 bytes long, for a standard 24-bit uncompressed bmp file.

Write the following to the new file you just created:

Code: Select all

424D
*4 bytes here for fileSize*
000000003600000028000000
*4 bytes here for image width in pixels*
*4 bytes here for image height in pixels*
0100180000000000
*4 bytes here for bitmapDataSize*
00000000000000000000000000000000
With me so far? That takes care of the header of the file.

To finish, simply write, line by line, the contents of the generated framebuffer, into the file next. Remember to write the lines in reverse order, or the image will be upside down when viewed elsewhere.

Possible example:

Code: Select all

for (int i=0, i < imageHeight, i++)
{
 for (int j=0, j < imageWidth, j++)
 {

 'pseudo-code - i obviously don't know what your functions look like
 bmpWriter.AddPixel(framebuffer.getValue(i, j));
 }

}
Is that more clear?

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Fri May 18, 2007 11:47 pm

I am probably to new to C++ to understand this :(
I am trying, but I can't make sense this bmp stuff :?

Code: Select all

    FILE *f;
    int filesize = 54 + 3*WIDTH*HEIGHT;

    unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
    unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};

    bmpfileheader[ 2] = (unsigned char)(filesize    );
    bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
    bmpfileheader[ 4] = (unsigned char)(filesize>>16);
    bmpfileheader[ 5] = (unsigned char)(filesize>>24);

    bmpinfoheader[ 4] = (unsigned char)(       WIDTH    );
    bmpinfoheader[ 5] = (unsigned char)(       WIDTH>> 8);
    bmpinfoheader[ 6] = (unsigned char)(       WIDTH>>16);
    bmpinfoheader[ 7] = (unsigned char)(       WIDTH>>24);
    bmpinfoheader[ 8] = (unsigned char)(       HEIGHT    );
    bmpinfoheader[ 9] = (unsigned char)(       HEIGHT>> 8);
    bmpinfoheader[10] = (unsigned char)(       HEIGHT>>16);
    bmpinfoheader[11] = (unsigned char)(       HEIGHT>>24);

    f = fopen("C:/ti_img01.bmp","wb");
    fwrite(bmpfileheader,1,14,f);
    fwrite(bmpinfoheader,1,40,f);
    	
	//Set pixels
	for(int y = 0; y < HEIGHT; y++){
		for(int x = 0; x < WIDTH; x++){

			if(pixel[x][y] == '1'){
				printf("#");
			}else{
				printf("·");
			}
			//WHAT THE FUCK!!!???
		}
		printf("\n");
	}
	fclose(f);
All of this, except the loop parts is something I just copyed and pasted..
It does save a .bmp file with all the info, but not the image, obviously :)

Code: Select all

bmpWriter.AddPixel(framebuffer.getValue(i, j));
Does not work.. I have just been using arrays for x/y info storing, is that okay?
pixel[x][y] and img[x][y][(r,g,b)]


Arg...


EDIT:
Hand drawn replica of one of my results:
Image

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Sat May 19, 2007 2:45 am

Just thought I should post a screenshot of what I have so far :)

Image

New update (with "fake"/simple Z-Buffer) :)

Image

User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Sat May 19, 2007 7:03 am

Nice antialiasing!

:lol:

Well, your frustrations at least convey to me your skill level in C++ :wink:

I don't have time for indepth fix, but here:

Code: Select all

    FILE *f;
    int filesize = 54 + 3*WIDTH*HEIGHT;

    unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
    unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};

    bmpfileheader[ 2] = (unsigned char)(filesize    );
    bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
    bmpfileheader[ 4] = (unsigned char)(filesize>>16);
    bmpfileheader[ 5] = (unsigned char)(filesize>>24);

    bmpinfoheader[ 4] = (unsigned char)(       WIDTH    );
    bmpinfoheader[ 5] = (unsigned char)(       WIDTH>> 8);
    bmpinfoheader[ 6] = (unsigned char)(       WIDTH>>16);
    bmpinfoheader[ 7] = (unsigned char)(       WIDTH>>24);
    bmpinfoheader[ 8] = (unsigned char)(       HEIGHT    );
    bmpinfoheader[ 9] = (unsigned char)(       HEIGHT>> 8);
    bmpinfoheader[10] = (unsigned char)(       HEIGHT>>16);
    bmpinfoheader[11] = (unsigned char)(       HEIGHT>>24);

    f = fopen("C:/ti_img01.bmp","wb");
    fwrite(bmpfileheader,1,14,f);
    fwrite(bmpinfoheader,1,40,f);
       
   //Set pixels
   for(int y = 0; y < HEIGHT; y++){
      for(int x = 0; x < WIDTH; x++){

         if(pixel[x][y] == '1'){
            //printf("#");
            //00FF00 is RGB(0, 255, 0) - draw a Green pixel basically
              fwrite(0x00FF00, 1, 3, f);
         }else{
            printf("·");
         }
         //WHAT THE FUCK!!!???
      }
      //printf("\n");
   }
   fclose(f);
Now try. You weren't actually writing the results into your image file :)

Note that your intended image will be upside down, and paint.exe (which is the program I used to test my output :P) might display it oddly if your width isn't divisible by 4. The .bmp spec specifies that image data be padded to DWORD boundaries.

I'm actually quite surprised, arne - I assumed you were a much more experienced coder than I :)

User avatar
Kram1032
Posts: 6649
Joined: Tue Jan 23, 2007 3:55 am
Location: Austria near Vienna

Post by Kram1032 » Sat May 19, 2007 7:07 am

In php, that may be the case, but he hasn't got the possibility to use C++, since a very short time back :P

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Sat May 19, 2007 7:42 am

Ah, thanks! :D
It is writing green to the file! :)

Heh.. I've been messing with C/C++ for maybe two months :P
But PHP for a year and a half, I think..

User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Sat May 19, 2007 8:21 am

So post an image then :)

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Sat May 19, 2007 8:29 am

Okay! :D
Attachments
ti_img01.jpg
Image
ti_img01.jpg (8.56 KiB) Viewed 3193 times

User avatar
DaveC
Posts: 596
Joined: Mon Sep 11, 2006 12:20 am
Location: The Tottenham, London, UK
Contact:

Post by DaveC » Sat May 19, 2007 9:45 am

Nice work, Arne. Great to see the progress :D
The hardest part of BEING yourself is FINDING yourself in the first place...
http://thebigdavec.googlepages.com

User avatar
arneoog
Indigo 100
Posts: 504
Joined: Sun Jun 25, 2006 2:19 am
Contact:

Post by arneoog » Sun May 20, 2007 2:06 am

Thanks, Dave :D

I made a simple "rotate animation" with it :P
AVI | MP4

It took like 0.5 sec to generate and save 35 images :D
I have some bad normal issues :? :)
I will fix the, hehe.


Also, what exactly does this "error" mean?

Code: Select all

10 [main] a 2104 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)
It's seems to be an error Cygwin print beacuse I have to many variables or something :? :?
This limits me to 320x240 images, and not very big models... :(

User avatar
zsouthboy
Posts: 1395
Joined: Fri Oct 13, 2006 5:12 am

Post by zsouthboy » Sun May 20, 2007 4:10 am

I've never used cygwin. You get the error when you try to write an image over a certain size?

Why are you using cygwin - IIRC its a *nix layer for windows, right? if your program is just using stdio.h you don't need it.

Or are you more familiar with *nix programming and are using it because of that?

User avatar
Kram1032
Posts: 6649
Joined: Tue Jan 23, 2007 3:55 am
Location: Austria near Vienna

Post by Kram1032 » Sun May 20, 2007 4:12 am

he's using it, 'cause Deus told him to use it :P

Post Reply
64 posts

Who is online

Users browsing this forum: No registered users and 35 guests