Click here to Skip to main content
15,901,373 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: raytracer Pin
Jochen Arndt30-Sep-17 22:14
professionalJochen Arndt30-Sep-17 22:14 
AnswerRe: raytracer Pin
Rick York29-Sep-17 4:44
mveRick York29-Sep-17 4:44 
GeneralRe: raytracer Pin
leon de boer30-Sep-17 7:39
leon de boer30-Sep-17 7:39 
GeneralRe: raytracer Pin
bluatigro1-Oct-17 0:35
bluatigro1-Oct-17 0:35 
GeneralRe: raytracer Pin
bluatigro1-Oct-17 1:00
bluatigro1-Oct-17 1:00 
GeneralRe: raytracer Pin
leon de boer1-Oct-17 4:45
leon de boer1-Oct-17 4:45 
GeneralRe: raytracer Pin
bluatigro1-Oct-17 5:56
bluatigro1-Oct-17 5:56 
GeneralRe: raytracer Pin
leon de boer1-Oct-17 16:20
leon de boer1-Oct-17 16:20 
So many typing errors .. use of ( ) instead of [ ], spelling errors, incorrect types.

You had a mixture of unicode and ascii text so I added #include <tchar.h> and put all the text
in _T( ) macro so they work either way.

I also assume you realize you haven't started the D3D render system so your D3d stuff wont work you will just get black screen.

Fixed to at least compile. I assume you sent in the wrong window handle because it
does a magnificent full screen capture (that is window handle was zero) rather than
capture your actual program window so you get a nice bitmap of your entire screen Smile | :)
// bluatigro 1 okt 2017
// windows raytracer 0.2

#include <windows.h>
#include <string>
#include <math.h>
#include <tchar.h>

const int winx = 800;
const int winy = 600;

typedef struct PIXEL {
	char r, g, b, a;
};

class d3d
{
public:
	double x, y, z;
	d3d()
	{
		x = 0.0;
		y = 0.0;
		z = 0.0;
	}
	d3d(double X, double Y, double Z)
	{
		x = X;
		y = Y;
		z = Z;
	}
	void fill(double X, double Y, double Z)
	{
		x = X;
		y = Y;
		z = Z;
	}
	unsigned long toColor()
	{
		return (unsigned long)
			(floor(x * 255) +
				floor(y * 255) * 256 +
				floor(z * 255) * 256 * 256);
	}
};
d3d operator + (d3d a, d3d b)
{
	return d3d(a.x + b.x,
		a.y + b.y,
		a.z + b.z);
}
d3d operator - (d3d a, d3d b)
{
	return d3d(a.x - b.x,
		a.y - b.y,
		a.z - b.z);
}
d3d operator / (d3d a, double b)
{
	return d3d(a.x / b,
		a.y / b,
		a.z / b);
}
d3d operator * (d3d a, double b)
{
	return d3d(a.x * b,
		a.y * b,
		a.z * b);
}
double dot(d3d a, d3d b)
{
	return a.x * b.x
		+ a.y * b.y
		+ a.z * b.z;
}
double length(d3d a)
{
	return sqrt(dot(a, a));
}
d3d normalize(d3d a)
{
	return a / length(a);
}
double getAngle(d3d a, d3d b)
{
	double d, la, lb;
	d = dot(a, b);
	la = length(a);
	lb = length(b);
	return acos(d / (la * lb));
}
d3d cross(d3d a, d3d b)
{
	return d3d(a.y * b.z - a.z * b.y,
		a.z * b.x - a.x * b.z,
		a.x * b.y - a.y * b.x);
}

struct Matrial
{
	d3d diffuse;
	double reflection;
};
Matrial material;


//const double INFINITY = 1e300;  Already defined
#define SMALL 1e-300
#define PI 3.141592658

class Sphere
{
public:
	d3d center;
	double radius, radius2;
	Matrial mat;
	void fill(d3d c, double r)
	{
		center = c;
		radius = r;
		radius2 = r * r;
		mat = material;
	}
	double hit(d3d o, d3d d)
	{
		double t, a, b, c, disc;
		d3d temp = o - center;
		a = dot(d, d);
		b = 2 * dot(temp, d);
		c = dot(temp, temp) - radius2;
		disc = b * b - 4 * a * c;
		if (disc < 0)
			return INFINITY;
		else
		{
			double e = sqrt(disc);
			double demon = 2 * a;
			t = (-b - e) / demon;
			if (t > SMALL) return t;
			t = (-b + e) / demon;
			if (t > SMALL) return t;
		}
		return INFINITY;
	}
};

Sphere spheres[100];
int spheretel;
void sphere(double x, double y, double z
	, double r, d3d color)
{
	d3d pt;
	pt.x = x;
	pt.y = y;
	pt.z = z;
	material.diffuse = color;
	spheres[spheretel].fill(pt, r);
	spheretel++;
}

d3d light;


d3d render(d3d o, d3d d, int depth)
{
	double dist, sphdist = INFINITY;
	int i, isph = -1;
	for (i = 0; i < spheretel; i++)
	{
		dist = spheres[i].hit(o, d);
		if (dist < sphdist)
		{
			sphdist = dist;
			isph = i;
		}
	}
	if (isph == -1)
		return d3d();
		d3d p, n;
	p = o + d * sphdist;
	n = p - spheres[isph].center;
	double a = getAngle(n, light);
	d3d color = spheres[isph].mat.diffuse;
	color = color * (0.5 + cos(a * 2) / 2);
	if (a > PI / 2)
		color = d3d();
	for (i = 0; i < spheretel; i++)
	{
		if (i != isph)
		{
			a = spheres[i].hit(p, light);
			if (a == INFINITY)
				color = d3d();
		}
	}
	return color;
}

int CaptureAnImage(HWND hWnd,
	char* filename)
{
	HDC hdcScreen;
	HDC hdcWindow;
	HDC hdcMemDC = NULL;
	HBITMAP hbmScreen = NULL;
	BITMAP bmpScreen;

	// Retrieve the handle to a display device context for the client 
	// area of the window. 
	hdcScreen = GetDC(NULL);
	hdcWindow = GetDC(hWnd);

	// Create a compatible DC which is used in a BitBlt from the window DC
	hdcMemDC = CreateCompatibleDC(hdcWindow);

	if (!hdcMemDC)
	{
		MessageBox(hWnd, _T("CreateCompatibleDC has failed"), _T("Failed"), MB_OK);
		goto done;
	}

	// Get the client area for size calculation
	RECT rcClient;
	GetClientRect(hWnd, &rcClient);

	//This is the best stretch mode
	SetStretchBltMode(hdcWindow, HALFTONE);

	//The source DC is the entire screen and the destination DC is the current window (HWND)
	if (!StretchBlt(hdcWindow,
		0, 0,
		rcClient.right, rcClient.bottom,
		hdcScreen,
		0, 0,
		GetSystemMetrics(SM_CXSCREEN),
		GetSystemMetrics(SM_CYSCREEN),
		SRCCOPY))
	{
		MessageBox(hWnd, _T("StretchBlt has failed"), _T("Failed"), MB_OK);
		goto done;
	}

	// Create a compatible bitmap from the Window DC
	hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);

	if (!hbmScreen)
	{
		MessageBox(hWnd, _T("CreateCompatibleBitmap Failed"), _T("Failed"), MB_OK);
		goto done;
	}

	// Select the compatible bitmap into the compatible memory DC.
	SelectObject(hdcMemDC, hbmScreen);

	// Bit block transfer into our compatible memory DC.
	if (!BitBlt(hdcMemDC,
		0, 0,
		rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
		hdcWindow,
		0, 0,
		SRCCOPY))
	{
		MessageBox(hWnd, _T("BitBlt has failed"), _T("Failed"), MB_OK);
		goto done;
	}

	// Get the BITMAP from the HBITMAP
	GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);

	BITMAPFILEHEADER   bmfHeader;
	BITMAPINFOHEADER   bi;

	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = bmpScreen.bmWidth;
	bi.biHeight = bmpScreen.bmHeight;
	bi.biPlanes = 1;
	bi.biBitCount = 32;
	bi.biCompression = BI_RGB;
	bi.biSizeImage = 0;
	bi.biXPelsPerMeter = 0;
	bi.biYPelsPerMeter = 0;
	bi.biClrUsed = 0;
	bi.biClrImportant = 0;

	DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

	// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
	// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
	// have greater overhead than HeapAlloc.
	HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
	char *lpbitmap = (char *)GlobalLock(hDIB);

	// Gets the "bits" from the bitmap and copies them into a buffer 
	// which is pointed to by lpbitmap.
	GetDIBits(hdcWindow, hbmScreen, 0,
		(UINT)bmpScreen.bmHeight,
		lpbitmap,
		(BITMAPINFO *)&bi, DIB_RGB_COLORS);

	// A file is created, this is where we will save the screen capture.
	HANDLE hFile = CreateFile(filename,
		GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, NULL);

	// Add the size of the headers to the size of the bitmap to get the total file size
	DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

	//Offset to where the actual bitmap bits start.
	bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

	//Size of the file
	bmfHeader.bfSize = dwSizeofDIB;

	//bfType must always be BM for Bitmaps
	bmfHeader.bfType = 0x4D42; //BM   

	DWORD dwBytesWritten = 0;
	WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
	WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
	WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

	//Unlock and Free the DIB from the heap
	GlobalUnlock(hDIB);
	GlobalFree(hDIB);

	//Close the handle for the file that was created
	CloseHandle(hFile);

	//Clean up
done:
	DeleteObject(hbmScreen);
	DeleteObject(hdcMemDC);
	ReleaseDC(NULL, hdcScreen);
	ReleaseDC(hWnd, hdcWindow);

	return 0;
}

/*
void saveBMP( string filename , PIXEL[][] pixel
, int w , int h )
{
unsigned nWidthBytes = ((w * 24 + 31) & ~31) / 8;
// EDIT: Corrected
//unsigned nExtra = 8 * ((screenx * 24) % 32);
unsigned nExtra = nWidthBytes - 3 * w ;
unsigned nPixelSize = nWidthBytes * h ;
BITMAPFILEHEADER FileHdr ;
// File header
FileHdr.bfType = 0x4D42; // "BM"
FileHdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD) + nPixelSize;
FileHdr.bfReserved1 = pBmHdr.bfReserved2 = 0;
// EDIT: Corrected
//FileHdr.bfOffBits = sizeof(BITMAPFILEHEADER);
FileHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
BITMAPINFOHEADER InfoHdr ;
// Info header for 24-bit RGB
InfoHdr.biSize = sizeof(BITMAPINFOHEADER);
InfoHdr.biWidth = screenx;
InfoHdr.biHeight = screeny;
InfoHdr.biPlanes = 1;
InfoHdr.biBitCount = 24;
InfoHdr.biCompression = BI_BITFIELDS;
InfoHdr.biSizeImage = nPixelSize;
InfoHdr.biXPelsPerMeter = 0;
InfoHdr.biYPelsPerMeter = 0;
InfoHdr.biClrUsed = 0;
InfoHdr.biClrImportant = 0;

// Color table (bit masks for the three colours) with BI_BITFIELDS
// NOTE: I'm actually not sure if these must be reversed!
DWORD clrTable[3] = { 0xff, 0xff00, 0xff0000 };

fwrite(&FileHdr, 1, sizeof(BITMATFILEHEADER), file);
fwrite(&InfoHdr, 1, sizeof(BITMATINFOHEADER), file);
fwrite(clrTable, 1, sizeof(clrTable), file);
for (int y = 0 ; y < ; h ; y++ )
{
// EDIT: Corrected
//fwrite(pixel[y], 3, nWidthBytes, file);
fwrite( pixel[y] , 3 , w , file ) ;
if ( nExtra )
{
DWORD dummy = 0;
fwrite( &dummy , 1 , nExtra , file ) ;
}
}
}*/

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {

	HDC hdc;
	PAINTSTRUCT ps;

	switch (Message)
	{

	case WM_PAINT: {
		int x, y;
		d3d o, d, WHITE;
		WHITE.fill(1.0, 1.0, 1.0);
		unsigned long color;
		hdc = BeginPaint(hwnd, &ps);

		//scene
		spheretel = 0;
		light.fill(-1.0, 1.0, -1.0);
		sphere(0.0, 0.0, 0.0, 100.0, WHITE);
		sphere(0.0, -INFINITY - winy / 2, 0.0
			, INFINITY, WHITE);
		//create scene on window
		for (x = 0; x < winx; x++)
		{
			for (y = 0; y < winy; y++)
			{
				o.fill(0.0, 0.0, -1000);
				d.fill((double)x,
					(double)y, 1000);
				color = render(o, d, 7).toColor();
				SetPixel(hdc, x, y, color);
			}
		}

		int dummy = CaptureAnImage(hwnd,
			_T("white-sphere.bmp"));
		//			saveBMP( "WHITE-sphere.bmp" 
		//			, pixel , winx , winy ) ;

		EndPaint(hwnd, &ps);
		break;
	}
		/* Upon destruction, tell the main thread to stop */
	case WM_DESTROY: {
		PostQuitMessage(0);
		break;
	}

					 /* All other messages (a lot of them) are processed using default procedures */
	default:
		return DefWindowProc(hwnd, Message, wParam, lParam);
	}
	return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASSEX wc; /* A properties struct of our window */
	HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
	MSG msg; /* A temporary location for all messages */

			 /* zero out the struct and set the stuff we want to modify */
	memset(&wc, 0, sizeof(wc));
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);

	/* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.lpszClassName = "WindowClass";
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */

	if (!RegisterClassEx(&wc)) {
		MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("WindowClass"), _T("Caption"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, /* x */
		CW_USEDEFAULT, /* y */
		winx, /* width */
		winy, /* height */
		NULL, NULL, hInstance, NULL);

	if (hwnd == NULL) {
		MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), MB_ICONEXCLAMATION | MB_OK);
		return 0;
	}

	/*
	This is the heart of our program where all input is processed and
	sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
	this loop will not produce unreasonably high CPU usage
	*/
	while (GetMessage(&msg, NULL, 0, 0) > 0) { /* If no error is received... */
		TranslateMessage(&msg); /* Translate key codes to chars if present */
		DispatchMessage(&msg); /* Send it to WndProc */
	}
	return msg.wParam;
}

In vino veritas


modified 1-Oct-17 22:56pm.

GeneralRe: raytracer Pin
bluatigro2-Oct-17 1:34
bluatigro2-Oct-17 1:34 
GeneralRe: raytracer Pin
leon de boer2-Oct-17 3:46
leon de boer2-Oct-17 3:46 
GeneralRe: raytracer Pin
leon de boer2-Oct-17 10:00
leon de boer2-Oct-17 10:00 
GeneralRe: raytracer Pin
bluatigro2-Oct-17 22:57
bluatigro2-Oct-17 22:57 
GeneralRe: raytracer Pin
leon de boer3-Oct-17 4:47
leon de boer3-Oct-17 4:47 
GeneralRe: raytracer Pin
bluatigro6-Oct-17 1:30
bluatigro6-Oct-17 1:30 
GeneralRe: raytracer Pin
bluatigro22-Oct-17 22:37
bluatigro22-Oct-17 22:37 
QuestionCPP Syntax Pin
Bram van Kampen28-Sep-17 11:17
Bram van Kampen28-Sep-17 11:17 
AnswerRe: CPP Syntax Pin
CPallini28-Sep-17 22:16
mveCPallini28-Sep-17 22:16 
GeneralRe: CPP Syntax Pin
Bram van Kampen6-Oct-17 13:51
Bram van Kampen6-Oct-17 13:51 
QuestionComparing Files for Differences Pin
Member 1343302227-Sep-17 3:42
Member 1343302227-Sep-17 3:42 
AnswerRe: Comparing Files for Differences Pin
jeron127-Sep-17 4:09
jeron127-Sep-17 4:09 
QuestionRe: Comparing Files for Differences Pin
David Crow27-Sep-17 5:24
David Crow27-Sep-17 5:24 
AnswerRe: Comparing Files for Differences Pin
jschell27-Sep-17 9:23
jschell27-Sep-17 9:23 
GeneralRe: Comparing Files for Differences Pin
Member 1343302228-Sep-17 2:41
Member 1343302228-Sep-17 2:41 
GeneralRe: Comparing Files for Differences Pin
Jochen Arndt28-Sep-17 3:29
professionalJochen Arndt28-Sep-17 3:29 
GeneralMessage Closed Pin
29-Sep-17 4:00
Member 1343302229-Sep-17 4:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.