Thursday, June 22, 2017

PlaySound() and SND_FILENAME

Two big things I found out today about PlaySound() when you use it with the SND_FILENAME flag:
1. It only accepts .wav files.
2. The bitrate can't be too high. (file size can be in MB's, as I've tried, but bitrate is still big limiter)

The documentation does say the sound specified "must fit into available physical memory", but I thought that meant file size. It actually meant bit rate. I tried a "Chicken Sound.wav" (wanted to try something funny when I was trying this function for the first time). 67 KB, should've been no problem, but I was really confused/frustrated when I was only getting default beeps. 67 KB sounded really small, at least to me.

I tried a bear sound from WavSource.com, "bear_growl_y.wav". (It was listed as "Bear growl 12KB" here.) 48.9KB. And it worked. Even more confused.

I thought about it, checked the bit rate, and guessed how the huge difference in bitrate was causing the bear growl wav to play but not the chicken sound wav.

bear_growl_y.wav -> 88 kbps || Chicken Sound.wav -> 705kbps 


I exported a new wav of the chicken sound in Audacity in lower bitrate, and it worked. Found the details at superuser. I set the Project Rate in the bottom left corner to 8000 HZ, and exported to "WAV (Microsoft) signed 16-bit PCM".

Again, quite confusing what they meant by "available physical memory". Wish they could've noted that part in. Anyways, happy it's working now.

Sunday, June 4, 2017

GL_STENCIL_BITS returns 0

About two months ago, I found that glGetIntegerV(GL_STENCIL_BITS) was returning 0. I asked about it in the OpenGL forums. I got a lot of help, that was really nice. The post goes 2 pages. I found at the time that even with all the ideas, I was still getting 0, so I called it a driver bug. Guess it goes to say that there can be rare cases where it's really a hardware bug and you can't really do anything about it.

I wanted to end it at that. Now, however, I'm getting 8 again. I found a minimal.c here for Windows. Here's a dropbox link to the edited version I had to make to get it to work on VS 2015. (If you're doing VS 2015, don't forget to right click Project -> Properties -> Configuration Properties -> Linker -> SubSystem to Windows (/SUBSYSTEM:WINDOWS). Got me for a bit.)

I now know after a while that it's for Windows only because it's Windows API based. When I first found this while trying to work with the forums, it looked pretty daunting, but I found by changing some DC calls if I remember right and some strings that it worked again. Pretty neat, considering the code was written in 1997. That's the cool thing about Windows API, I see.

I don't have the original file for some reason, but back then, I found a display() function, guessed it was the exact same as  GLFW's "while (!glfwWindowShouldClose(window)) {}" loop, and added this code snippet in to attempt to get stencil bits (lines 19 to 23).


Back then, when I opened the file, it returned 0. That's why I concluded it was a driver bug in the forums. But now when I run it again, it returns 8! No clue why, but that's great! But I'm now confused again. Maybe it could be a GLEW or GLFW bug now to conclude from? Or maybe I read it wrong for some odd reason back then?Anyways, ya, quite a surprise to get this when I'm writing this blog. 

Anyways, ya, overall, wanted to put this entry in here about how in rare cases, weird results can actually be a hardware bug (or now, I'm seeing, maybe a library bug, surprisingly). I haven't reported it to Intel, I would've now, but with the proper 8 result, I'm not sure what to write now haha. I'll let it be for now. If it happens with another function, and trying it in a minimal.c like this doesn't work, then I'll definitely write it in.

Also, it was pretty cool to find that I was trying Windows API for the first time too. Really, that was awesome, getting working results out of a program written that long ago. 

Saturday, May 27, 2017

Pointer problems (check your warnings!)

I was working on a Tic Tac Toe console game in C++ with someone I met online.

(We finished it Thursday. : ) Here's the github repo. My partner tried to incorporate AI, but it was too hard for him. Nonetheless, we both enjoyed working together to make it, even if Tic Tac Toe is a small game.)

Anyways, at one point, when I made a Board object in a Board.h header, I originally wrote it like this:


On building, my Code Blocks compiler gave this warning:


I didn't think much of it (I didn't even read it I think lol.). I gave my Board.h to my partner. He started coding in a gui, but at one point, he got an error like this (which I didn't get interestingly):


He was running on Linux, me on Windows, so at first we were stumped. He thought it was just an OS error, until I looked back at the warning. I googled stuff, found this.

Basically, as shown in the first picture of this post, I returned the address of a local array, which would technically be gone after the function call was over, and the address would be pointing to anywhere, leading to undefined behavior. I fixed it by dynamically allocating the array (allocating to the heap, as they call it) with 'new', so the array would exist even after the function call was over, just as needed.


Overall, that was quite an experience in the Skype chat figuring that out, wanted to share it here. It was two big messages, code-wise:

1. "warning: address of local variable <board_layout> returned"
2. "Segmentation fault [core dumped]"


What was interesting was that I didn't get the same behavior as my partner did (because of the undefined behavior I wrote about). But it's nice that the experience ended well, was able to figure out what was happening. I'm pretty sure they say stuff like this in the books or internet, but I feel like, with most things, you understand it the most through practice and experience: the "hard" way, haha. Anyways, what I learned was: check your warnings! They're warnings for a reason!

BitBlt documentation doesn't mention monochrome to color blitting

I was trying to understand more about BitBlt in theForger's "Transparent Bitmaps" tutorial. What I didn't know was that there's a special conversion process where if you blit a monochrome bitmap to a color bitmap (aka the color bitmap is the hdcDest parameter of BitBlt and the monochrome is the hdcSrc parameter, according to the docs), the monochrome bitmap is mapped to a color bitmap first, like this:

-The white color is mapped to the color bitmap's background color (set from SetBkColor).
-The black color is mapped to the color bitmap's text color (set from SetTextColor).

After that, the 2 images are combined. This was mentioned in this msdn blog post by Raymond Chen. A comment from 'Mike Dimmick' highlights this too. What sucks is that it wasn't mentioned in the BitBlt docs today. That really confused me a lot. Well, anyways, happy to know there's no super magic, just still bitwise ops in the end.

I asked about this in the msdn forums, but I didn't mention about a 'monochrome' bitmap or using SetBkColor or SetTextColor. I didn't know that was relevant til later on. I put my own answer there. I made a diagram too about it, thought it could help anyone in the future.




(The text is hard to see, sorry, I was putting in an image. Opening it in a new tab or downloading it should help to view it easier.)

Also, I was wondering about how the bitwise operations happened in the first place too, with two pixels. Someone at SO helped me with that. Thanks. Basically, in a sense, you can visualize the process by converting the colors to 8 bit hexadecimal and do the bitwise op there. For example, with an AND operation:

RGB(66,244,134) (light green) AND RGB(66, 155, 244) (light blue)

(light green)
66 -> 0x42
244 -> 0xf4
134 -> 0x86
(0x42f486)

(light blue)
66 -> 0x42
155 -> 0x9b
244 -> 0xf4
(0x429bf4)


0x42f486  AND 0x429bf4
0b10000101111010010000110 AND 0b10000101001101111110100
0b10000101001000010000100

0x429084
0x42 -> 66
0x90 -> 144
0x84 -> 132

RESULT -> 0x429084, RGB(66,144,132) (some greenish blue or something)


Tuesday, May 16, 2017

Game Industry Life Project: Writing 39B

One of the writing projects I worked on in my Writing 39B class here at the university was called the RIP Project. "Rhetoric in Practice" Project. Or Rest in Peace lol. That was intense. We were supposed to write a total of 6-8 pages about trying to convince our audience of something. One part was supposed to be the actual content: choosing a genre like a blog or column and writing something in the style of it. The other part was analyzing our own writing choices and how they appealed to our audience. I didn't like the workload. This was a lot. But I still put genuine thought into the game industry topic I wrote about, and I wanted to talk about that more in this post.

The topic I chose was on game industry life. At the time, I was thinking about choosing a Computer Game Science major here at the university, so I wanted to look more into it. I had to tie my project in to the class theme, which was fairy tales at the time, so the project was a little cheesy, but I made it work. As I was researching it though, I realized how harsh it is. Crunch time and short employment seem to be continuous problems in almost every game studio. I mean like, seriously. It sounds really bad, from what I've read. Here's an excerpt from Joshua Rivera's "Inside the Video Game Industry's Culture of Crunch Time":

-------------
“This is people coming in at 9. Working all day. Leaving 10, 11, 12, 1, depending what they were doing. And then coming back the next morning and doing it all over again, six to seven days a week. To my knowledge, five couples got a divorce because of this. Almost the entire creative leadership has now quit, after ship. It was toxic; it was a toxic environment.”
-------------

At first, I'd think this is rare. This is really extreme. But I've seen this same pattern in the other articles I've read, like Andrew McMillen's IGN article on L.A. Noire's 7-year development.

In the end, from doing this project, I've realized that while making games is fun, in the game industry, it can be so busy that it can hurt your health. I don't want to do a Computer Game Science major anymore, just normal Computer Science. I still like making games (I've done a little bit. Nothing AAA of course, but still, I've really enjoyed it), but I don't want to devote my life to it, especially with this lifestyle I'm hearing about. I haven't researched into other computer science fields yet, but I still do love computers and want to have a career with it.

Though I wonder if this lifestyle is common in other industries, and like it's just receiving news in the game industry because the industry is so big. Not sure.

Anyways, I wanted to share my RIP project on this. I did take it seriously, more than just for the grade. Yes, it's a little cheesy. I had to tie it in with fairy tales. But both in the main project and self-analysis, I add in what I've seen from game industry life articles. Of course I haven't had any experience in the industry, but I still think at least mentioning these articles is important.

Dropbox link:
RIP Project

Articles about game industry life:
(the two not mentioned in my bibliography were more about an image and analyzing Polygon's column genre)

Andrew McMillen. "Why Did L.A. Noire Take Seven Years to Make?"

YouTube. "The Realities of Life in Game Development" (Interestingly, I don't think the panel mentions crunch. So maybe crunch is over-hyped, like not in all industries? Or maybe there's something odd here. I don't know.)

Joshua Rivera. "Inside the Video Game Industry's Culture of Crunch Time" 

Jason Schreier. "The Horrible World of Video Game Crunch"

YouTube. "What It's Really Like to Work in the Game Industry"

Tuesday, May 9, 2017

Graphics Card Influencing Whether OpenGL Project Runs

Summary: If you're sure your OpenGL program has no bugs, code-wise, and it's still crashing, it may be your graphics card can't handle the program. In that case, if you have switchable graphics, try switching the graphics card assigned to run the program. Switching from x64 build to x86 could work, but I think that could still lead to random crashes. The "switchable graphics" option works more consistently, I think.

Or maybe upgrade the graphics card. I don't have experience with that though, so I can't say for sure. Though that'd definitely would cost a lot. Or maybe it's a driver bug, which sucks too.

================

I mentioned about a High Performance power setting option in my last post. Wanted to go more into that today.

When I did the Multiple Lights tutorial on Learn OpenGL maybe a long time ago, I was pretty sure I got no errors, code wise. However, when I ran the program, it crashed. This was on a x64 Release build of the project.


I was really sure the code had no errors. I admit I was just copy n pasting code haha. Though I was just learning OpenGL for the first time. I still am new to GL right now as I'm writing it. (As long as the code works, even with copy n paste, I'm still happy with it. I'll go back to it one day and look at it more.)

I tried to run it in Debug mode in VS 2015, got this:




Even odder. When I first saw it, I found 'ig7icd64.dll' to be an interesting file. I found that in C:\Windows\System32. (Now even that's odder! I remember figuring that out for the first time, that 64-bit applications ran using dlls from the System32 folder, while 32-bit apps ran using the SysWOW64 folder. That took a long time to figure out, was a nightmare haha. I think this msdn link and stack overflow link explain what's going on well.)

I remember I even tried to look for files with the same name in other directories in my computer, and I even tried to download a .dll of the same name somewhere. I tried to temporarily replace the .dll, but nothing worked. I got other errors. So I replaced the original .dll.


Anyways, this was really puzzling me. If I remember right, back then, I also tried to mess around with the fragment shader. I found that there was a threshold to the amount of light struct objects I could instantiate in the shader. So for example, given the struct:

struct PointLight {
    vec3 position;
   
    float constant;
    float linear;
    float quadratic;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

If I was to make an array of maybe like 4 to 7 of these struct objects, the program would crash. Like it was just a one-liner like "PointLight array[3];" in the shader's main() function. However, if I instantiated a single struct object, it wouldn't crash. I'm still not sure about the reasoning behind this. I did some searching on that, and I think what I found was that the members of the struct object are like uniform variables, and the graphics card has a max amount of uniform variables allowed when running with OpenGL. 

This was still super confusing. The most interesting part is that I tried it in my dorm-mate's computer, same 64-bit build .exe, and it worked on his. And I tried it on a university library computer, and it worked on that one too! (Ironically, it didn't work on a computer in the student center computer lab lol. If I remember right, it wasn't even the same error, like some glfw error.) 

Side note:
I used VS 2015 to make these builds. I found out I had to make sure to include any image files and shader files in the same directory as my .exe. I also had to include the correct .dlls. In general, I found you need these .dlls with your .exe:

64-bit build Release:
C:\Windows\System32\msvcp140.dll
C:\Windows\System32\vcruntime140.dll

64-bit build Debug:
C:\Windows\System32\msvcp140d.dll
C:\Windows\System32\vcruntime140d.dll

32-bit build Release:
C:\Windows\SysWOW64\msvcp140.dll
C:\Windows\SysWOW64\vcruntime140.dll

32-bit build Debug:
C:\Windows\SysWOW64\msvcp140d.dll
C:\Windows\SysWOW64\vcruntime140d.dll

Anyways, jeez, so I realized that it was something to do with my laptop. I was pretty bummed out at first. (I can't upgrade/change graphics cards in my laptop. They're like "integrated" into the laptop.) 

After more thought, though, I found out that my laptop has switchable graphics. When I right click in my desktop, I got this:



Here's the window that comes up afterwards:


Lol I never knew I had this before, even the fact that I had 2 graphics card in my laptop. When I first saw it, the Graphics Setting was at "Not Assigned". When I changed it to Power Saving, clicked Apply, and tried running it again, it crashed. So I assumed "Not Assigned" led to the Power Saving option at the time, even though I'm pretty sure my laptop was plugged in at the time. However, when I changed it to High Performance, it ran, the 64-bit build Release! I was so happy! : )



It ran on my desktop, ran from the USB, it was awesome. Looking back at the Device Manager and Display adapters section, I know now I have 2 graphics card. I'm pretty sure, when talking about the switchable graphics program above, that they correspond like this:

Power saving: Intel(R) HD Graphics 4000
High performance: AMD Radeon HD 7570M/HD 7670M Graphics


So ya, that was it. I always have that .exe set to "High performance". That was quite the interesting time figuring that out, especially the fact that my laptop had 2 graphics cards. Didn't even think of the idea before haha. 

Monday, April 10, 2017

Linking the wrong library version of SOIL into an OpenGL Project

Here's a summary of what I wrote. I admit I wrote a lot for this one:

Tips on linking:

1. Know if your errors are linking errors. In Visual Studio 2015, as shown above, the errors usually come up with code numbers starting with LNK, like "LNK2001" or "LNK1120". If you know how to solve the linking errors, work from there.

2. One of the ways to solve a linking error is to have the correct bit version of the library linked in a given build. It's either 32-bit or 64-bit.


Compiling SOIL on VS 2015:

The lib/libSOIL.a library file given in the SOIL folder download doesn't work for me. I opened the VC9 .sln in projects/VC9, and built my own 32 and 64-bit SOIL.lib files instead.

------------------------------------

When I originally did the Texture tutorial on the Learn OpenGL site, I did it in 64-bit on Windows 8.1, on Visual Studio 14 (aka Visual Studio 2015). Later, when I was doing the Model tutorial also on Learn OpenGL, I ran into some .dll issues where the .exe was crashing w/ no C++ or GLSL errors. I thought using 32-bit libraries would fix it. (It didn't. I had to change power settings to High Performance. I'll write about that in a future post).

After I compiled 32-bit libraries, moved them to a new folder, and linked them to my project, for some reason I placed a 64-bit library version of SOIL.lib into my libraries folder. To make sure everything was working, I tried to do a Release build on 32-bit  (Release | x86 in the pic below). I got linking errors.




Either it took me a while to see that these were linking errors, or it took me a while to figure out it was a 32-bit vs. 64-bit "wrong library version" issue. Anyways, after a while, I figured out it was a wrong library bit version. After that, it was just compiling an actual 32-bit SOIL.lib, and putting it in the right library folder.

Anyways, I thought I'd write this to say two tips that I think would help others if they get the same library error while doing the Texture tutorial :

1. Know if your errors are linking errors. In Visual Studio 2015, as shown above, the errors usually come up with code numbers starting with LNK, like "LNK2001" or "LNK1120". If you know how to solve the linking errors, work from there.

2. One of the ways to solve a linking error is to have the correct bit version of the library linked in a given build. It's either 32-bit or 64-bit.



I also thought it'd be helpful to show how I ended up building a SOIL.lib for both 32-bit and 64-bit. Learn OpenGL again has a very nice tutorial on cmake and building libraries. SOIL goes past the cmake step and already gives you projects to build libraries from. It's that small of a difference, and the Texture tutorial even points it out. But I thought I'd still show some pics on Visual Studio 2015.

1. When you download SOIL, you'll get a zip file container one folder. Extract that folder somewhere, like your desktop. Here's the SOIL site. The zip file is under the "Download" section.

2. When you open the folder, you'll see this (at least, this is what it looks like when I wrote this).

In the lib folder, there is a libSOIL.a file. That's apparently a library file too. Like it's the exact same as SOIL.lib. According to the SOIL site, it should've worked as a linked library. It didn't for me. Maybe it's not for VS 2015, but an older VS.

Anyways, if it could work for you, I'd say you can either keep the name, or rename it to something like SOIL.lib or SOIL.a ("libSOIL" or "SOIL", it doesn't matter, just make sure to update your linker settings to match the name).


3. Instead of using the lib/libSOIL.a library file (I mention my experience w/ it above), go to the projects folder. For VS 2015, I went to the VC9 folder, the latest one. Then I opened the .sln file. Then change the version settings to Win32 or x64, and build the corresponding 32-bit or 64-bit of the solution. I'd say out of whim that building on Release seems better than Debug mode.

Though Debug or Release version shouldn't matter. I'm not sure if there's a huge difference. I've noticed in both the 32 and 64 bit builds that the Debug build's libraries are smaller than the Release build's libraries.

4. Find the .lib file, copy to your libraries folder as needed, link it to your project, and you're good to go. Here's the directories that came out for me. These all start from the VC9 folder:

32-bit:
Debug: Debug
Release: Release

64-bit:
Debug: x64/Debug
Release: x64/Release

Anyways, that's my experience with SOIL. Hope it helps someone! : )