Advertisement Jump to content
  • Advertisement

VanillaSnake21

Member
  • Content Count

    818
  • Joined

  • Last visited

Community Reputation

181 Neutral

About VanillaSnake21

  • Rank
    Advanced Member

Social

  • Twitter
    TymAfterDark
  • Github
    TimAkgayev
  • Steam
    VanillaSnake

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. VanillaSnake21

    Issues with loading/drawing a bitmap

    Yes! That was it. Using the formula to calculate the proper pitch fixed it.Thanks!
  2. VanillaSnake21

    Issues with loading/drawing a bitmap

    I think I've narrowed down the error to the loading function. What I've done is I've used gdiplus bitmap class to load up a bitmap, I've left the drawing code and the heightmap code the same and it came out right. So I'm pretty sure at this point that I'm not loading up the 8 bit bitmap correctly. But I'm really not sure what it could be. Here is a simplified code snippet from my op: // Read the bitmap file header ReadFile(hFile, &fileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL); // Read the bitmap info head ReadFile(hFile, &infoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL); // Go to pixel array position within the file SetFilePointer(hFile, fileHeader.bfOffBits, NULL, FILE_BEGIN); // Read the pixel array ReadFile(hFile, data, infoHeader.biSizeImage, &dwBytesRead, NULL); What am I missing? Should I be loading the pallette even though I'm not using it? Just to reiterate that this code works for 32bit bitmaps.
  3. I'm trying to implement heightmaps for my engine however I'm having some troubles with bitmap loading code. The bitmap I'm trying to load is 8bit grayscale 250x250 pixels. I've attached the image of what it looks like. (Scroll all the way to the end). The image on the left (in the debug window) is rendered using software, the image on the right is what the height map comes out to look like (I added the colors on purpose to make it clearer to see), that is rendered in hardware. The photoshop shows the original image and how it's meant to look. I'm not exactly sure where the error is, I'm thinking it's the loading function but it's so straight forward that I just can't find the mistake. This is some relevant code: Loading: int Bitmap::LoadBitmapFromDisk(std::string szFileName) { // Open the bitmap file HANDLE hFile = CreateFileA(szFileName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return 0; // Read the bitmap file header DWORD dwBytesRead; BOOL bOK = ReadFile(hFile, &fileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL); //see if the correct byte number was read and that it's actually a bitmap (bfType has to match) if (!bOK || (dwBytesRead != sizeof(BITMAPFILEHEADER)) || (fileHeader.bfType != 0x4D42)) { CloseHandle(hFile); return 0; } // Read the bitmap info head bOK = ReadFile(hFile, &infoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL); if (!bOK || (dwBytesRead != sizeof(BITMAPINFOHEADER))) { CloseHandle(hFile); return 0; } // Store the width and height of the bitmap int m_iWidth = (int)infoHeader.biWidth; int m_iHeight = (int)infoHeader.biHeight; unsigned int sz; SetFilePointer(hFile, fileHeader.bfOffBits, NULL, FILE_BEGIN); data = (UCHAR*) new unsigned char[infoHeader.biSizeImage]; bOK = ReadFile(hFile, data, infoHeader.biSizeImage, &dwBytesRead, NULL); //flip the bytes to little endian if (infoHeader.biBitCount == 32) { DWORD* temp = (DWORD*)data; for (int i = 0; i < infoHeader.biSizeImage / 4; i++) { //photoshop saves a,r,g,b into little endian b,g,r,a //this engine is expecting r,g,b,a so all that's needed is to flip 1st and 3rd bytes //be careful with this code if the image source program is working in r,g,b,a instead of a,r,g,b char* byteMem = (char*)&temp[i]; char btemp = byteMem[0]; byteMem[0] = byteMem[2]; byteMem[2] = btemp; } } if (bOK) return 1; // Something went wrong, so cleanup everything return 0; } Software Render: else if (byteCount == 1) { UCHAR* sourceStartMem = (UCHAR*)source->GetData(); DWORD* destStartMem = (texture_buffer)+(x1 + y1*lpitch32); int numColumns = (x2 - x1); int numRows = (y2 - y1); for (int row = 0; row < numRows; row++) { for (int column = 0; column < numColumns; column++) { int r = sourceStartMem[column]; int g = sourceStartMem[column]; int b = sourceStartMem[column]; destStartMem[column] = _RGBA32BIT(r, g, b, 255); //the RGBA macro is defined like this //_RGBA32BIT(r, g, b, a) ( (r & 255) + ((g & 255) << 8) + ((b & 255) << 16) + ((a & 255) << 24) ) } destStartMem += lpitch32; sourceStartMem += image_width; } } The generation of floor vertex buffer using the height map //create the vertices Vertex* floorMesh = new Vertex[dim.x*dim.y]; for (int xdim = 0; xdim < dim.x; xdim++) { for (int zdim = 0; zdim < dim.y; zdim++) { //height map is just a Bitmap class, GetData returns a UCHAR pointer to the raw pixel array float height = heightMap.GetData()[xdim + zdim*dim.x]; float color = (height)/ 255.0f; floorMesh[xdim + zdim*dim.x] = { XMFLOAT3((float)xdim, height , (float)zdim), XMFLOAT2(float(xdim)/dim.x, float(zdim)/dim.y) }; } }
  4. VanillaSnake21

    Generating an index buffer from a vertex buffer

    @Zakwayda Thank you, I finally got it working, thanks for taking the time to explain it.
  5. VanillaSnake21

    Generating an index buffer from a vertex buffer

    @Zakwayda, Ok, I see what you mean. So if I can just do this: index0 = cellY * vertsPerRow + cellX; index1 = index0 + 1; index2 = (cellY + 1) * vertsPerRow + cellX; index3 = index2 + 1; index4 = index2 index5 = index1 And then repeat for next cell index6 = cellY * vertsPerRow + cellX; index7 = index6 + 1; index8 = (cellY + 1) * vertsPerRow + cellX; index9 = index8 + 1; index10 = index8 index11 = index7 And so on...
  6. VanillaSnake21

    Generating an index buffer from a vertex buffer

    But don't I need 6 indices per 4 vertex square? Three for each triangle?
  7. I'm working on creating a simple terrain for my game. It starts off as a flat, square grid mesh with vertices at even intervals which then gets transformed by the height map and textured. I'm having some issues with creating the square grid. I've just iteratively plopped vertices down, however I'm not seeing how I can now generate an index buffer from that. I've sat down with pen and paper and tried to find a pattern formulae to the indices, but it's not as easy as I expected. I've attached an image of what I came up with. It seems like there is some pattern there but it's not immediately clear. Is there any algorithm for this? I assume this is some form of tessellation, but I have not been able to find anything online. Thanks.
  8. VanillaSnake21

    Using windows messages for camera movement

    @0xnullptr Thanks, great code example. If you dont mind I will use that general layout.
  9. I'd like to move the camera in the game world using the W-A-S-D keys. I always used the GetAsyncKeyState to accomplish this, however I'd like to try and rely solely on windows messages this time. The problem is that key repeat rate has an initial delay so there is a pause between pressing the move key and the camera actually moving. I've read a few threads on this subject and people recommend using a custom timing function to implement this, which I did, however there is something wrong with way I have it at the moment. This is some relevant code: case WM_KEYDOWN: { //mKeyDownMap is declared as std::map<int, bool> , it just matches the keycode of the key to its down state, false key is up, true - down if (wParam == 0x57) //W key if (!mKeyDownMap[0x57]) { SetTimer(mWindow, W_TIMER, 400, NULL); mKeyDownMap[0x57] = true; } if (wParam == 0x53) //S key if (!mKeyDownMap[0x53]) { SetTimer(mWindow, S_TIMER, 400, NULL); mKeyDownMap[0x53] = true; } //... same for other keys }break; case WM_TIMER: { if (wParam == W_TIMER) mCamera.Move(XMFLOAT3(0.0f, 0.0f, 1.0f)); else if(wParam == S_TIMER) mCamera.Move(XMFLOAT3(0.0f, 0.0f, -1.0f)); //..same for other 2 keys } break; case WM_KEYUP: { if (wParam == 0x57) //W key { KillTimer(mWindow, W_TIMER); mKeyDownMap[0x57] = false; } if (wParam == 0x53) //S key { KillTimer(mWindow, S_TIMER); mKeyDownMap[0x53] = false; } //... same goes for other 2 keys }break; The exact issue with this code is when I press the W key once and let go fast, the WM_TIMER is never received, however if I hold the key down then it comes in. I suspect that its got something to do with the processing order of the messages, where WM_KEYDOWN is prossessed and WM_KEYUP is processed right after, killing the timer that never giving the timer a chance to send the WM_TIMER message. I can start writing some annoying workarounds, maybe making sure the mCamera.Move is executed at least once, however I feel like there should be a better way to handle this. I'm not even sure that using these timers is the way it should be done. Can anyone suggest something? Edit: After reading the SetTimer doc, I realized that by calling it again before the first instance of it is killed resets it, so I added a map that holds the previous state saved. Edit 2: Well, I got it running a bit smoother by lower the timer interval to 10ms. However I'd still like to get some feedback if I'm doing this whole thing right.
  10. I'm doing a WinAPI/DX10 framework rewrite and this time around I'd like to start handling errors a little more seriously in my code. Up to this point I've allowed the code to fail naturally and catch the exception within VS. I always found that to be the quickest method. Usually a break occurs and I just step through the call stack and find the problem in seconds (hopefully). However I'm not really sure that's the proper way to do this, but it does feel like I can avoid writing code that is littered with FAILED() or if( == NULL) statements. So what is the proper way? I've read a few other threads on here that talk about using asserts, but I've never really seen any code written with that so I'm bit doubtfull. Most of the conditions I'd like to monitor for errors are usually DirectX function return values, sometimes null points, sometimes WinAPI function fail handles, sometimes index overrun errors, but mostly DX function fails. Again, I feel like debug DX libraries are very verbose and do a wonderful job interacting with VS as it is, so up to this point I've just relied on output window messages for that, but again I'd like to know if that is a proper way to do things. P.S the framework is really just a learning tool for me so it's not going to see serious use. So I lean on the side of cleaner, more readable code vs obfuscated one, so I'd like to not go too crazy with error checking however I'd like to get at least an idea of the way things are done properly. P.P.S I'd also like to mention that I am aware of exceptions however I'm particularly asking about catching programming errors, I was under the impression that exception handling is more of a run-time error detection method to catch things that are not really the programmers fault (like memory, harwdware or network issues).
  11. VanillaSnake21

    When drawing a bitmap, pixels come out misaligned.

    Yes I think that was the issue, i forgot to change this as my old code had RGB only, then I moved to RGBA. However now the letters come out with different colors, but it's probably something in the way I'm encoding the rgba value, I'm going to rework this whole code section. Thanks a bunch, I appreciate you spotting that!
  12. I'm working on a software rasterizer and I'm trying to get the text rending to work correctly. I'm producing the text as a collection of bitmaps, one bitmap for each letter. The bitmaps are generated by the FreeType library, which then passes it to my software blitter that draws them on my main texture. The issue is that when the text gets small the letters look garbled, some pixels come out missing and it just looks blurry and unreadable. However when I move the letters around by a few pixels they render correctly, sharp and crisp. I'm thinking that it's got something to do with pixel alignment, however I'm not sure exactly how my code is not aligning them already. This is the overall picture of the project. Main Texture that is the size of the screen -> this is my main drawing surface of the screen, I just access it through an array like video_memory[x_coord + y_coord * pitch] Various Small Bitmaps and Textures and plots -> all get drawn on the main bitmap through the same array access method This is an except from this particular issue: //I get the bitmap generated by the FreeType library FT_Bitmap bmp = slot->bitmap; //I convert the bitmap into my own bitmap format that the engine can handle //Essentially just copies the buffer and width and height BitmapFile* file = new BitmapFile(bmp.width, bmp.rows, bmp.buffer); //I then draw the bitmap on my main texture DrawBitmapWithClipping(video_mem, lpitch32, bitmap, 102, 100, NULL); //this is the breakdown of the method void DrawBitmapWithClipping(DWORD* dest, int destLPitch32, BitmapFile* source, int destPosX, int destPosY, RECT* sourceRegion) { //... other code// //handles 8 bit bitmap (this is what FreeType is outputting) else if (byteCount == 1) { UCHAR* sourceStartMem = source->GetData() + (((offsetX + reg_offsetX) * byteCount) + ((offsetY + reg_offsetY)* image_width * byteCount)); UCHAR* destStartMem = (UCHAR*)(dest)+(x1 + y1 *(destLPitch32 << 2)); int numColumns = (x2 - x1) + 1; int numRows = (y2 - y1) + 1; for (int row = 0; row < numRows - 1; row++) { for (int column = 0; column < numColumns; column++) { UCHAR pixel[4]; pixel[0] = sourceStartMem[column]; if (pixel[0] != 0) { destStartMem[column * 3] = pixel[0]; destStartMem[column * 3 + 1] = pixel[0]; destStartMem[column * 3 + 2] = pixel[0]; destStartMem[column * 3 + 3] = 255; } } destStartMem += destLPitch32 << 2; sourceStartMem += image_width; } } } I'd like to know how this misalignment happens and what can I do to fix it. Thanks. The images included: exmpl1 - the properly aligned letters, the code for it is expl1_ image exmpl2 - the misaligned letters, code for it is in exmpl2_ As you can see I just changed the x-position by 1 pixel on each and they get misaligned
  13. Wasn't sure whether to post this in Game Design section, but it seems that that one leans towards actual gameplay design, whereas this topic is more about programming decisions. In any case mods can move it. Just want to say that this is the first in a series of questions I planned out oriented towards using proper OOP. A while back I came across a post on here that made me rethink my ways in writing OO code. I cannot quote the individual but he said something along the lines of "it's not OO programming if you're just throwing related functions and data in a class and calling it a day". It kind of struck a chord with me and I got to thinking how most of the code I had was just that, things were Objects for no reason. For example in my initial iterations of frameworks, I had an Application class, a WindowsInterface class, a Utility "class" that just had all static functions (because it was convenient to just write Utility::TransformVector or something like that). Everything was a class just because. About a year ago I decided to step back from that and write code without any classes at all just to see the difference. I rewrote my entire framework in that style and really never looked back since. I no longer have to worry about class instances, about what seem like useless restrictions like having to pass hidden "this" pointers in window parameters or managing objects that didn't even seem like objects to being with. So on to my question. I'm now reading Code Complete 2 (after having read 1 years back) and with everything I've learned I'm tempted to give OOP another go. With a renewed mindset and a renewed appreciation for constraint. However that also got me thinking of whether or not all things conform well to OOP, maybe things like general low level frameworks or systems programming are inherently anti-oop? Maybe I'm just trying to push for something that's not really needed at this point? The reason I came to that conclusion is because I'm re-reading some design chapters right now in CC2 and he speaks of designing software at high level first thinking of it like a house. Designating subsystems, then designating modules in the subsystems, then designing classes and planning their interactions and only then moving on to functional execution of class methods. As I sat down to rewrite my code, I realized that it's really difficult to even begin. I can't specify subsystem interaction for example and as per the book I have to restrict subsystem interaction because "it's chaos if every subsystem can access every other subsystem". Well that's the way I have right now, I have a SoftwareRenderer, UserInterface, Resources, Windows, Application and GameEngine subsystems. I see no reason to restrict SoftwareRendrer to any one, and as of right now since I'm coding in C, all a subsystem has to do is include "SoftwareRasterizer.h" and it's good to go with making calls. It's flexible and convenient. So besides subsystem interaction, I'm also having difficulty breaking things down into meaningfully classes. I blame it on the fact that a framework is by definition a low level system, so the obejcts can't be really straighforward common sense abstractions, they must be EventListeners and FrameDescriptors, which are abstractions non-the-less but at a much less intuitive level. Despite being confident that I don't really need OOP to get the job done, it's nagging me that it's so difficult for me to find an OO solution to a framework. Does that mean that I don't understand what a framework requires if I can't easily delineate the objects required to create it? Should I still push to get there? Or are some things just not as suited for OOP as others? Thanks.
  14. VanillaSnake21

    Pointer becomes invalid for unknown reason

    That did it. Thanks jpetrie. I totally forgot about the difference in bit layouts
  15. I've restructured some of my code to use namespaces and started getting problems in a module that was working correctly previously. The one in question is a DebugWindow, what happens is I give it a pointer to a variable that I want to monitor/change and it's job is to display that variable in a separate window along with a some + and - buttons to in/decrement the variable. These are the relevant portions: WindowManager.h namespace WindowManager { /* WindowManager functions snipped */ namespace DebugWindow { void AddView(double* vard, std::wstring desc, double increment); void AddView(std::wstring* vars, std::wstring desc); void CreateDebugWindow(int width, int height, int x, int y); } } Application.cpp is the main app, it calls the above functions to set the watch on the variables I need to see in real-time void ApplicationInitialization() { //create the main window UINT windowID = SR::WindowManager::CreateNewWindow(LocalWindowsSettings); //initialize the rasterizer InitializeSoftwareRasterizer(SR::WindowManager::GetWindow(windowID)); //create the debug window SR::WindowManager::DebugWindow::CreateDebugWindow(400, LocalWindowsSettings.clientHeight, LocalWindowsSettings.clientPosition.x + LocalWindowsSettings.clientWidth, LocalWindowsSettings.clientPosition.y); //display some debug info SR::WindowManager::DebugWindow::AddView((double*)&gMouseX,TEXT("Mouse X"), 1); SR::WindowManager::DebugWindow::AddView((double*)&gMouseY, TEXT("Mouse Y"), 1); } The variables gMouseX and Y are globals in my application, they are updated inside the App's WindProc inside the WM_MOUSEMOVE like so : case WM_MOUSEMOVE: { gMouseX = GET_X_LPARAM(lParam); gMouseY = GET_Y_LPARAM(lParam); /* .... */ }break; Now inside the AddView() function that I'm calling to set the watch on the variable void AddView(double* vard, std::wstring desc, double increment) { _var v; v.vard = vard; // used when variable is a number v.vars = nullptr; // used when varialbe is a string (in this case it's not) v.desc = desc; v.increment = increment; mAddVariable(v); } _var is just a structure I use to pass the variable definition and annotation inside the module, it's defined as such struct _var { double* vard; //use when variable is a number double increment; //value to increment/decrement in live-view std::wstring* vars; //use when variable is a string std::wstring desc; //description to be displayed next to the variable int minusControlID; int plusControlID; HWND viewControlEdit; //WinAPI windows associated with the display, TextEdit, and two buttons (P) for plus and (M) for minus. HWND viewControlBtnM; HWND viewControlBtnP; }; So after I call AddView it formats this structure and passes it on to mAddVariable(_var), here it is: void mAddVariable(_var variable) { //destroy and recreate a timer KillTimer(mDebugOutWindow, 1); SetTimer(mDebugOutWindow, 1, 10, (TIMERPROC)NULL); //convert the variable into readable string if it's a number std::wstring varString; if (variable.vard) varString = std::to_wstring(*variable.vard); else varString = *variable.vars; //create all the controls variable.viewControlEdit = CreateWindow(/*...*/); //text field control variable.minusControlID = (mVariables.size() - 1) * 2 + 1; variable.viewControlBtnM = CreateWindow(/*...*/); //minus button control variable.plusControlID = (mVariables.size() - 1) * 2 + 2; variable.viewControlBtnP = CreateWindow(/*...*/); //plus button control mVariables.push_back(variable); } I then update the variable using a timer inside the DebugWindow msgproc case WM_TIMER: { switch (wParam) { case 1: // 1 is the id of the timer { for (_var v : mVariables) { SetWindowText(v.viewControlEdit, std::to_wstring(*v.vard).c_str()); } }break; default: break; } }; break; When I examine the mVariables, their vard* is something like 1.48237482E-33#DEN. Why does this happen? Also to note is that I'm programming in C like fashion, without using any objects at all. The module consists of .h and .cpp file, whatever I expose in .h is public, if a function is only exposed in .cpp it's private . So even though I precede some functions with m_Function it's not in a member of a class but just means that it's not exposed in the header file, so it's only visible within this module. Thanks.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!