Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 27 Mar 2006
Offline Last Active Aug 18 2014 09:53 PM

Posts I've Made

In Topic: Game Engine and APIs

03 August 2014 - 11:51 PM

I think you're confusing APIs with engines. To understand what an API is it's best to use an example. For example you have Microsoft Word, and you would like to make it read a new type of file or would like to export a file in a different format besides text, how can you do that if Word's source code is not available to you? You use an API that was released for that application by the maker of the application. The API basically lets you use parts of the code that could interact with the application. That's why it's called Application Programming Interface, it lets you literally interface with the application you are developing for. But you might think OpenGL is an API also, but there's no single application. It's an interace to the the graphics card driver, you can program the driver by using the functions revealed in the API. But an engine is more like an interface to a variety of APIs that handle physics, graphics, file reading, producing sound etc etc. So it's more like a program rather then a strict collection of function like an API. 


Now to answer if it's easier then a pure API, yes and no. An API is more fundamental, that is you can say DrawPrimitive and specify a triangle to draw and it will draw it, or you can say PlaySound() and it will play a sound, so it's very fundamental and that's what makes APIs easy. The difficulty comes from organizing these very basic calls to create a whole game, as you can see it doesn't handle anything for you at all and you must program all the functionality yourself using these basic building blocks like legos. An engine on the other hand is harder because you have to do some setup that might be less intuitive, like creating scene managers, placing a sound and adding it to your scene before you can play it, creating a camera and attatching it to your player before you can even draw anything etc. You get the idea, you have to have a sense of the stucture of the engine to use it successfully. But it is easier once you get over that initial step because all the code for the most common game techniques is written for you already, you just have to do some setting up and calling some functions, to get it going, then you can concentrate on the logic of your game instead of worrying in which order you have to specify vertices in you model for it to draw correctly as in an API. 


I hope that answers some of your questions.

In Topic: Are there engines out there made for Minecraft clones?

03 August 2014 - 11:34 PM

Minecraft looks simple and basic but it actually uses some advanced 3d graphical principles to do even basic things. The way it partitions and stores space is NOT an easy topic to dive into, the basic physics engine is also not that trivial, on top of that you need to have at least understand how textures, transparancies and such work. The other thing is procedural generation, creating biomes, landmasses, oceans and caves requires some hefty algorithms to look even half decent and playable. Then comes enemy AI and pathfinding in a completely generated world (so you can't pre-program the movements). All in all you NEED to know how to code, otherwise it will be a very frustrating task for you. But as not to be a complete downer, if you really do want to jump into it as quickly as possible and are willing to learn how to code, I would start of with an existing minecraft like game that has it's source code in public domain. So you will have a working game without putting anything into it, and you will be able to add things to your liking. Starting with a game engine even with the ultra beginner friendly Unity will still take A LOT of effort to get anything at all. So I wouldn't suggest that as you will most likely be diving in deep waters without even knowing how to swim, you'll get overwhelmed and abandon the project in a week (at most).

In Topic: Full Screen Quad with Texture, looks off

03 August 2014 - 11:18 PM

Thank you so much Buckeye, I took your suggestion and changed the SCREEN_WIDTH and HEIGHT to client rect and it worked beautifully. And thanks mhagain, as he suggested it right away. I guess somehow the sizes did end up being different. Just for clarity if anyone else is having this issue this is my final code:


//INSIDE WinMain
RECT requestClientSize;
requestClientSize.left = 0;
requestClientSize.top = 0;
requestClientSize.right = SCREEN_WIDTH - 1;
requestClientSize.bottom = SCREEN_HEIGHT - 1;
AdjustWindowRectEx(&requestClientSize, WS_TILED, false, NULL);
if (!RegisterClassEx(&winclass))
// create the window
if (!(hwnd = CreateWindowEx(NULL,                  // extended style
TEXT("DirectX 32-Bit Software Rasterizer v1"), // title
0, 0,<span> </span>  // initial x,y
requestClientSize.right, requestClientSize.bottom,  // initial width, height
NULL,<span> </span>  // handle to parent 
NULL,<span> </span>  // handle to menu
hinstance,// instance of this application
NULL)))<span> </span>// extra creation parms
softrest10_obj.mainWindow = 0;
return 0;

// save main window handle
softrest7_obj.mainWindow = hwnd;
softrest10_obj.mainWindow = hwnd;
GetClientRect(hwnd, &softrest10_obj.clientRect);

//inside RasterizerInit

//setup swap chain ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ZeroMemory(&softObjPtr->D3D10SwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
//set buffer dimensions and format
softObjPtr->D3D10SwapChainDesc.BufferCount = 2;
softObjPtr->D3D10SwapChainDesc.BufferDesc.Width = softObjPtr->clientRect.right;
softObjPtr->D3D10SwapChainDesc.BufferDesc.Height = softObjPtr->clientRect.bottom;
softObjPtr->D3D10SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
softObjPtr->D3D10SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

//set view port aka region of render target ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
softObjPtr->D3D10Viewport.Width = softObjPtr->D3D10SwapChainDesc.BufferDesc.Width;
softObjPtr->D3D10Viewport.Height = softObjPtr->D3D10SwapChainDesc.BufferDesc.Height;
softObjPtr->D3D10Viewport.MinDepth = 0.0f;
softObjPtr->D3D10Viewport.MaxDepth = 1.0f;
softObjPtr->D3D10Viewport.TopLeftX = 0;
softObjPtr->D3D10Viewport.TopLeftY = 0;

//create our texture (or load it) ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
ZeroMemory(&desc, sizeof(desc));
desc.Width = softObjPtr->D3D10SwapChainDesc.BufferDesc.Width;
desc.Height = softObjPtr->D3D10SwapChainDesc.BufferDesc.Height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//softObjPtr->D3D10SwapChainDesc.BufferDesc.Format;
desc.SampleDesc.Count = 1;
desc.Usage = D3D10_USAGE_DYNAMIC;
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
Now it's running as it should be! Can't describe how happy I am :) Thanks again

In Topic: Full Screen Quad with Texture, looks off

01 August 2014 - 01:18 AM

In post #3 above, your code is a bit confusing. It appears you create a window (hwnd, SCREEN_WIDTH x SCREEN+HEIGHT) which you may or may not use(??), set softrest7_obj.mainWindow to 0 on an error, change the size of another window (softObjPtr->mainWindow) based on an adjusted RECT, and create your backbuffer SCREEN_WIDTH x SCREEN_HEIGHT.


IF you're presenting the backbuffer to softObjPtr->mainWindow, though your approach is rather unconventional, it appears things should be correct dimensionally. You didn't post your code for rendering to the texture, nor for rendering the quad. That would help.


For clarity to yourself and others, you might consider creating the mainwindow directly with the desired size, then use the size of the client area (rather than constants) to size your backbuffer. That also allows changing the window size later, ensuring all dimensions are consistent and as expected.



RECT reqSize = { ... };
mainWindow = CreateWindowEx( ... reqSize.right, reqSize.bottom ... );
RECT clientRect;
GetClientRect( mainWindow, &clientRect );
BufferDesc.Width = clientRect.right;
BufferDesc.Height = clientRect.bottom;
// texture
desc.Width = BufferDesc.Width;
desc.Height = BufferDesc.Height;

Also, ensure your viewport is set to the proper rectangle.


Thanks for the reply, I was sure this will go unanswered as it's a strange problem. Ok to explain the softrest7_obj and softObjPtr. I'm not using classes for my software rasterizer but use mostly c like functions. So I have a struct that contains initialization variables for my rasterizer. Before I used DX7 and direct draw so my struct was softrest7_obj and contained stuff like back buffer, interfaces, surface descs etx. Now I have softrast10_obj that contains dx10 interfaces, effect files etc so i can interface with the renderer from my app. So I pass a pointer to 


void InitializeSoftwareRasterizer(SOFTWARERASTERIZER_DX10_OBJECTS* softObjPtr)



and it fills in all the interafaces, also in WinMain i set the softrast10_obj->mainWindow = hwnd; later on so it is the same window

But that's why you see it named different things. In window creation I forgot to change softrest7 to softrast10 and set the wrong window to null but that's not a big issue.


Next is the texture rendering, I did post the code for that in my first post, that for loop is between texture->map / unmap calls. 


softrest10_obj.texture->Map(D3D10CalcSubresource(0,0,1), D3D10_MAP_WRITE_DISCARD, 0, &mappedTex);

UINT lpitch32 = mappedTex.RowPitch >> 2; //in bytes, div by 4 to get num dwords

DWORD* texture_buffer = (DWORD*)mappedTex.pData;

ZeroMemory(texture_buffer, SCREEN_HEIGHT*mappedTex.RowPitch);

// SnowGameMain(texture_buffer, lpitch32, Time.deltaTime);

// OceanMain(texture_buffer, lpitch32, Time.deltaTime);

Main(texture_buffer, lpitch32);

softrest10_obj.texture->Unmap(D3D10CalcSubresource(0, 0, 1));


This is the quad setup:


//lock vertex buffer for CPU use
//right now inside InitializeSoftwareRasterizer10(SOFTWARERASTERIZER_DX10_OBJECTS* softObjPtr)
float planeXOrig =  -1.0f, planeYOrig = -1.0f;
float planeWidth = 2.0f;
float planeHeight = 2.0f;
softObjPtr->pD3D10VertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&v);

v[0] = DX10VERTEX(D3DXVECTOR3(planeXOrig, planeYOrig, 0), D3DXVECTOR4(1, 0, 0, 1), D3DXVECTOR2(0.0f, 1.0f));

v[1] = DX10VERTEX(D3DXVECTOR3(planeXOrig + planeWidth, planeYOrig, 0), D3DXVECTOR4(0, 1, 0, 1), D3DXVECTOR2(1.0f, 1.0f));

v[2] = DX10VERTEX(D3DXVECTOR3(planeXOrig + planeWidth, planeYOrig + planeHeight, 0), D3DXVECTOR4(0, 0, 1, 1), D3DXVECTOR2(1.0f, 0.0f));

v[3] = DX10VERTEX(D3DXVECTOR3(planeXOrig, planeYOrig + planeHeight, 0), D3DXVECTOR4(1, 0.5f, 0.7f, 1), D3DXVECTOR2(0.0f, 0.0f));

//initialize the INDEX BUFFER ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
int* i = NULL;
softObjPtr->pD3D10IndexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&i);
i[0] = 0;
i[1] = 1;
i[2] = 2;
i[3] = 0;
i[4] = 2;
i[5] = 3;


This part I'm not 100% certain about as it's something new to me, I read that if you make your quad go from (-1, -1) to (1, 1) and don't apply any transforms to it, it stays in clip space and therefore spans the whole screen, which is what I need, as before I tried to orthographically project it which was a hassle to line it up.


Also this is my viewport


//set view port aka region of render target ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

softObjPtr->D3D10Viewport.Width = SCREEN_WIDTH;

softObjPtr->D3D10Viewport.Height = SCREEN_HEIGHT;

softObjPtr->D3D10Viewport.MinDepth = 0.0f;

softObjPtr->D3D10Viewport.MaxDepth = 1.0f;

softObjPtr->D3D10Viewport.TopLeftX = 0;

softObjPtr->D3D10Viewport.TopLeftY = 0;

softObjPtr->pD3D10Device->RSSetViewports(1, &softObjPtr->D3D10Viewport);


I understand what you mean about the window resizing, but I like the global defines of screen dimensions. Since my window code has been untouched for a new months it's not really a problem but I do use SCREEN_WIDTH/HEIGHT often so carrying around the clientRect to multiple files will be cumbersome.


As far as I can see this stuff I posted won't really help you pinpoint the fault as it's mostly spot on, I've double and tripple checked everything, so I've resorted to doing low level trial and error things to determine the issue, this is what I have come up with: I wanted to see what would happen if used my old software blitter function to print a bitmap unto the texture. This function worked flawlessly in DirectDraw, but now it stumbles, the bitmap is skewed and the color is moved to one side. So I dove even deeper and just performed this basic test on the texture:


for(int y = offsetY, dy = 0; y < offsetY + image_height - 1; y++, dy++)
for(int x = offsetX*3, dx = 0; x < offsetX*3 + image_width*3; x+=3, dx++)
short red = source[x + y*source_width*3];
short green = source[x + y*source_width*3 + 1];
short blue = source[x + y*source_width*3 + 2];
short a = 255;
DWORD pixel = _RGBA32BIT(red, green, blue, a);
dest[(destPosX + dx) + (destPosY + dy)*destLPitch32] = pixel;


so to break it down, my bitmap is 24 bits, my texture is 32 bits, so I use UCHAR* to traverse the bitmap data and therefore have to manually increment each pixel moved by 3 bytes, during which I read in 3 bytes. I extract each r/g/b byte into a short and then recombine it using my macro

_RGBA32BIT ( (r & 255) + ((g & 255) << 8) + ((b & 255) << 16)  + ((a & 255) << 24) )

Since the <<dest>> is a DWORD ptr I traverse it ragular pixel indexes and it's own pitch. 


The problem is that my square bitmap gets stretched horizontally when I do this. In order to fix that I restructured everything so I cast the texture into a UCHAR* as well and instead used this code to traverse it, this is same as above only more intuitive as now everything is a UCHAR


//establish starting points in memory

UCHAR* sourceStartMem = source + ( ( (offsetX + reg_offsetX) * 3) + ( (offsetY + reg_offsetY)*source_width * 3) );

UCHAR* destStartMem = (UCHAR*)(dest) + (x1 + y1*(destLPitch32 << 2));

int numColumns = (x2 - x1) + 1;

int numRows = (y2 - y1) + 1;

for (int row = 0; row < numRows; row++)


for (int column = 0; column < numColumns; column++)


UCHAR pixel[3];

pixel[0] = sourceStartMem[column * 3];

pixel[1] = sourceStartMem[column * 3 + 1];

pixel[2] = sourceStartMem[column * 3 + 2];
//NOTE - multiplying column by 3 works, texture becomes square, but it SHOULD BE 4, since the texture is 32bit!!!, making it 4 makes the //texture elongated horizonally

destStartMem[column * 3] =  pixel[0];

destStartMem[column * 3 + 1] = pixel[1];

destStartMem[column * 3 + 2] = pixel[2];

destStartMem[column * 3  + 3] = 255;


destStartMem += destLPitch32 << 2; // multiply by 4 to get the 32bit lpitch back into bytes

sourceStartMem += source_width * 3; 


You can ignore the starting memory and offsets, as this fragment is a part of a bigger function where I have to clip the bitmap the import fragment is the for loop. I copy each byte to the appropriate byte on the destination texture and I fill in the 4th byte as 255 for the alpha. The interesting thing is that this works well, the texture is now square, albeit still misscolored. But read the little not i wrote in code, if I multiply the column by 4 which is the correct way since the texture is 4 bytes per pixel the result is the same as the previous code, the texture gets stretched!!! I don't understand why that is happening but I think it's related to the stripes and the mispositioned dots that I was referring to in the original post. So I think this is the problem with the way I lay the pixels into memory, the only thing is why doesn't it just carry over smoothly from DirectDraw, the surface format I used there was 32bit RGBX, this texture is 32bit RGBA so I thought I just have to fill in the last byte to get it to covert, but something else must be at play as well. Here are some pics, first is the stretched bitmap when I use DWORD ptr to address the texture, next is the correctly square bitmap when I use UCHAR ptr to address the texture, and the little blue circle is what the bitmap is supposed to look like had it been drawn correctly:

In Topic: Full Screen Quad with Texture, looks off

30 July 2014 - 08:32 PM

Shameless bump, anyone??